Merge "NDK methods to get SurfaceControl/Transction from java"
diff --git a/apct-tests/perftests/core/jni/Android.bp b/apct-tests/perftests/core/jni/Android.bp
index 1e4405de..b92b13b 100644
--- a/apct-tests/perftests/core/jni/Android.bp
+++ b/apct-tests/perftests/core/jni/Android.bp
@@ -9,7 +9,6 @@
 
 cc_library_shared {
     name: "libperftestscore_jni",
-    sdk_version: "21",
 
     srcs: ["SystemPerfTest.cpp"],
 
@@ -20,4 +19,10 @@
         "-Wunreachable-code",
     ],
     header_libs: ["jni_headers"],
+
+    shared_libs: [
+        "libandroid_runtime",
+        "liblog",
+        "libnativehelper",
+    ],
 }
diff --git a/apct-tests/perftests/core/jni/SystemPerfTest.cpp b/apct-tests/perftests/core/jni/SystemPerfTest.cpp
index f102e3e..e7d451d 100644
--- a/apct-tests/perftests/core/jni/SystemPerfTest.cpp
+++ b/apct-tests/perftests/core/jni/SystemPerfTest.cpp
@@ -16,6 +16,9 @@
 
 #include <jni.h>
 
+#include "nativehelper/JNIHelp.h"
+#include "core_jni_helpers.h"
+
 #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
 
 static void jintarrayArgumentNoop(JNIEnv*, jclass, jintArray, jint) {
@@ -48,11 +51,38 @@
     return ret;
 }
 
+static jint jintFastNativeAccess(JNIEnv*, jclass, jint number) {
+    return number;
+}
+
+static jint jintCriticalNativeAccess(CRITICAL_JNI_PARAMS_COMMA jint number) {
+    return number;
+}
+
+static jint jintFastNativeCheckNullPointer(JNIEnv* env, jclass, jint number) {
+    if (number == 0) {
+        jniThrowNullPointerException(env, NULL);
+        return -1;
+    }
+    return number;
+}
+
+static jint jintCriticalNativeCheckNullPointer(CRITICAL_JNI_PARAMS_COMMA jint number) {
+    if (number == 0) {
+        return -1;
+    }
+    return number;
+}
+
 static const JNINativeMethod sMethods[] = {
     {"jintarrayArgumentNoop", "([II)V", (void *) jintarrayArgumentNoop},
     {"jintarrayGetLength", "([I)I", (void *) jintarrayGetLength},
     {"jintarrayCriticalAccess", "([II)I", (void *) jintarrayCriticalAccess},
     {"jintarrayBasicAccess", "([II)I", (void *) jintarrayBasicAccess},
+    {"jintFastNativeAccess", "(I)I", (void *) jintFastNativeAccess},
+    {"jintCriticalNativeAccess", "(I)I", (void *) jintCriticalNativeAccess},
+    {"jintFastNativeCheckNullPointer", "(I)I", (void *) jintFastNativeCheckNullPointer},
+    {"jintCriticalNativeCheckNullPointer", "(I)I", (void *) jintCriticalNativeCheckNullPointer},
 };
 
 static int registerNativeMethods(JNIEnv* env, const char* className,
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
index adcd571..b995b06 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
@@ -158,11 +158,10 @@
     }
 
     @Test
-    public void timeClonedSimpleDateFormat() {
-        SimpleDateFormat sdf = new SimpleDateFormat();
+    public void timeNewSimpleDateFormat() {
         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
-            sdf.clone();
+            new SimpleDateFormat();
         }
     }
 
diff --git a/apct-tests/perftests/core/src/android/perftests/SystemPerfTest.java b/apct-tests/perftests/core/src/android/perftests/SystemPerfTest.java
index 4f0d108..c636be9 100644
--- a/apct-tests/perftests/core/src/android/perftests/SystemPerfTest.java
+++ b/apct-tests/perftests/core/src/android/perftests/SystemPerfTest.java
@@ -22,8 +22,10 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 
+import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -106,6 +108,93 @@
         }
     }
 
+    /** this result should be compared with {@link #testJniCriticalNativeAccess()}. */
+    @Test
+    public void testJniFastNativeAccess() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            jintFastNativeAccess(50);
+        }
+    }
+
+    /**
+     * This result should be compared with {@link #testJniFastNativeAccess()}.
+     *
+     * <p>In theory, the result should be better than {@link #testJniFastNativeAccess()}.
+     */
+    @Test
+    public void testJniCriticalNativeAccess() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            jintCriticalNativeAccess(50);
+        }
+    }
+
+    /** The result should be compared with {@link #testJniCriticalNativeCheckNullPointer()}. */
+    @Test
+    public void testJniFastNativeCheckNullPointer() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            final int echoNumber = jintFastNativeCheckNullPointer(50);
+        }
+    }
+
+    /**
+     * The result should be compared with {@link #testJniFastNativeCheckNullPointer()}.
+     *
+     * <p>CriticalNative can't reference JavaEnv in native layer. It means it should check the null
+     * pointer in java layer. It's a comparison between native layer and java layer.
+     */
+    @Test
+    public void testJniCriticalNativeCheckNullPointer() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            final int echoNumber = jintCriticalNativeCheckNullPointer(50);
+            if (echoNumber == -1) {
+                Assert.fail("It shouldn't be here");
+            }
+        }
+    }
+
+    /**
+     * The result should be compared with {@link #testJniCriticalNativeThrowNullPointerException()}.
+     */
+    @Test
+    public void testJniFastNativeThrowNullPointerException() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            try {
+                jintFastNativeCheckNullPointer(0);
+            } catch (NullPointerException e) {
+                continue;
+            }
+            Assert.fail("It shouldn't be here");
+        }
+    }
+
+    /**
+     * The result should be compared with {@link #testJniFastNativeThrowNullPointerException()}.
+     *
+     * <p>CriticalNative can't reference JavaEnv in native layer. It means it should check the null
+     * pointer in java layer. It's a comparison between native layer and java layer.
+     */
+    @Test
+    public void testJniCriticalNativeThrowNullPointerException() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            try {
+                final int echoNumber = jintCriticalNativeCheckNullPointer(0);
+                if (echoNumber == -1) {
+                    throw new NullPointerException();
+                }
+            } catch (NullPointerException e) {
+                continue;
+            }
+            Assert.fail("It shouldn't be here");
+        }
+    }
+
+    // ----------- @FastNative ------------------
     @FastNative
     private static native void jintarrayArgumentNoop(int[] array, int length);
     @FastNative
@@ -114,4 +203,17 @@
     private static native int jintarrayCriticalAccess(int[] array, int index);
     @FastNative
     private static native int jintarrayBasicAccess(int[] array, int index);
+
+    @FastNative
+    private static native int jintFastNativeAccess(int echoNumber);
+
+    @FastNative
+    private static native int jintFastNativeCheckNullPointer(int echoNumber);
+
+    // ----------- @CriticalNative ------------------
+    @CriticalNative
+    private static native int jintCriticalNativeAccess(int echoNumber);
+
+    @CriticalNative
+    private static native int jintCriticalNativeCheckNullPointer(int echoNumber);
 }
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index b6d29aa..5b61f9a 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -676,6 +676,9 @@
         private static final String KEY_TIME_TICK_ALLOWED_WHILE_IDLE =
                 "time_tick_allowed_while_idle";
 
+        private static final String KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF =
+                "delay_nonwakeup_alarms_while_screen_off";
+
         @VisibleForTesting
         static final String KEY_ALLOW_WHILE_IDLE_QUOTA = "allow_while_idle_quota";
 
@@ -743,6 +746,8 @@
 
         private static final int DEFAULT_TEMPORARY_QUOTA_BUMP = 0;
 
+        private static final boolean DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = true;
+
         // Minimum futurity of a new alarm
         public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
 
@@ -835,6 +840,9 @@
          */
         public int TEMPORARY_QUOTA_BUMP = DEFAULT_TEMPORARY_QUOTA_BUMP;
 
+        public boolean DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF =
+                DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF;
+
         private long mLastAllowWhileIdleWhitelistDuration = -1;
         private int mVersion = 0;
 
@@ -1011,6 +1019,11 @@
                             TEMPORARY_QUOTA_BUMP = properties.getInt(KEY_TEMPORARY_QUOTA_BUMP,
                                     DEFAULT_TEMPORARY_QUOTA_BUMP);
                             break;
+                        case KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF:
+                            DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = properties.getBoolean(
+                                    KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF,
+                                    DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);
+                            break;
                         default:
                             if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
                                 // The quotas need to be updated in order, so we can't just rely
@@ -1249,6 +1262,10 @@
             pw.print(KEY_TEMPORARY_QUOTA_BUMP, TEMPORARY_QUOTA_BUMP);
             pw.println();
 
+            pw.print(KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF,
+                    DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);
+            pw.println();
+
             pw.decreaseIndent();
         }
 
@@ -4360,7 +4377,11 @@
         }
     }
 
+    @GuardedBy("mLock")
     boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) {
+        if (!mConstants.DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF) {
+            return false;
+        }
         if (mInteractive) {
             return false;
         }
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 72553ed..90ce8bf 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -366,7 +366,7 @@
                     job.getNumFailures());
             // Use the context's ID to distinguish traces since there'll only be one job running
             // per context.
-            Trace.asyncTraceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, job.getBatteryName(), getId());
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, job.getTag(), getId());
             try {
                 mBatteryStats.noteJobStart(job.getBatteryName(), job.getSourceUid());
             } catch (RemoteException e) {
@@ -1030,7 +1030,7 @@
                 completedJob.getJob().getPriority(),
                 completedJob.getEffectivePriority(),
                 completedJob.getNumFailures());
-        Trace.asyncTraceEnd(Trace.TRACE_TAG_SYSTEM_SERVER, completedJob.getBatteryName(), getId());
+        Trace.asyncTraceEnd(Trace.TRACE_TAG_SYSTEM_SERVER, completedJob.getTag(), getId());
         try {
             mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(), mRunningJob.getSourceUid(),
                     internalStopReason);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
index f1e13df..9c16772 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
@@ -644,7 +644,7 @@
         static final String KEY_FALLBACK_FLEXIBILITY_DEADLINE =
                 FC_CONFIG_PREFIX + "fallback_flexibility_deadline_ms";
         static final String KEY_MIN_TIME_BETWEEN_FLEXIBILITY_ALARMS_MS =
-                FC_CONFIG_PREFIX + "min_alarm_time_flexibility_ms";
+                FC_CONFIG_PREFIX + "min_time_between_flexibility_alarms_ms";
         static final String KEY_PERCENTS_TO_DROP_NUM_FLEXIBLE_CONSTRAINTS =
                 FC_CONFIG_PREFIX + "percents_to_drop_num_flexible_constraints";
         static final String KEY_MAX_RESCHEDULED_DEADLINE_MS =
diff --git a/api/Android.bp b/api/Android.bp
index e9930e3..29eaec6 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -38,23 +38,9 @@
     pluginFor: ["soong_build"],
 }
 
-python_defaults {
-    name: "python3_version_defaults",
-    version: {
-        py2: {
-            enabled: false,
-        },
-        py3: {
-            enabled: true,
-            embedded_launcher: false,
-        },
-    },
-}
-
 python_binary_host {
     name: "api_versions_trimmer",
     srcs: ["api_versions_trimmer.py"],
-    defaults: ["python3_version_defaults"],
 }
 
 python_test_host {
@@ -64,7 +50,6 @@
         "api_versions_trimmer_unittests.py",
         "api_versions_trimmer.py",
     ],
-    defaults: ["python3_version_defaults"],
     test_options: {
         unit_test: true,
     },
@@ -73,7 +58,6 @@
 python_binary_host {
     name: "merge_annotation_zips",
     srcs: ["merge_annotation_zips.py"],
-    defaults: ["python3_version_defaults"],
 }
 
 python_test_host {
@@ -83,7 +67,6 @@
         "merge_annotation_zips.py",
         "merge_annotation_zips_test.py",
     ],
-    defaults: ["python3_version_defaults"],
     test_options: {
         unit_test: true,
     },
diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h
index 58aff42..03e714a 100644
--- a/cmds/idmap2/include/idmap2/Idmap.h
+++ b/cmds/idmap2/include/idmap2/Idmap.h
@@ -21,42 +21,51 @@
  * header                     := magic version target_crc overlay_crc fulfilled_policies
  *                               enforce_overlayable target_path overlay_path overlay_name
  *                               debug_info
- * data                       := data_header target_entry* target_inline_entry* overlay_entry*
- *                               string_pool
- * data_header                := target_entry_count target_inline_entry_count overlay_entry_count
+ * data                       := data_header target_entry* target_inline_entry*
+                                 target_inline_entry_value* config* overlay_entry* string_pool
+ * data_header                := target_entry_count target_inline_entry_count
+                                 target_inline_entry_value_count config_count overlay_entry_count
  *                               string_pool_index
  * target_entry               := target_id overlay_id
- * target_inline_entry        := target_id Res_value::size padding(1) Res_value::type
+ * target_inline_entry        := target_id start_value_index value_count
+ * target_inline_entry_value  := config_index Res_value::size padding(1) Res_value::type
+ *                               Res_value::value
+ * config                     := target_id Res_value::size padding(1) Res_value::type
  *                               Res_value::value
  * overlay_entry              := overlay_id target_id
  *
- * debug_info                 := string
- * enforce_overlayable        := <uint32_t>
- * fulfilled_policies         := <uint32_t>
- * magic                      := <uint32_t>
- * overlay_crc                := <uint32_t>
- * overlay_entry_count        := <uint32_t>
- * overlay_id                 := <uint32_t>
- * overlay_package_id         := <uint8_t>
- * overlay_name               := string
- * overlay_path               := string
- * padding(n)                 := <uint8_t>[n]
- * Res_value::size            := <uint16_t>
- * Res_value::type            := <uint8_t>
- * Res_value::value           := <uint32_t>
- * string                     := <uint32_t> <uint8_t>+ padding(n)
- * string_pool                := string
- * string_pool_index          := <uint32_t>
- * string_pool_length         := <uint32_t>
- * target_crc                 := <uint32_t>
- * target_entry_count         := <uint32_t>
- * target_inline_entry_count  := <uint32_t>
- * target_id                  := <uint32_t>
- * target_package_id          := <uint8_t>
- * target_path                := string
- * value_type                 := <uint8_t>
- * value_data                 := <uint32_t>
- * version                    := <uint32_t>
+ * debug_info                       := string
+ * enforce_overlayable              := <uint32_t>
+ * fulfilled_policies               := <uint32_t>
+ * magic                            := <uint32_t>
+ * overlay_crc                      := <uint32_t>
+ * overlay_entry_count              := <uint32_t>
+ * overlay_id                       := <uint32_t>
+ * overlay_package_id               := <uint8_t>
+ * overlay_name                     := string
+ * overlay_path                     := string
+ * padding(n)                       := <uint8_t>[n]
+ * Res_value::size                  := <uint16_t>
+ * Res_value::type                  := <uint8_t>
+ * Res_value::value                 := <uint32_t>
+ * string                           := <uint32_t> <uint8_t>+ padding(n)
+ * string_pool                      := string
+ * string_pool_index                := <uint32_t>
+ * string_pool_length               := <uint32_t>
+ * target_crc                       := <uint32_t>
+ * target_entry_count               := <uint32_t>
+ * target_inline_entry_count        := <uint32_t>
+ * target_inline_entry_value_count  := <uint32_t>
+ * config_count                     := <uint32_t>
+ * config_index                     := <uint32_t>
+ * start_value_index                := <uint32_t>
+ * value_count                      := <uint32_t>
+ * target_id                        := <uint32_t>
+ * target_package_id                := <uint8_t>
+ * target_path                      := string
+ * value_type                       := <uint8_t>
+ * value_data                       := <uint32_t>
+ * version                          := <uint32_t>
  */
 
 #ifndef IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
@@ -70,6 +79,7 @@
 #include "android-base/macros.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
+#include "androidfw/ConfigDescription.h"
 #include "idmap2/ResourceContainer.h"
 #include "idmap2/ResourceMapping.h"
 
@@ -165,19 +175,27 @@
    public:
     static std::unique_ptr<const Header> FromBinaryStream(std::istream& stream);
 
-    inline uint32_t GetTargetEntryCount() const {
+    [[nodiscard]] inline uint32_t GetTargetEntryCount() const {
       return target_entry_count;
     }
 
-    inline uint32_t GetTargetInlineEntryCount() const {
+    [[nodiscard]] inline uint32_t GetTargetInlineEntryCount() const {
       return target_entry_inline_count;
     }
 
-    inline uint32_t GetOverlayEntryCount() const {
+    [[nodiscard]] inline uint32_t GetTargetInlineEntryValueCount() const {
+      return target_entry_inline_value_count;
+    }
+
+    [[nodiscard]] inline uint32_t GetConfigCount() const {
+      return config_count;
+    }
+
+    [[nodiscard]] inline uint32_t GetOverlayEntryCount() const {
       return overlay_entry_count;
     }
 
-    inline uint32_t GetStringPoolIndexOffset() const {
+    [[nodiscard]] inline uint32_t GetStringPoolIndexOffset() const {
       return string_pool_index_offset;
     }
 
@@ -186,6 +204,8 @@
    private:
     uint32_t target_entry_count;
     uint32_t target_entry_inline_count;
+    uint32_t target_entry_inline_value_count;
+    uint32_t config_count;
     uint32_t overlay_entry_count;
     uint32_t string_pool_index_offset;
     Header() = default;
@@ -202,7 +222,7 @@
 
   struct TargetInlineEntry {
     ResourceId target_id;
-    TargetValue value;
+    std::map<ConfigDescription, TargetValue> values;
   };
 
   struct OverlayEntry {
@@ -227,11 +247,11 @@
     return target_inline_entries_;
   }
 
-  const std::vector<OverlayEntry>& GetOverlayEntries() const {
+  [[nodiscard]] const std::vector<OverlayEntry>& GetOverlayEntries() const {
     return overlay_entries_;
   }
 
-  const std::string& GetStringPoolData() const {
+  [[nodiscard]] const std::string& GetStringPoolData() const {
     return string_pool_data_;
   }
 
diff --git a/cmds/idmap2/include/idmap2/ResourceMapping.h b/cmds/idmap2/include/idmap2/ResourceMapping.h
index 21862a36..4bad2fa 100644
--- a/cmds/idmap2/include/idmap2/ResourceMapping.h
+++ b/cmds/idmap2/include/idmap2/ResourceMapping.h
@@ -33,7 +33,8 @@
 using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask;
 
 namespace android::idmap2 {
-using TargetResourceMap = std::map<ResourceId, std::variant<ResourceId, TargetValue>>;
+using ConfigMap = std::unordered_map<std::string, TargetValue>;
+using TargetResourceMap = std::map<ResourceId, std::variant<ResourceId, ConfigMap>>;
 using OverlayResourceMap = std::map<ResourceId, ResourceId>;
 
 class ResourceMapping {
diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h
index 8ec7496..af4dd89 100644
--- a/cmds/idmap2/include/idmap2/ResourceUtils.h
+++ b/cmds/idmap2/include/idmap2/ResourceUtils.h
@@ -46,6 +46,10 @@
 struct TargetValueWithConfig {
   TargetValue value;
   std::string config;
+
+  [[nodiscard]] std::pair<std::string, TargetValue> to_pair() const {
+    return std::make_pair(config, value);
+  }
 };
 
 namespace utils {
diff --git a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
index 3bbe9d9..4b271a1 100644
--- a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
+++ b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
@@ -70,12 +70,35 @@
   }
 
   static constexpr uint16_t kValueSize = 8U;
+  std::vector<std::pair<ConfigDescription, TargetValue>> target_values;
+  target_values.reserve(data.GetHeader()->GetTargetInlineEntryValueCount());
   for (const auto& target_entry : data.GetTargetInlineEntries()) {
     Write32(target_entry.target_id);
+    Write32(target_values.size());
+    Write32(target_entry.values.size());
+    target_values.insert(
+        target_values.end(), target_entry.values.begin(), target_entry.values.end());
+  }
+
+  std::vector<ConfigDescription> configs;
+  configs.reserve(data.GetHeader()->GetConfigCount());
+  for (const auto& target_entry_value : target_values) {
+    auto config_it = find(configs.begin(), configs.end(), target_entry_value.first);
+    if (config_it != configs.end()) {
+      Write32(config_it - configs.begin());
+    } else {
+      Write32(configs.size());
+      configs.push_back(target_entry_value.first);
+    }
     Write16(kValueSize);
     Write8(0U);  // padding
-    Write8(target_entry.value.data_type);
-    Write32(target_entry.value.data_value);
+    Write8(target_entry_value.second.data_type);
+    Write32(target_entry_value.second.data_value);
+  }
+
+  for( auto& cd : configs) {
+    cd.swapHtoD();
+    stream_.write(reinterpret_cast<char*>(&cd), sizeof(cd));
   }
 
   for (const auto& overlay_entry : data.GetOverlayEntries()) {
@@ -89,6 +112,8 @@
 void BinaryStreamVisitor::visit(const IdmapData::Header& header) {
   Write32(header.GetTargetEntryCount());
   Write32(header.GetTargetInlineEntryCount());
+  Write32(header.GetTargetInlineEntryValueCount());
+  Write32(header.GetConfigCount());
   Write32(header.GetOverlayEntryCount());
   Write32(header.GetStringPoolIndexOffset());
 }
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index 06650f6..4efaeea 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -186,6 +186,8 @@
   std::unique_ptr<IdmapData::Header> idmap_data_header(new IdmapData::Header());
   if (!Read32(stream, &idmap_data_header->target_entry_count) ||
       !Read32(stream, &idmap_data_header->target_entry_inline_count) ||
+      !Read32(stream, &idmap_data_header->target_entry_inline_value_count) ||
+      !Read32(stream, &idmap_data_header->config_count) ||
       !Read32(stream, &idmap_data_header->overlay_entry_count) ||
       !Read32(stream, &idmap_data_header->string_pool_index_offset)) {
     return nullptr;
@@ -207,20 +209,59 @@
     if (!Read32(stream, &target_entry.target_id) || !Read32(stream, &target_entry.overlay_id)) {
       return nullptr;
     }
-    data->target_entries_.push_back(target_entry);
+    data->target_entries_.emplace_back(target_entry);
   }
 
   // Read the mapping of target resource id to inline overlay values.
-  uint8_t unused1;
-  uint16_t unused2;
+  std::vector<std::tuple<TargetInlineEntry, uint32_t, uint32_t>> target_inline_entries;
   for (size_t i = 0; i < data->header_->GetTargetInlineEntryCount(); i++) {
     TargetInlineEntry target_entry{};
-    if (!Read32(stream, &target_entry.target_id) || !Read16(stream, &unused2) ||
-        !Read8(stream, &unused1) || !Read8(stream, &target_entry.value.data_type) ||
-        !Read32(stream, &target_entry.value.data_value)) {
+    uint32_t entry_offset;
+    uint32_t entry_count;
+    if (!Read32(stream, &target_entry.target_id) || !Read32(stream, &entry_offset)
+        || !Read32(stream, &entry_count)) {
       return nullptr;
     }
-    data->target_inline_entries_.push_back(target_entry);
+    target_inline_entries.emplace_back(std::make_tuple(target_entry, entry_offset, entry_count));
+  }
+
+  // Read the inline overlay resource values
+  std::vector<std::pair<uint32_t, TargetValue>> target_values;
+  uint8_t unused1;
+  uint16_t unused2;
+  for (size_t i = 0; i < data->header_->GetTargetInlineEntryValueCount(); i++) {
+    uint32_t config_index;
+    if (!Read32(stream, &config_index)) {
+      return nullptr;
+    }
+    TargetValue value;
+    if (!Read16(stream, &unused2)
+        || !Read8(stream, &unused1)
+        || !Read8(stream, &value.data_type)
+        || !Read32(stream, &value.data_value)) {
+      return nullptr;
+    }
+    target_values.emplace_back(std::make_pair(config_index, value));
+  }
+
+  // Read the configurations
+  std::vector<ConfigDescription> configurations;
+  for (size_t i = 0; i < data->header_->GetConfigCount(); i++) {
+    ConfigDescription cd;
+    if (!stream.read(reinterpret_cast<char*>(&cd), sizeof(ConfigDescription))) {
+      return nullptr;
+    }
+    configurations.emplace_back(cd);
+  }
+
+  // Construct complete target inline entries
+  for (auto [target_entry, entry_offset, entry_count] : target_inline_entries) {
+    for(size_t i = 0; i < entry_count; i++) {
+      const auto& target_value = target_values[entry_offset + i];
+      const auto& config = configurations[target_value.first];
+      target_entry.values[config] = target_value.second;
+    }
+    data->target_inline_entries_.emplace_back(target_entry);
   }
 
   // Read the mapping of overlay resource id to target resource id.
@@ -278,12 +319,21 @@
 
   std::unique_ptr<IdmapData> data(new IdmapData());
   data->string_pool_data_ = resource_mapping.GetStringPoolData().to_string();
+  uint32_t inline_value_count = 0;
+  std::set<std::string> config_set;
   for (const auto& mapping : resource_mapping.GetTargetToOverlayMap()) {
     if (auto overlay_resource = std::get_if<ResourceId>(&mapping.second)) {
       data->target_entries_.push_back({mapping.first, *overlay_resource});
     } else {
-      data->target_inline_entries_.push_back(
-          {mapping.first, std::get<TargetValue>(mapping.second)});
+      std::map<ConfigDescription, TargetValue> values;
+      for (const auto& [config, value] : std::get<ConfigMap>(mapping.second)) {
+        config_set.insert(config);
+        ConfigDescription cd;
+        ConfigDescription::Parse(config, &cd);
+        values[cd] = value;
+        inline_value_count++;
+      }
+      data->target_inline_entries_.push_back({mapping.first, values});
     }
   }
 
@@ -295,6 +345,8 @@
   data_header->target_entry_count = static_cast<uint32_t>(data->target_entries_.size());
   data_header->target_entry_inline_count =
       static_cast<uint32_t>(data->target_inline_entries_.size());
+  data_header->target_entry_inline_value_count = inline_value_count;
+  data_header->config_count = config_set.size();
   data_header->overlay_entry_count = static_cast<uint32_t>(data->overlay_entries_.size());
   data_header->string_pool_index_offset = resource_mapping.GetStringPoolOffset();
   data->header_ = std::move(data_header);
diff --git a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
index d10a278..a44fa75 100644
--- a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
+++ b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
@@ -94,14 +94,17 @@
   }
 
   for (auto& target_entry : data.GetTargetInlineEntries()) {
-    stream_ << TAB << base::StringPrintf("0x%08x -> ", target_entry.target_id)
-            << utils::DataTypeToString(target_entry.value.data_type);
+    for(auto iter = target_entry.values.begin(); iter != target_entry.values.end(); ++iter) {
+      auto value = iter->second;
+      stream_ << TAB << base::StringPrintf("0x%08x -> ", target_entry.target_id)
+              << utils::DataTypeToString(value.data_type);
 
-    if (target_entry.value.data_type == Res_value::TYPE_STRING) {
-      auto str = string_pool.stringAt(target_entry.value.data_value - string_pool_offset);
-      stream_ << " \"" << str.value_or(StringPiece16(u"")) << "\"";
-    } else {
-      stream_ << " " << base::StringPrintf("0x%08x", target_entry.value.data_value);
+      if (value.data_type == Res_value::TYPE_STRING) {
+        auto str = string_pool.stringAt(value.data_value - string_pool_offset);
+        stream_ << " \"" << str.value_or(StringPiece16(u"")) << "\"";
+      } else {
+        stream_ << " " << base::StringPrintf("0x%08x", value.data_value);
+      }
     }
 
     std::string target_name = kUnknownResourceName;
diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
index 779538c..3531cd7 100644
--- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
+++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
@@ -89,22 +89,30 @@
       print(target_entry.target_id, "target id");
     }
 
+
     pad(sizeof(Res_value::size) + sizeof(Res_value::res0));
 
-    print(target_entry.value.data_type, "type: %s",
-          utils::DataTypeToString(target_entry.value.data_type).data());
+    for (auto& target_entry_value : target_entry.values) {
+      auto value = target_entry_value.second;
 
-    Result<std::string> overlay_name(Error(""));
-    if (overlay_ != nullptr &&
-        (target_entry.value.data_value == Res_value::TYPE_REFERENCE ||
-         target_entry.value.data_value == Res_value::TYPE_DYNAMIC_REFERENCE)) {
-      overlay_name = overlay_->GetResourceName(target_entry.value.data_value);
-    }
+      print(target_entry_value.first.to_string(), false, "config: %s",
+          target_entry_value.first.toString().string());
 
-    if (overlay_name) {
-      print(target_entry.value.data_value, "data: %s", overlay_name->c_str());
-    } else {
-      print(target_entry.value.data_value, "data");
+      print(value.data_type, "type: %s",
+            utils::DataTypeToString(value.data_type).data());
+
+      Result<std::string> overlay_name(Error(""));
+      if (overlay_ != nullptr &&
+          (value.data_value == Res_value::TYPE_REFERENCE ||
+           value.data_value == Res_value::TYPE_DYNAMIC_REFERENCE)) {
+        overlay_name = overlay_->GetResourceName(value.data_value);
+      }
+
+      if (overlay_name) {
+        print(value.data_value, "data: %s", overlay_name->c_str());
+      } else {
+        print(value.data_value, "data");
+      }
     }
   }
 
@@ -138,6 +146,8 @@
 void RawPrintVisitor::visit(const IdmapData::Header& header) {
   print(header.GetTargetEntryCount(), "target entry count");
   print(header.GetTargetInlineEntryCount(), "target inline entry count");
+  print(header.GetTargetInlineEntryValueCount(), "target inline entry value count");
+  print(header.GetConfigCount(), "config count");
   print(header.GetOverlayEntryCount(), "overlay entry count");
   print(header.GetStringPoolIndexOffset(), "string pool index offset");
 }
diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp
index 8ebe5aa4..bb31c11 100644
--- a/cmds/idmap2/libidmap2/ResourceMapping.cpp
+++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp
@@ -161,14 +161,13 @@
 Result<Unit> ResourceMapping::AddMapping(
     ResourceId target_resource,
     const std::variant<OverlayData::ResourceIdValue, TargetValueWithConfig>& value) {
-  if (target_map_.find(target_resource) != target_map_.end()) {
-    return Error(R"(target resource id "0x%08x" mapped to multiple values)", target_resource);
-  }
-
   // TODO(141485591): Ensure that the overlay type is compatible with the target type. If the
   // runtime types are not compatible, it could cause runtime crashes when the resource is resolved.
 
   if (auto overlay_resource = std::get_if<OverlayData::ResourceIdValue>(&value)) {
+    if (target_map_.find(target_resource) != target_map_.end()) {
+      return Error(R"(target resource id "0x%08x" mapped to multiple values)", target_resource);
+    }
     target_map_.insert(std::make_pair(target_resource, overlay_resource->overlay_id));
     if (overlay_resource->rewrite_id) {
       // An overlay resource can override multiple target resources at once. Rewrite the overlay
@@ -176,8 +175,18 @@
       overlay_map_.insert(std::make_pair(overlay_resource->overlay_id, target_resource));
     }
   } else {
-    auto overlay_value = std::get<TargetValueWithConfig>(value);
-    target_map_.insert(std::make_pair(target_resource, overlay_value.value));
+    auto[iter, inserted] = target_map_.try_emplace(target_resource, ConfigMap());
+    auto& resource_value = iter->second;
+    if (!inserted && std::holds_alternative<ResourceId>(resource_value)) {
+      return Error(R"(target resource id "0x%08x" mapped to multiple values)", target_resource);
+    }
+    auto& config_map = std::get<ConfigMap>(resource_value);
+    const auto& config_value = std::get<TargetValueWithConfig>(value);
+    if (config_map.find(config_value.config) != config_map.end()) {
+      return Error(R"(target resource id "0x%08x" mapped to multiple values with the same config)",
+                   target_resource);
+    }
+    config_map.insert(config_value.to_pair());
   }
 
   return Unit{};
diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
index bf63327..f1eeab9 100644
--- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
+++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
@@ -84,8 +84,10 @@
   const auto& target_inline_entries2 = data2->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries1.size(), target_inline_entries2.size());
   ASSERT_EQ(target_inline_entries1[0].target_id, target_inline_entries2[0].target_id);
-  ASSERT_EQ(target_inline_entries1[0].value.data_type, target_inline_entries2[0].value.data_type);
-  ASSERT_EQ(target_inline_entries1[0].value.data_value, target_inline_entries2[0].value.data_value);
+  ASSERT_EQ(target_inline_entries1[0].values.begin()->second.data_type,
+      target_inline_entries2[0].values.begin()->second.data_type);
+  ASSERT_EQ(target_inline_entries1[0].values.begin()->second.data_value,
+      target_inline_entries2[0].values.begin()->second.data_value);
 
   const auto& overlay_entries1 = data1->GetOverlayEntries();
   const auto& overlay_entries2 = data2->GetOverlayEntries();
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index ee9a424..7b7dc17 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -47,10 +47,11 @@
   ASSERT_EQ((entry).target_id, (target_resid));                 \
   ASSERT_EQ((entry).overlay_id, (overlay_resid))
 
-#define ASSERT_TARGET_INLINE_ENTRY(entry, target_resid, expected_type, expected_value) \
-  ASSERT_EQ((entry).target_id, target_resid);                                          \
-  ASSERT_EQ((entry).value.data_type, (expected_type));                                 \
-  ASSERT_EQ((entry).value.data_value, (expected_value))
+#define ASSERT_TARGET_INLINE_ENTRY(entry, target_resid, ex_config, expected_type, expected_value) \
+  ASSERT_EQ((entry).target_id, target_resid);                                                     \
+  ASSERT_EQ((entry).values.begin()->first.to_string(), (ex_config));                              \
+  ASSERT_EQ((entry).values.begin()->second.data_type, (expected_type));                           \
+  ASSERT_EQ((entry).values.begin()->second.data_value, (expected_value))
 
 #define ASSERT_OVERLAY_ENTRY(entry, overlay_resid, target_resid) \
   ASSERT_EQ((entry).overlay_id, (overlay_resid));                \
@@ -67,7 +68,7 @@
   std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
   ASSERT_THAT(header, NotNull());
   ASSERT_EQ(header->GetMagic(), 0x504d4449U);
-  ASSERT_EQ(header->GetVersion(), 0x08U);
+  ASSERT_EQ(header->GetVersion(), 0x09U);
   ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
   ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
   ASSERT_EQ(header->GetFulfilledPolicies(), 0x11);
@@ -122,8 +123,8 @@
 
   const auto& target_inline_entries = data->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries.size(), 1U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000, Res_value::TYPE_INT_HEX,
-                             0x12345678);
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000,  "land-xxhdpi-v7",
+                             Res_value::TYPE_INT_HEX, 0x12345678);
 
   const auto& overlay_entries = data->GetOverlayEntries();
   ASSERT_EQ(target_entries.size(), 3U);
@@ -142,7 +143,7 @@
 
   ASSERT_THAT(idmap->GetHeader(), NotNull());
   ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
-  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x08U);
+  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x09U);
   ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U);
   ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U);
   ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), kIdmapRawDataPolicies);
@@ -165,8 +166,8 @@
 
   const auto& target_inline_entries = data->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries.size(), 1U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000, Res_value::TYPE_INT_HEX,
-                             0x12345678);
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000,  "land-xxhdpi-v7",
+                             Res_value::TYPE_INT_HEX, 0x12345678);
 
   const auto& overlay_entries = data->GetOverlayEntries();
   ASSERT_EQ(target_entries.size(), 3U);
@@ -203,7 +204,7 @@
 
   ASSERT_THAT(idmap->GetHeader(), NotNull());
   ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
-  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x08U);
+  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x09U);
   ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), android::idmap2::TestConstants::TARGET_CRC);
   ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), android::idmap2::TestConstants::OVERLAY_CRC);
   ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), PolicyFlags::PUBLIC);
@@ -261,9 +262,9 @@
 
   auto frro = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "test.target")
                   .SetOverlayable("TestResources")
-                  .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "")
-                  .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "")
-                  .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "")
+                  .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "land-xxhdpi-v7")
+                  .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "land")
+                  .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "xxhdpi-v7")
                   .Build();
 
   ASSERT_TRUE(frro);
@@ -295,11 +296,11 @@
 
   const auto& target_inline_entries = data->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries.size(), 3U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1, "land-xxhdpi-v7",
                              Res_value::TYPE_INT_DEC, 2U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1, "land",
                              Res_value::TYPE_REFERENCE, 0x7f010000);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[2], R::target::string::str2,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[2], R::target::string::str2, "xxhdpi-v7",
                              Res_value::TYPE_STRING,
                              (uint32_t) (string_pool.indexOfString(u"foobar", 6)).value_or(-1));
 }
@@ -442,9 +443,9 @@
   constexpr size_t overlay_string_pool_size = 10U;
   const auto& target_inline_entries = data->GetTargetInlineEntries();
   ASSERT_EQ(target_inline_entries.size(), 2U);
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1, std::string(),
                              Res_value::TYPE_INT_DEC, 73U);  // -> 73
-  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1,
+  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1, std::string(),
                              Res_value::TYPE_STRING,
                              overlay_string_pool_size + 0U);  // -> "Hello World"
 
diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
index a6371cb..7112eeb 100644
--- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
@@ -64,7 +64,7 @@
   (*idmap)->accept(&visitor);
 
   ASSERT_CONTAINS_REGEX(ADDRESS "504d4449  magic\n", stream.str());
-  ASSERT_CONTAINS_REGEX(ADDRESS "00000008  version\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000009  version\n", stream.str());
   ASSERT_CONTAINS_REGEX(
       StringPrintf(ADDRESS "%s  target crc\n", android::idmap2::TestConstants::TARGET_CRC_STRING),
       stream.str());
@@ -75,6 +75,8 @@
   ASSERT_CONTAINS_REGEX(ADDRESS "00000001  enforce overlayable\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000004  target entry count", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000000  target inline entry count", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000000  target inline entry value count", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000000  config count", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000004  overlay entry count", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "0000000a  string pool index offset", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f010000  target id: integer/int1", stream.str());
@@ -111,7 +113,7 @@
   (*idmap)->accept(&visitor);
 
   ASSERT_CONTAINS_REGEX(ADDRESS "504d4449  magic\n", stream.str());
-  ASSERT_CONTAINS_REGEX(ADDRESS "00000008  version\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000009  version\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00001234  target crc\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00005678  overlay crc\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000011  fulfilled policies: public|signature\n", stream.str());
@@ -124,17 +126,25 @@
   ASSERT_CONTAINS_REGEX(ADDRESS "........  overlay name: OverlayName\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000003  target entry count\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000001  target inline entry count\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000001  target inline entry value count", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "00000001  config count", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000003  overlay entry count\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000000  string pool index offset\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f020000  target id\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f020000  overlay id\n", stream.str());
-  ASSERT_CONTAINS_REGEX(ADDRESS "7f020000  target id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f030000  target id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f030000  overlay id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f030002  target id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f030001  overlay id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "7f040000  target id\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "0000000e  config: land-xxhdpi-v7 size\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "........  config: land-xxhdpi-v7\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "      11  type: integer\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "12345678  data\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f020000  overlay id\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "7f030002  target id\n", stream.str());
   ASSERT_CONTAINS_REGEX(ADDRESS "00000004  string pool size\n", stream.str());
-  ASSERT_CONTAINS_REGEX("000000a4: ........  string pool\n", stream.str());
+  ASSERT_CONTAINS_REGEX(ADDRESS "........  string pool\n", stream.str());
 }
 
 }  // namespace android::idmap2
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index ca9a444..016d427 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -111,19 +111,20 @@
     return Error("Failed to find mapping for target resource");
   }
 
-  auto actual_overlay_value = std::get_if<TargetValue>(&entry_map->second);
-  if (actual_overlay_value == nullptr) {
+  auto config_map = std::get_if<ConfigMap>(&entry_map->second);
+  if (config_map == nullptr || config_map->empty()) {
     return Error("Target resource is not mapped to an inline value");
   }
+  auto actual_overlay_value = config_map->begin()->second;
 
-  if (actual_overlay_value->data_type != type) {
+  if (actual_overlay_value.data_type != type) {
     return Error(R"(Expected type: "0x%02x" Actual type: "0x%02x")", type,
-                 actual_overlay_value->data_type);
+                 actual_overlay_value.data_type);
   }
 
-  if (actual_overlay_value->data_value != value) {
+  if (actual_overlay_value.data_value != value) {
     return Error(R"(Expected value: "0x%08x" Actual value: "0x%08x")", type,
-                 actual_overlay_value->data_value);
+                 actual_overlay_value.data_value);
   }
 
   return Result<Unit>({});
diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h
index 6b5f3a8..45740e2 100644
--- a/cmds/idmap2/tests/TestHelpers.h
+++ b/cmds/idmap2/tests/TestHelpers.h
@@ -30,7 +30,7 @@
     0x49, 0x44, 0x4d, 0x50,
 
     // 0x4: version
-    0x08, 0x00, 0x00, 0x00,
+    0x09, 0x00, 0x00, 0x00,
 
     // 0x8: target crc
     0x34, 0x12, 0x00, 0x00,
@@ -76,66 +76,123 @@
     // 0x58: target_inline_entry_count
     0x01, 0x00, 0x00, 0x00,
 
-    // 0x5c: overlay_entry_count
+    // 0x5c: target_inline_entry_value_count
+    0x01, 0x00, 0x00, 0x00,
+
+    // 0x60: config_count
+    0x01, 0x00, 0x00, 0x00,
+
+    // 0x64: overlay_entry_count
     0x03, 0x00, 0x00, 0x00,
 
-    // 0x60: string_pool_offset
+    // 0x68: string_pool_offset
     0x00, 0x00, 0x00, 0x00,
 
     // TARGET ENTRIES
-    // 0x64: target id (0x7f020000)
+    // 0x6c: target id (0x7f020000)
     0x00, 0x00, 0x02, 0x7f,
 
-    // 0x68: overlay_id (0x7f020000)
+    // 0x70: overlay_id (0x7f020000)
     0x00, 0x00, 0x02, 0x7f,
 
-    // 0x6c: target id (0x7f030000)
+    // 0x74: target id (0x7f030000)
     0x00, 0x00, 0x03, 0x7f,
 
-    // 0x70: overlay_id (0x7f030000)
+    // 0x78: overlay_id (0x7f030000)
     0x00, 0x00, 0x03, 0x7f,
 
-    // 0x74: target id (0x7f030002)
+    // 0x7c: target id (0x7f030002)
     0x02, 0x00, 0x03, 0x7f,
 
-    // 0x78: overlay_id (0x7f030001)
+    // 0x80: overlay_id (0x7f030001)
     0x01, 0x00, 0x03, 0x7f,
 
     // INLINE TARGET ENTRIES
 
-    // 0x7c: target_id
+    // 0x84: target_id
     0x00, 0x00, 0x04, 0x7f,
 
-    // 0x80: Res_value::size (value ignored by idmap)
+    // 0x88: start value index
+    0x00, 0x00, 0x00, 0x00,
+
+    // 0x8c: value count
+    0x01, 0x00, 0x00, 0x00,
+
+    // INLINE TARGET ENTRY VALUES
+
+    // 0x90: config index
+    0x00, 0x00, 0x00, 0x00,
+
+    // 0x94: Res_value::size (value ignored by idmap)
     0x08, 0x00,
 
-    // 0x82: Res_value::res0 (value ignored by idmap)
+    // 0x98: Res_value::res0 (value ignored by idmap)
     0x00,
 
-    // 0x83: Res_value::dataType (TYPE_INT_HEX)
+    // 0x9c: Res_value::dataType (TYPE_INT_HEX)
     0x11,
 
-    // 0x84: Res_value::data
+    // 0xa0: Res_value::data
     0x78, 0x56, 0x34, 0x12,
 
+    // CONFIGURATIONS
+
+    // 0xa4: ConfigDescription
+    // size
+    0x40, 0x00, 0x00, 0x00,
+    // 0xa8: imsi
+    0x00, 0x00, 0x00, 0x00,
+    // 0xac: locale
+    0x00, 0x00, 0x00, 0x00,
+    // 0xb0: screenType
+    0x02, 0x00, 0xe0, 0x01,
+    // 0xb4: input
+    0x00, 0x00, 0x00, 0x00,
+    // 0xb8: screenSize
+    0x00, 0x00, 0x00, 0x00,
+    // 0xbc: version
+    0x07, 0x00, 0x00, 0x00,
+    // 0xc0: screenConfig
+    0x00, 0x00, 0x00, 0x00,
+    // 0xc4: screenSizeDp
+    0x00, 0x00, 0x00, 0x00,
+    // 0xc8: localeScript
+    0x00, 0x00, 0x00, 0x00,
+    // 0xcc: localVariant(1)
+    0x00, 0x00, 0x00, 0x00,
+    // 0xd0: localVariant(2)
+    0x00, 0x00, 0x00, 0x00,
+    // 0xd4: screenConfig2
+    0x00, 0x00, 0x00, 0x00,
+    // 0xd8: localeScriptWasComputed
+    0x00,
+    // 0xd9: localeNumberingSystem(1)
+    0x00, 0x00, 0x00, 0x00,
+    // 0xdd: localeNumberingSystem(2)
+    0x00, 0x00, 0x00, 0x00,
+
+    // 0xe1: padding
+    0x00, 0x00, 0x00,
+
+
     // OVERLAY ENTRIES
-    // 0x88: 0x7f020000 -> 0x7f020000
+    // 0xe4: 0x7f020000 -> 0x7f020000
     0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f,
 
-    // 0x90: 0x7f030000 -> 0x7f030000
+    // 0xec: 0x7f030000 -> 0x7f030000
     0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f,
 
-    // 0x98: 0x7f030001 -> 0x7f030002
+    // 0xf4: 0x7f030001 -> 0x7f030002
     0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f,
 
-    // 0xa0: string pool
+    // 0xfc: string pool
     // string length,
     0x04, 0x00, 0x00, 0x00,
 
-    // 0xa4 string contents "test"
+    // 0x100 string contents "test"
     0x74, 0x65, 0x73, 0x74};
 
-const unsigned int kIdmapRawDataLen = 0xa8;
+const unsigned int kIdmapRawDataLen = 0x104;
 const unsigned int kIdmapRawDataOffset = 0x54;
 const unsigned int kIdmapRawDataTargetCrc = 0x1234;
 const unsigned int kIdmapRawOverlayCrc = 0x5678;
diff --git a/core/api/current.txt b/core/api/current.txt
index f554e71..19713cf 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -5933,6 +5933,7 @@
     field public static final String EXTRA_BIG_TEXT = "android.bigText";
     field public static final String EXTRA_CALL_IS_VIDEO = "android.callIsVideo";
     field public static final String EXTRA_CALL_PERSON = "android.callPerson";
+    field public static final String EXTRA_CALL_TYPE = "android.callType";
     field public static final String EXTRA_CHANNEL_GROUP_ID = "android.intent.extra.CHANNEL_GROUP_ID";
     field public static final String EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID";
     field public static final String EXTRA_CHRONOMETER_COUNT_DOWN = "android.chronometerCountDown";
@@ -6240,6 +6241,10 @@
     method @NonNull public android.app.Notification.CallStyle setIsVideo(boolean);
     method @NonNull public android.app.Notification.CallStyle setVerificationIcon(@Nullable android.graphics.drawable.Icon);
     method @NonNull public android.app.Notification.CallStyle setVerificationText(@Nullable CharSequence);
+    field public static final int CALL_TYPE_INCOMING = 1; // 0x1
+    field public static final int CALL_TYPE_ONGOING = 2; // 0x2
+    field public static final int CALL_TYPE_SCREENING = 3; // 0x3
+    field public static final int CALL_TYPE_UNKNOWN = 0; // 0x0
   }
 
   public static final class Notification.CarExtender implements android.app.Notification.Extender {
@@ -18919,8 +18924,8 @@
     method public android.view.View onCreateCandidatesView();
     method public android.view.View onCreateExtractTextView();
     method @Nullable public android.view.inputmethod.InlineSuggestionsRequest onCreateInlineSuggestionsRequest(@NonNull android.os.Bundle);
-    method public android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl onCreateInputMethodInterface();
-    method public android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
+    method @Deprecated public android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl onCreateInputMethodInterface();
+    method @Deprecated public android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
     method public android.view.View onCreateInputView();
     method protected void onCurrentInputMethodSubtypeChanged(android.view.inputmethod.InputMethodSubtype);
     method public void onDisplayCompletions(android.view.inputmethod.CompletionInfo[]);
@@ -41572,7 +41577,7 @@
     field public static final String KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL = "show_signal_strength_in_sim_status_bool";
     field public static final String KEY_SHOW_VIDEO_CALL_CHARGES_ALERT_DIALOG_BOOL = "show_video_call_charges_alert_dialog_bool";
     field public static final String KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL = "show_wfc_location_privacy_policy_bool";
-    field public static final String KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL = "simplified_network_settings_bool";
+    field @Deprecated public static final String KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL = "simplified_network_settings_bool";
     field public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
     field public static final String KEY_SMDP_SERVER_ADDRESS_STRING = "smdp_server_address_string";
     field public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
@@ -48771,6 +48776,10 @@
     field public static final int KEYCODE_STEM_2 = 266; // 0x10a
     field public static final int KEYCODE_STEM_3 = 267; // 0x10b
     field public static final int KEYCODE_STEM_PRIMARY = 264; // 0x108
+    field public static final int KEYCODE_STYLUS_BUTTON_PRIMARY = 308; // 0x134
+    field public static final int KEYCODE_STYLUS_BUTTON_SECONDARY = 309; // 0x135
+    field public static final int KEYCODE_STYLUS_BUTTON_TAIL = 311; // 0x137
+    field public static final int KEYCODE_STYLUS_BUTTON_TERTIARY = 310; // 0x136
     field public static final int KEYCODE_SWITCH_CHARSET = 95; // 0x5f
     field public static final int KEYCODE_SYM = 63; // 0x3f
     field public static final int KEYCODE_SYSRQ = 120; // 0x78
@@ -53061,6 +53070,24 @@
     method @NonNull public android.view.inputmethod.DeleteGesture.Builder setGranularity(int);
   }
 
+  public final class DeleteRangeGesture extends android.view.inputmethod.HandwritingGesture implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.graphics.RectF getDeletionEndArea();
+    method @NonNull public android.graphics.RectF getDeletionStartArea();
+    method public int getGranularity();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.DeleteRangeGesture> CREATOR;
+  }
+
+  public static final class DeleteRangeGesture.Builder {
+    ctor public DeleteRangeGesture.Builder();
+    method @NonNull public android.view.inputmethod.DeleteRangeGesture build();
+    method @NonNull public android.view.inputmethod.DeleteRangeGesture.Builder setDeletionEndArea(@NonNull android.graphics.RectF);
+    method @NonNull public android.view.inputmethod.DeleteRangeGesture.Builder setDeletionStartArea(@NonNull android.graphics.RectF);
+    method @NonNull public android.view.inputmethod.DeleteRangeGesture.Builder setFallbackText(@Nullable String);
+    method @NonNull public android.view.inputmethod.DeleteRangeGesture.Builder setGranularity(int);
+  }
+
   public final class EditorBoundsInfo implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public android.graphics.RectF getEditorBounds();
@@ -53160,11 +53187,13 @@
   public abstract class HandwritingGesture {
     method @Nullable public String getFallbackText();
     field public static final int GESTURE_TYPE_DELETE = 4; // 0x4
+    field public static final int GESTURE_TYPE_DELETE_RANGE = 64; // 0x40
     field public static final int GESTURE_TYPE_INSERT = 2; // 0x2
     field public static final int GESTURE_TYPE_JOIN_OR_SPLIT = 16; // 0x10
     field public static final int GESTURE_TYPE_NONE = 0; // 0x0
     field public static final int GESTURE_TYPE_REMOVE_SPACE = 8; // 0x8
     field public static final int GESTURE_TYPE_SELECT = 1; // 0x1
+    field public static final int GESTURE_TYPE_SELECT_RANGE = 32; // 0x20
     field public static final int GRANULARITY_CHARACTER = 2; // 0x2
     field public static final int GRANULARITY_WORD = 1; // 0x1
   }
@@ -53549,6 +53578,24 @@
     method @NonNull public android.view.inputmethod.SelectGesture.Builder setSelectionArea(@NonNull android.graphics.RectF);
   }
 
+  public final class SelectRangeGesture extends android.view.inputmethod.HandwritingGesture implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getGranularity();
+    method @NonNull public android.graphics.RectF getSelectionEndArea();
+    method @NonNull public android.graphics.RectF getSelectionStartArea();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.SelectRangeGesture> CREATOR;
+  }
+
+  public static final class SelectRangeGesture.Builder {
+    ctor public SelectRangeGesture.Builder();
+    method @NonNull public android.view.inputmethod.SelectRangeGesture build();
+    method @NonNull public android.view.inputmethod.SelectRangeGesture.Builder setFallbackText(@Nullable String);
+    method @NonNull public android.view.inputmethod.SelectRangeGesture.Builder setGranularity(int);
+    method @NonNull public android.view.inputmethod.SelectRangeGesture.Builder setSelectionEndArea(@NonNull android.graphics.RectF);
+    method @NonNull public android.view.inputmethod.SelectRangeGesture.Builder setSelectionStartArea(@NonNull android.graphics.RectF);
+  }
+
   public final class SurroundingText implements android.os.Parcelable {
     ctor public SurroundingText(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0xffffffff) int);
     method public int describeContents();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 619e9fd..7dcfab4 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2804,6 +2804,7 @@
     method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.companion.virtual.audio.VirtualAudioDevice createVirtualAudioDevice(@NonNull android.hardware.display.VirtualDisplay, @Nullable java.util.concurrent.Executor, @Nullable android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChangeCallback);
     method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@IntRange(from=1) int, @IntRange(from=1) int, @IntRange(from=1) int, @Nullable android.view.Surface, int, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.display.VirtualDisplay.Callback);
+    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualDpad createVirtualDpad(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualKeyboard createVirtualKeyboard(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
@@ -4373,6 +4374,11 @@
 
 package android.hardware.input {
 
+  public class VirtualDpad implements java.io.Closeable {
+    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
+    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendKeyEvent(@NonNull android.hardware.input.VirtualKeyEvent);
+  }
+
   public final class VirtualKeyEvent implements android.os.Parcelable {
     method public int describeContents();
     method public int getAction();
@@ -6666,6 +6672,15 @@
 
 }
 
+package android.media.projection {
+
+  public class MediaProjectionGlobal {
+    method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface);
+    method @NonNull public static android.media.projection.MediaProjectionGlobal getInstance();
+  }
+
+}
+
 package android.media.session {
 
   public final class MediaSessionManager {
@@ -10041,7 +10056,7 @@
     method @WorkerThread public long getAllocatableBytes(@NonNull java.util.UUID, @RequiresPermission int) throws java.io.IOException;
     method @RequiresPermission(android.Manifest.permission.WRITE_MEDIA_STORAGE) public int getExternalStorageMountMode(int, @NonNull String);
     method public static boolean hasIsolatedStorage();
-    method public void updateExternalStorageFileQuotaType(@NonNull java.io.File, int) throws java.io.IOException;
+    method @RequiresPermission(android.Manifest.permission.MANAGE_EXTERNAL_STORAGE) public void updateExternalStorageFileQuotaType(@NonNull java.io.File, int) throws java.io.IOException;
     field @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE) public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
     field public static final int MOUNT_MODE_EXTERNAL_ANDROID_WRITABLE = 4; // 0x4
     field public static final int MOUNT_MODE_EXTERNAL_DEFAULT = 1; // 0x1
@@ -10366,6 +10381,7 @@
     field public static final String NAMESPACE_LOCATION = "location";
     field public static final String NAMESPACE_MEDIA = "media";
     field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
+    field public static final String NAMESPACE_NEARBY = "nearby";
     field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
     field public static final String NAMESPACE_NNAPI_NATIVE = "nnapi_native";
     field public static final String NAMESPACE_ON_DEVICE_PERSONALIZATION = "on_device_personalization";
@@ -10395,6 +10411,7 @@
     field public static final String NAMESPACE_TELEPHONY = "telephony";
     field public static final String NAMESPACE_TETHERING = "tethering";
     field public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
+    field public static final String NAMESPACE_TRANSPARENCY_METADATA = "transparency_metadata";
     field public static final String NAMESPACE_UWB = "uwb";
     field public static final String NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT = "window_manager_native_boot";
   }
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index f780e6f..887af1f 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1874,7 +1874,7 @@
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.content.pm.UserInfo> getUsers(boolean, boolean, boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle);
     method public static boolean isSplitSystemUser();
-    method public static boolean isUsersOnSecondaryDisplaysEnabled();
+    method public boolean isUsersOnSecondaryDisplaysSupported();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo preCreateUser(@NonNull String) throws android.os.UserManager.UserOperationException;
   }
 
@@ -2209,6 +2209,7 @@
     field public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE = "accessibility_shortcut_target_service";
     field public static final String ANR_SHOW_BACKGROUND = "anr_show_background";
     field public static final String AUTOFILL_SERVICE = "autofill_service";
+    field public static final String BIOMETRIC_VIRTUAL_ENABLED = "biometric_virtual_enabled";
     field public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled";
     field public static final String DISABLED_PRINT_SERVICES = "disabled_print_services";
     field @Deprecated public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = "enabled_notification_policy_access_packages";
@@ -2854,7 +2855,7 @@
     method public static String actionToString(int);
     method public final void setDisplayId(int);
     field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
-    field public static final int LAST_KEYCODE = 307; // 0x133
+    field public static final int LAST_KEYCODE = 311; // 0x137
   }
 
   public final class KeyboardShortcutGroup implements android.os.Parcelable {
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index 0a906be..f9b8a30 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -873,6 +873,8 @@
     New setting keys are not allowed (Field: ACCESSIBILITY_SHORTCUT_TARGET_SERVICE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_SERVICE:
     New setting keys are not allowed (Field: AUTOFILL_SERVICE); use getters/setters in relevant manager class
+NoSettingsProvider: android.provider.Settings.Secure#BIOMETRIC_VIRTUAL_ENABLED:
+    New setting keys are not allowed (Field: BIOMETRIC_VIRTUAL_ENABLED); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#CONTENT_CAPTURE_ENABLED:
     New setting keys are not allowed (Field: CONTENT_CAPTURE_ENABLED); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Secure#DISABLED_PRINT_SERVICES:
@@ -1011,7 +1013,7 @@
     Classes holding a set of parameters should be called `FooParams`, was `ContentCaptureOptions`
 
 
-VisiblySynchronized: PsiThisExpression:this:
+VisiblySynchronized: PsiThisExpression:
     Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getApkPaths()
 VisiblySynchronized: android.content.res.AssetManager#getApkPaths():
     Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.content.res.AssetManager.getApkPaths()
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index c2b315f..212e358 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -89,6 +89,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.StrictMode;
+import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.text.Selection;
@@ -8304,13 +8305,15 @@
         mIsInPictureInPictureMode = windowingMode == WINDOWING_MODE_PINNED;
         mShouldDockBigOverlays = getResources().getBoolean(R.bool.config_dockBigOverlayWindows);
         restoreHasCurrentPermissionRequest(icicle);
+        final long startTime = SystemClock.uptimeMillis();
         if (persistentState != null) {
             onCreate(icicle, persistentState);
         } else {
             onCreate(icicle);
         }
+        final long duration = SystemClock.uptimeMillis() - startTime;
         EventLogTags.writeWmOnCreateCalled(mIdent, getComponentName().getClassName(),
-                "performCreate");
+                "performCreate", duration);
         mActivityTransitionState.readState(icicle);
 
         mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
@@ -8332,8 +8335,11 @@
         mFragments.noteStateNotSaved();
         mCalled = false;
         mFragments.execPendingActions();
+        final long startTime = SystemClock.uptimeMillis();
         mInstrumentation.callActivityOnStart(this);
-        EventLogTags.writeWmOnStartCalled(mIdent, getComponentName().getClassName(), reason);
+        final long duration = SystemClock.uptimeMillis() - startTime;
+        EventLogTags.writeWmOnStartCalled(mIdent, getComponentName().getClassName(), reason,
+                duration);
 
         if (!mCalled) {
             throw new SuperNotCalledException(
@@ -8410,8 +8416,11 @@
             }
 
             mCalled = false;
+            final long startTime = SystemClock.uptimeMillis();
             mInstrumentation.callActivityOnRestart(this);
-            EventLogTags.writeWmOnRestartCalled(mIdent, getComponentName().getClassName(), reason);
+            final long duration = SystemClock.uptimeMillis() - startTime;
+            EventLogTags.writeWmOnRestartCalled(mIdent, getComponentName().getClassName(), reason,
+                    duration);
             if (!mCalled) {
                 throw new SuperNotCalledException(
                     "Activity " + mComponent.toShortString() +
@@ -8438,9 +8447,12 @@
         getAutofillClientController().onActivityPerformResume(followedByPause);
 
         mCalled = false;
+        final long startTime = SystemClock.uptimeMillis();
         // mResumed is set by the instrumentation
         mInstrumentation.callActivityOnResume(this);
-        EventLogTags.writeWmOnResumeCalled(mIdent, getComponentName().getClassName(), reason);
+        final long duration = SystemClock.uptimeMillis() - startTime;
+        EventLogTags.writeWmOnResumeCalled(mIdent, getComponentName().getClassName(), reason,
+                duration);
         if (!mCalled) {
             throw new SuperNotCalledException(
                 "Activity " + mComponent.toShortString() +
@@ -8483,9 +8495,11 @@
         mDoReportFullyDrawn = false;
         mFragments.dispatchPause();
         mCalled = false;
+        final long startTime = SystemClock.uptimeMillis();
         onPause();
+        final long duration = SystemClock.uptimeMillis() - startTime;
         EventLogTags.writeWmOnPausedCalled(mIdent, getComponentName().getClassName(),
-                "performPause");
+                "performPause", duration);
         mResumed = false;
         if (!mCalled && getApplicationInfo().targetSdkVersion
                 >= android.os.Build.VERSION_CODES.GINGERBREAD) {
@@ -8529,8 +8543,11 @@
             mFragments.dispatchStop();
 
             mCalled = false;
+            final long startTime = SystemClock.uptimeMillis();
             mInstrumentation.callActivityOnStop(this);
-            EventLogTags.writeWmOnStopCalled(mIdent, getComponentName().getClassName(), reason);
+            final long duration = SystemClock.uptimeMillis() - startTime;
+            EventLogTags.writeWmOnStopCalled(mIdent, getComponentName().getClassName(), reason,
+                    duration);
             if (!mCalled) {
                 throw new SuperNotCalledException(
                     "Activity " + mComponent.toShortString() +
@@ -8564,9 +8581,11 @@
         mDestroyed = true;
         mWindow.destroy();
         mFragments.dispatchDestroy();
+        final long startTime = SystemClock.uptimeMillis();
         onDestroy();
+        final long duration = SystemClock.uptimeMillis() - startTime;
         EventLogTags.writeWmOnDestroyCalled(mIdent, getComponentName().getClassName(),
-                "performDestroy");
+                "performDestroy", duration);
         mFragments.doLoaderDestroy();
         if (mVoiceInteractor != null) {
             mVoiceInteractor.detachActivity();
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d899dab..dfef279 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -4216,13 +4216,23 @@
         }
     }*/
 
+    /** @hide
+     * Determines whether the given UID can access unexported components
+     * @param uid the calling UID
+     * @return true if the calling UID is ROOT or SYSTEM
+     */
+    public static boolean canAccessUnexportedComponents(int uid) {
+        final int appId = UserHandle.getAppId(uid);
+        return (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID);
+    }
+
     /** @hide */
     @UnsupportedAppUsage
     public static int checkComponentPermission(String permission, int uid,
             int owningUid, boolean exported) {
         // Root, system server get to do everything.
         final int appId = UserHandle.getAppId(uid);
-        if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
+        if (canAccessUnexportedComponents(uid)) {
             return PackageManager.PERMISSION_GRANTED;
         }
         // Isolated processes don't get any permissions.
@@ -4350,20 +4360,28 @@
     }
 
     /**
-     * Starts the given user in background and associate the user with the given display.
+     * Starts the given user in background and assign the user to the given display.
      *
      * <p>This method will allow the user to launch activities on that display, and it's typically
      * used only on automotive builds when the vehicle has multiple displays (you can verify if it's
-     * supported by calling {@link UserManager#isBackgroundUsersOnSecondaryDisplaysSupported()}).
+     * supported by calling {@link UserManager#isUsersOnSecondaryDisplaysSupported()}).
      *
-     * @return whether the user was started.
+     * <p><b>NOTE:</b> differently from {@link #switchUser(int)}, which stops the current foreground
+     * user before starting a new one, this method does not stop the previous user running in
+     * background in the display, and it will return {@code false} in this case. It's up to the
+     * caller to call {@link #stopUser(int, boolean)} before starting a new user.
+     *
+     * @param userId user to be started in the display. It will return {@code false} if the user is
+     * a profile, the {@link #getCurrentUser()}, the {@link UserHandle#SYSTEM system user}, or
+     * does not exist.
+     *
+     * @param displayId id of the display, it must exist.
+     *
+     * @return whether the operation succeeded. Notice that if the user was already started in such
+     * display before, it will return {@code false}.
      *
      * @throws UnsupportedOperationException if the device does not support background users on
      * secondary displays.
-     * @throws IllegalArgumentException if the display does not exist.
-     * @throws IllegalStateException if the user cannot be started on that display (for example, if
-     * there's already a user using that display or if the user is already associated with other
-     * display).
      *
      * @hide
      */
@@ -4372,6 +4390,10 @@
             android.Manifest.permission.CREATE_USERS})
     public boolean startUserInBackgroundOnSecondaryDisplay(@UserIdInt int userId,
             int displayId) {
+        if (!UserManager.isUsersOnSecondaryDisplaysEnabled()) {
+            throw new UnsupportedOperationException(
+                    "device does not support users on secondary displays");
+        }
         try {
             return getService().startUserInBackgroundOnSecondaryDisplay(userId, displayId);
         } catch (RemoteException e) {
@@ -4532,6 +4554,10 @@
     /**
      * Stops the given {@code userId}.
      *
+     * <p><b>NOTE:</b> on systems that support
+     * {@link UserManager#isUsersOnSecondaryDisplaysSupported() background users on secondary
+     * displays}, this method will also unassign the user from the display it was started on.
+     *
      * @hide
      */
     @TestApi
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 2a0553e..03c1e07 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -554,7 +554,7 @@
      * @hide
      */
     public static int resolveFirstUnrestrictedUidState(int op) {
-        return UID_STATE_FOREGROUND;
+        return UID_STATE_MAX_LAST_NON_RESTRICTED;
     }
 
     /**
@@ -1910,6 +1910,7 @@
             OP_SCHEDULE_EXACT_ALARM,
             OP_MANAGE_MEDIA,
             OP_TURN_SCREEN_ON,
+            OP_GET_USAGE_STATS,
     };
 
     static final AppOpInfo[] sAppOpInfos = new AppOpInfo[]{
diff --git a/core/java/android/app/EventLogTags.logtags b/core/java/android/app/EventLogTags.logtags
index d0856f4..479f5a6 100644
--- a/core/java/android/app/EventLogTags.logtags
+++ b/core/java/android/app/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package android.app
 
@@ -6,21 +6,21 @@
 # google3/googledata/wireless/android/provisioning/gservices.config !!
 #
 # The activity's onPause has been called.
-30021 wm_on_paused_called (Token|1|5),(Component Name|3),(Reason|3)
+30021 wm_on_paused_called (Token|1|5),(Component Name|3),(Reason|3),(time|2|3)
 # The activity's onResume has been called.
-30022 wm_on_resume_called (Token|1|5),(Component Name|3),(Reason|3)
+30022 wm_on_resume_called (Token|1|5),(Component Name|3),(Reason|3),(time|2|3)
 
 # The activity's onStop has been called.
-30049 wm_on_stop_called (Token|1|5),(Component Name|3),(Reason|3)
+30049 wm_on_stop_called (Token|1|5),(Component Name|3),(Reason|3),(time|2|3)
 
 # The activity's onCreate has been called.
-30057 wm_on_create_called (Token|1|5),(Component Name|3),(Reason|3)
+30057 wm_on_create_called (Token|1|5),(Component Name|3),(Reason|3),(time|2|3)
 # The activity's onRestart has been called.
-30058 wm_on_restart_called (Token|1|5),(Component Name|3),(Reason|3)
+30058 wm_on_restart_called (Token|1|5),(Component Name|3),(Reason|3),(time|2|3)
 # The activity's onStart has been called.
-30059 wm_on_start_called (Token|1|5),(Component Name|3),(Reason|3)
+30059 wm_on_start_called (Token|1|5),(Component Name|3),(Reason|3),(time|2|3)
 # The activity's onDestroy has been called.
-30060 wm_on_destroy_called (Token|1|5),(Component Name|3),(Reason|3)
+30060 wm_on_destroy_called (Token|1|5),(Component Name|3),(Reason|3),(time|2|3)
 # The activity's onActivityResult has been called.
 30062 wm_on_activity_result_called (Token|1|5),(Component Name|3),(Reason|3)
 
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 93381cf..81f6143 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -258,6 +258,11 @@
  * pressing back will pop it to return the user to whatever previous state
  * the activity UI was in.
  *
+ * <p>
+ * Fragments appearing or disappearing do not generate system events for accessibility, so set a
+ * title on your fragments with {@link View#setAccessibilityPaneTitle(CharSequence)} to notify
+ * accessibility users of these UI transitions.
+ *
  * @deprecated Use the <a href="{@docRoot}jetpack">Jetpack Fragment Library</a>
  *      {@link androidx.fragment.app.Fragment} for consistent behavior across all devices
  *      and access to <a href="{@docRoot}topic/libraries/architecture/lifecycle.html">Lifecycle</a>.
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 9c8d010..980b79b 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -766,6 +766,8 @@
      *
      * <p>Typically used only by automotive builds when the vehicle has multiple displays.
      */
+    @JavaPassthrough(annotation=
+            "@android.annotation.RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional = true)")
     boolean startUserInBackgroundOnSecondaryDisplay(int userid, int displayId);
 
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 343adb8..9bbebc8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1421,7 +1421,6 @@
     /**
      * {@link #extras} key: the type of call represented by the
      * {@link android.app.Notification.CallStyle} notification. This extra is an int.
-     * @hide
      */
     public static final String EXTRA_CALL_TYPE = "android.callType";
 
@@ -9301,11 +9300,43 @@
      * </pre>
      */
     public static class CallStyle extends Style {
-        /** @hide */
+
+        /**
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({
+                CALL_TYPE_UNKNOWN,
+                CALL_TYPE_INCOMING,
+                CALL_TYPE_ONGOING,
+                CALL_TYPE_SCREENING
+        })
+        public @interface CallType {};
+
+        /**
+         * Unknown call type.
+         *
+         * See {@link #EXTRA_CALL_TYPE}.
+         */
+        public static final int CALL_TYPE_UNKNOWN = 0;
+
+        /**
+         *  Call type for incoming calls.
+         *
+         *  See {@link #EXTRA_CALL_TYPE}.
+         */
         public static final int CALL_TYPE_INCOMING = 1;
-        /** @hide */
+        /**
+         * Call type for ongoing calls.
+         *
+         * See {@link #EXTRA_CALL_TYPE}.
+         */
         public static final int CALL_TYPE_ONGOING = 2;
-        /** @hide */
+        /**
+         * Call type for calls that are being screened.
+         *
+         * See {@link #EXTRA_CALL_TYPE}.
+         */
         public static final int CALL_TYPE_SCREENING = 3;
 
         /**
@@ -9392,13 +9423,14 @@
         }
 
         /**
+         * @param callType The type of the call
          * @param person The person displayed for the incoming call.
          *             The user also needs to have a non-empty name associated with it.
          * @param hangUpIntent The intent to be sent when the user taps the hang up action
          * @param declineIntent The intent to be sent when the user taps the decline action
          * @param answerIntent The intent to be sent when the user taps the answer action
          */
-        private CallStyle(int callType, @NonNull Person person,
+        private CallStyle(@CallType int callType, @NonNull Person person,
                 @Nullable PendingIntent hangUpIntent, @Nullable PendingIntent declineIntent,
                 @Nullable PendingIntent answerIntent) {
             if (person == null || TextUtils.isEmpty(person.getName())) {
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 13934e5..a51b9d3 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -391,7 +391,12 @@
     private static final boolean DEBUG = false;
     private static final boolean VERIFY = false;
 
-    // Per-Cache performance counters. As some cache instances are declared static,
+    /**
+     * The object-private lock.
+     */
+    private final Object mLock = new Object();
+
+    // Per-Cache performance counters.
     @GuardedBy("mLock")
     private long mHits = 0;
 
@@ -410,27 +415,21 @@
     @GuardedBy("mLock")
     private long mClears = 0;
 
-    // Most invalidation is done in a static context, so the counters need to be accessible.
-    @GuardedBy("sCorkLock")
-    private static final HashMap<String, Long> sInvalidates = new HashMap<>();
+    /**
+     * Protect objects that support corking.  mLock and sGlobalLock must never be taken while this
+     * is held.
+     */
+    private static final Object sCorkLock = new Object();
 
     /**
-     * Record the number of invalidate or cork calls that were nops because
-     * the cache was already corked.  This is static because invalidation is
-     * done in a static context.
+     * Record the number of invalidate or cork calls that were nops because the cache was already
+     * corked.  This is static because invalidation is done in a static context.  Entries are
+     * indexed by the cache property.
      */
     @GuardedBy("sCorkLock")
     private static final HashMap<String, Long> sCorkedInvalidates = new HashMap<>();
 
     /**
-     * If sEnabled is false then all cache operations are stubbed out.  Set
-     * it to false inside test processes.
-     */
-    private static boolean sEnabled = true;
-
-    private static final Object sCorkLock = new Object();
-
-    /**
      * A map of cache keys that we've "corked". (The values are counts.)  When a cache key is
      * corked, we skip the cache invalidate when the cache key is in the unset state --- that
      * is, when a cache key is corked, an invalidation does not enable the cache if somebody
@@ -440,21 +439,39 @@
     private static final HashMap<String, Integer> sCorks = new HashMap<>();
 
     /**
+     * A lock for the global list of caches and cache keys.  This must never be taken inside mLock
+     * or sCorkLock.
+     */
+    private static final Object sGlobalLock = new Object();
+
+    /**
      * A map of cache keys that have been disabled in the local process.  When a key is
      * disabled locally, existing caches are disabled and the key is saved in this map.
      * Future cache instances that use the same key will be disabled in their constructor.
      */
-    @GuardedBy("sCorkLock")
+    @GuardedBy("sGlobalLock")
     private static final HashSet<String> sDisabledKeys = new HashSet<>();
 
     /**
      * Weakly references all cache objects in the current process, allowing us to iterate over
      * them all for purposes like issuing debug dumps and reacting to memory pressure.
      */
-    @GuardedBy("sCorkLock")
+    @GuardedBy("sGlobalLock")
     private static final WeakHashMap<PropertyInvalidatedCache, Void> sCaches = new WeakHashMap<>();
 
-    private final Object mLock = new Object();
+    /**
+     * Counts of the number of times a cache key was invalidated.  Invalidation occurs in a static
+     * context with no cache object available, so this is a static map.  Entries are indexed by
+     * the cache property.
+     */
+    @GuardedBy("sGlobalLock")
+    private static final HashMap<String, Long> sInvalidates = new HashMap<>();
+
+    /**
+     * If sEnabled is false then all cache operations are stubbed out.  Set
+     * it to false inside test processes.
+     */
+    private static boolean sEnabled = true;
 
     /**
      * Name of the property that holds the unique value that we use to invalidate the cache.
@@ -595,14 +612,17 @@
         };
     }
 
-    // Register the map in the global list.  If the cache is disabled globally, disable it
-    // now.
+    /**
+     * Register the map in the global list.  If the cache is disabled globally, disable it
+     * now.  This method is only ever called from the constructor, which means no other thread has
+     * access to the object yet.  It can safely be modified outside any lock.
+     */
     private void registerCache() {
-        synchronized (sCorkLock) {
-            sCaches.put(this, null);
+        synchronized (sGlobalLock) {
             if (sDisabledKeys.contains(mCacheName)) {
                 disableInstance();
             }
+            sCaches.put(this, null);
         }
     }
 
@@ -797,8 +817,9 @@
     }
 
     /**
-     * Disable the use of this cache in this process.  This method is using during
-     * testing.  To disable a cache in normal code, use disableLocal().
+     * Disable the use of this cache in this process.  This method is using internally and during
+     * testing.  To disable a cache in normal code, use disableLocal().  A disabled cache cannot
+     * be re-enabled.
      * @hide
      */
     @TestApi
@@ -811,17 +832,23 @@
 
     /**
      * Disable the local use of all caches with the same name.  All currently registered caches
-     * using the key will be disabled now, and all future cache instances that use the key will be
-     * disabled in their constructor.
+     * with the name will be disabled now, and all future cache instances that use the name will
+     * be disabled in their constructor.
      */
     private static final void disableLocal(@NonNull String name) {
-        synchronized (sCorkLock) {
-            sDisabledKeys.add(name);
+        synchronized (sGlobalLock) {
+            if (sDisabledKeys.contains(name)) {
+                // The key is already in recorded so there is no further work to be done.
+                return;
+            }
             for (PropertyInvalidatedCache cache : sCaches.keySet()) {
                 if (name.equals(cache.mCacheName)) {
                     cache.disableInstance();
                 }
             }
+            // Record the disabled key after the iteration.  If an exception occurs during the
+            // iteration above, and the code is retried, the function should not exit early.
+            sDisabledKeys.add(name);
         }
     }
 
@@ -834,7 +861,7 @@
      */
     @TestApi
     public final void forgetDisableLocal() {
-        synchronized (sCorkLock) {
+        synchronized (sGlobalLock) {
             sDisabledKeys.remove(mCacheName);
         }
     }
@@ -851,9 +878,9 @@
     }
 
     /**
-     * Disable this cache in the current process, and all other caches that use the same
-     * name.  This does not affect caches that have a different name but use the same
-     * property.
+     * Disable this cache in the current process, and all other present and future caches that use
+     * the same name.  This does not affect caches that have a different name but use the same
+     * property.  Once disabled, a cache cannot be reenabled.
      * @hide
      */
     @TestApi
@@ -1381,10 +1408,9 @@
     /**
      * Returns a list of caches alive at the current time.
      */
+    @GuardedBy("sGlobalLock")
     private static @NonNull ArrayList<PropertyInvalidatedCache> getActiveCaches() {
-        synchronized (sCorkLock) {
-            return new ArrayList<PropertyInvalidatedCache>(sCaches.keySet());
-        }
+        return new ArrayList<PropertyInvalidatedCache>(sCaches.keySet());
     }
 
     /**
@@ -1540,7 +1566,7 @@
         boolean detail = anyDetailed(args);
 
         ArrayList<PropertyInvalidatedCache> activeCaches;
-        synchronized (sCorkLock) {
+        synchronized (sGlobalLock) {
             activeCaches = getActiveCaches();
             if (!detail) {
                 dumpCorkInfo(pw);
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 8d57e32..d17f2ba 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -45,6 +45,7 @@
 import android.view.WindowContentFrameStats;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.IAccessibilityManager;
+import android.window.ScreenCapture;
 
 import libcore.io.IoUtils;
 
@@ -220,13 +221,13 @@
             int width = crop.width();
             int height = crop.height();
             final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
-            final SurfaceControl.DisplayCaptureArgs captureArgs =
-                    new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
+            final ScreenCapture.DisplayCaptureArgs captureArgs =
+                    new ScreenCapture.DisplayCaptureArgs.Builder(displayToken)
                             .setSourceCrop(crop)
                             .setSize(width, height)
                             .build();
-            final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                    SurfaceControl.captureDisplay(captureArgs);
+            final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                    ScreenCapture.captureDisplay(captureArgs);
             return screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -242,11 +243,11 @@
             throwIfNotConnectedLocked();
         }
 
-        SurfaceControl.ScreenshotHardwareBuffer captureBuffer;
+        ScreenCapture.ScreenshotHardwareBuffer captureBuffer;
         final long identity = Binder.clearCallingIdentity();
         try {
-            captureBuffer = SurfaceControl.captureLayers(
-                    new SurfaceControl.LayerCaptureArgs.Builder(surfaceControl)
+            captureBuffer = ScreenCapture.captureLayers(
+                    new ScreenCapture.LayerCaptureArgs.Builder(surfaceControl)
                             .setChildrenOnly(false)
                             .build());
         } finally {
diff --git a/core/java/android/app/UidObserver.java b/core/java/android/app/UidObserver.java
new file mode 100644
index 0000000..9e92807
--- /dev/null
+++ b/core/java/android/app/UidObserver.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/**
+ * Default implementation of {@link IUidObserver} for which all methods are
+ * no-op. Subclasses can override the select methods they're interested in
+ * handling.
+ *
+ * @hide
+ */
+public class UidObserver extends IUidObserver.Stub {
+    @Override
+    public void onUidActive(int uid) {
+    }
+
+    @Override
+    public void onUidCachedChanged(int uid, boolean cached) {
+    }
+
+    @Override
+    public void onUidGone(int uid, boolean disabled) {
+    }
+
+    @Override
+    public void onUidIdle(int uid, boolean disabled) {
+    }
+
+    @Override
+    public void onUidProcAdjChanged(int uid) {
+    }
+
+    @Override
+    public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
+    }
+}
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index 8cfbf2f..9c99da5 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -57,6 +57,12 @@
 
     void onAudioSessionEnded();
 
+    void createVirtualDpad(
+            int displayId,
+            String inputDeviceName,
+            int vendorId,
+            int productId,
+            IBinder token);
     void createVirtualKeyboard(
             int displayId,
             String inputDeviceName,
@@ -77,6 +83,7 @@
             IBinder token,
             in Point screenSize);
     void unregisterInputDevice(IBinder token);
+    boolean sendDpadKeyEvent(IBinder token, in VirtualKeyEvent event);
     boolean sendKeyEvent(IBinder token, in VirtualKeyEvent event);
     boolean sendButtonEvent(IBinder token, in VirtualMouseButtonEvent event);
     boolean sendRelativeEvent(IBinder token, in VirtualMouseRelativeEvent event);
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 1b93bb8..d4c9a42 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -37,6 +37,7 @@
 import android.hardware.display.IVirtualDisplayCallback;
 import android.hardware.display.VirtualDisplay;
 import android.hardware.display.VirtualDisplayConfig;
+import android.hardware.input.VirtualDpad;
 import android.hardware.input.VirtualKeyboard;
 import android.hardware.input.VirtualMouse;
 import android.hardware.input.VirtualTouchscreen;
@@ -315,6 +316,32 @@
         }
 
         /**
+         * Creates a virtual dpad.
+         *
+         * @param display the display that the events inputted through this device should target
+         * @param inputDeviceName the name to call this input device
+         * @param vendorId the PCI vendor id
+         * @param productId the product id, as defined by the vendor
+         */
+        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+        @NonNull
+        public VirtualDpad createVirtualDpad(
+                @NonNull VirtualDisplay display,
+                @NonNull String inputDeviceName,
+                int vendorId,
+                int productId) {
+            try {
+                final IBinder token = new Binder(
+                        "android.hardware.input.VirtualDpad:" + inputDeviceName);
+                mVirtualDevice.createVirtualDpad(display.getDisplay().getDisplayId(),
+                        inputDeviceName, vendorId, productId, token);
+                return new VirtualDpad(mVirtualDevice, token);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
          * Creates a virtual keyboard.
          *
          * @param display the display that the events inputted through this device should target
diff --git a/core/java/android/content/res/ResourceTimer.java b/core/java/android/content/res/ResourceTimer.java
new file mode 100644
index 0000000..13f0b72
--- /dev/null
+++ b/core/java/android/content/res/ResourceTimer.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.res;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.FastPrintWriter;
+
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+/**
+ * Provides access to the resource timers without intruding on other classes.
+ * @hide
+ */
+public final class ResourceTimer {
+    private static final String TAG = "ResourceTimer";
+
+    // Enable metrics in this process.  The flag may be set false in some processes.  The flag is
+    // never set true at runtime, so setting it false here disables the feature entirely.
+    private static boolean sEnabled = true;
+
+    // Set true for incremental metrics (the counters are reset after every fetch).  Set false for
+    // cumulative metrics (the counters are never reset and accumulate values for the lifetime of
+    // the process).
+    private static boolean sIncrementalMetrics = true;
+
+    // Set true to enable some debug behavior.
+    private static boolean ENABLE_DEBUG = false;
+
+    // The global lock.
+    private static final Object sLock = new Object();
+
+    // The singleton cache manager
+    private static ResourceTimer sManager;
+
+    // The handler for the timeouts.
+    private static Handler mHandler;
+
+    // The time at which the process started.
+    private final static long sProcessStart = SystemClock.uptimeMillis();
+
+    // Metrics are published at offsets from the process start.  Processes publish at five minutes
+    // and one hour.  Thereafter, metrics are published every 12 hours.  The values in this array
+    // are in units of minutes.
+    private static final long[] sPublicationPoints = new long[]{ 5, 60, 60 * 12 };
+
+    // The index of the latest publication point.
+    private static int sCurrentPoint;
+
+    /**
+     * The runtime timer configuration.
+     */
+    private static class Config {
+        // The number of timers in the runtime
+        int maxTimer;
+        // The number of histogram buckets per timer.
+        int maxBuckets;
+        // The number of "largest" values per timer.
+        int maxLargest;
+        // A string label for each timer.  This array has maxTimer elements.
+        String[] timers;
+    }
+
+    /**
+     * The timer information that is pulled from the native runtime.  All times have units of ns.
+     */
+    private static class Timer {
+        int count;
+        long total;
+        int mintime;
+        int maxtime;
+        int[] largest;
+        int[] percentile;
+        @Override
+        public String toString() {
+            return TextUtils.formatSimple("%d:%d:%d:%d", count, total, mintime, maxtime);
+        }
+    }
+
+    /**
+     * A singleton Config.  This is initialized when the timers are started.
+     */
+    @GuardedBy("sLock")
+    private static Config sConfig;
+
+    /**
+     * A singleton Summary object that is refilled from the native side.  The length of the array
+     * is the number of timers that can be fetched.  nativeGetTimers() will fill the array to the
+     * smaller of the length of the array or the actual number of timers in the runtime.  The
+     * actual number of timers in the run time is returned by the function.
+     */
+    @GuardedBy("sLock")
+    private static Timer[] sTimers;
+
+    /**
+     * The time at which the local timer array was last updated.  This has the same units as
+     * sProcessStart; the difference is the process run time.
+     */
+    @GuardedBy("sLock")
+    private static long sLastUpdated = 0;
+
+    // The constructor is private.  Use the factory to get a hold of the manager.
+    private ResourceTimer() {
+        throw new RuntimeException("ResourceTimer constructor");
+    }
+
+    /**
+     * Start the manager.  This runs a periodic job that collects and publishes timer values.
+     * This is not part of the constructor only because the looper failicities might not be
+     * available at the beginning of time.
+     */
+    public static void start() {
+        synchronized (sLock) {
+            if (!sEnabled) {
+                return;
+            }
+            if (mHandler != null) {
+                // Nothing to be done.  The job has already been started.
+                return;
+            }
+            if (Looper.getMainLooper() == null) {
+                throw new RuntimeException("ResourceTimer started too early");
+            }
+            mHandler = new Handler(Looper.getMainLooper()) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        ResourceTimer.handleMessage(msg);
+                    }
+                };
+
+            // Initialize the container that holds information from the native runtime.  The
+            // container is built according to the dimensions returned by the native layer.
+            sConfig = new Config();
+            nativeEnableTimers(sConfig);
+            sTimers = new Timer[sConfig.maxTimer];
+            for (int i = 0; i < sTimers.length; i++) {
+                sTimers[i] = new Timer();
+                sTimers[i].percentile = new int[sConfig.maxBuckets];
+                sTimers[i].largest = new int[sConfig.maxLargest];
+            }
+
+            sCurrentPoint = 0;
+            startTimer();
+        }
+    }
+
+    /**
+     * Handle a refresh message.  Publish the metrics and start a timer for the next publication.
+     * The message parameter is unused.
+     */
+    private static void handleMessage(Message msg) {
+        synchronized (sLock) {
+            publish();
+            startTimer();
+        }
+    }
+
+    /**
+     * Start a timer to the next publication point.  Publication points are referenced from
+     * process start.
+     */
+    @GuardedBy("sLock")
+    private static void startTimer() {
+        // The delay is in minutes.
+        long delay;
+        if (sCurrentPoint < sPublicationPoints.length) {
+            delay = sPublicationPoints[sCurrentPoint];
+        } else {
+            // Repeat with the final publication point.
+            delay = sCurrentPoint * sPublicationPoints[sPublicationPoints.length - 1];
+        }
+        // Convert minutes to milliseconds.
+        delay *= 60 * 1000;
+        // If debug is enabled, convert hours down to minutes.
+        if (ENABLE_DEBUG) {
+            delay /= 60;
+        }
+        mHandler.sendEmptyMessageAtTime(0, sProcessStart + delay);
+    }
+
+    /**
+     * Update the local copy of the timers.  The current time is saved as well.
+     */
+    @GuardedBy("sLock")
+    private static void update(boolean reset) {
+        nativeGetTimers(sTimers, reset);
+        sLastUpdated = SystemClock.uptimeMillis();
+    }
+
+    /**
+     * Retrieve the accumulated timer information, reset the native counters, and advance the
+     * publication point.
+     */
+    @GuardedBy("sLock")
+    private static void publish() {
+        update(true);
+        // Log the number of records read.  This happens a few times a day.
+        for (int i = 0; i < sTimers.length; i++) {
+            if (sTimers[i].count > 0) {
+                Log.i(TAG, TextUtils.formatSimple("%s count=%d pvalues=%s",
+                                sConfig.timers[i], sTimers[i].count,
+                                packedString(sTimers[i].percentile)));
+            }
+        }
+        sCurrentPoint++;
+    }
+
+    /**
+     * Given an int[], return a string that is formatted as "a,b,c" with no spaces.
+     */
+    private static String packedString(int[] a) {
+        return Arrays.toString(a).replaceAll("[\\]\\[ ]", "");
+    }
+
+    /**
+     * Update the metrics information and dump it.
+     * @hide
+     */
+    public static void dumpTimers(@NonNull ParcelFileDescriptor pfd, @Nullable String[] args) {
+        FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor());
+        PrintWriter pw = new FastPrintWriter(fout);
+        synchronized (sLock) {
+            if (!sEnabled || (sConfig == null)) {
+                pw.println("  Timers are not enabled in this process");
+                pw.flush();
+                return;
+            }
+        }
+
+        // Look for the --refresh switch.  If the switch is present, then sTimers is updated.
+        // Otherwise, the current value of sTimers is displayed.
+        boolean refresh = Arrays.asList(args).contains("-refresh");
+
+        synchronized (sLock) {
+            update(refresh);
+            long runtime = sLastUpdated - sProcessStart;
+            pw.format("  config runtime=%d proc=%s\n", runtime, Process.myProcessName());
+            for (int i = 0; i < sTimers.length; i++) {
+                Timer t = sTimers[i];
+                if (t.count != 0) {
+                    String name = sConfig.timers[i];
+                    pw.format("  stats timer=%s cnt=%d avg=%d min=%d max=%d pval=%s "
+                        + "largest=%s\n",
+                        name, t.count, t.total / t.count, t.mintime, t.maxtime,
+                        packedString(t.percentile),
+                        packedString(t.largest));
+                }
+            }
+        }
+        pw.flush();
+    }
+
+    // Enable (or disabled) the runtime timers.  Note that timers are disabled by default.  This
+    // retrieves the runtime timer configuration that are taking effect
+    private static native int nativeEnableTimers(@NonNull Config config);
+
+    // Retrieve the timers from the native layer.  If reset is true, the timers are reset after
+    // being fetched.  The method returns the number of timers that are defined in the runtime
+    // layer.  The stats array is filled out to the smaller of its actual size and the number of
+    // runtime timers; it never overflows.
+    private static native int nativeGetTimers(@NonNull Timer[] stats, boolean reset);
+}
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index c59d757..257ad71 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -315,17 +315,17 @@
     int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
 
     /**
-     * Whether the FingerprintAcquired message is a signal to turn off HBM
+     * Whether the FingerprintAcquired message is a signal to disable the UDFPS display mode.
+     * We want to disable the UDFPS mode as soon as possible to conserve power and provide better
+     * UX. For example, prolonged high-brightness illumination of optical sensors can be unpleasant
+     * to the user, can cause long term display burn-in, and can drain the battery faster.
      */
-    static boolean shouldTurnOffHbm(@FingerprintAcquired int acquiredInfo) {
+    static boolean shouldDisableUdfpsDisplayMode(@FingerprintAcquired int acquiredInfo) {
         switch (acquiredInfo) {
             case FINGERPRINT_ACQUIRED_START:
-                // Authentication just began
+                // Keep the UDFPS mode because the authentication just began.
                 return false;
             case FINGERPRINT_ACQUIRED_GOOD:
-                // Good image captured. Turn off HBM. Success/Reject comes after, which is when
-                // hideUdfpsOverlay will be called.
-                return true;
             case FINGERPRINT_ACQUIRED_PARTIAL:
             case FINGERPRINT_ACQUIRED_INSUFFICIENT:
             case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
@@ -334,11 +334,12 @@
             case FINGERPRINT_ACQUIRED_IMMOBILE:
             case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
             case FINGERPRINT_ACQUIRED_VENDOR:
-                // Bad image captured. Turn off HBM. Matcher will not run, so there's no need to
-                // keep HBM on.
+                // Disable the UDFPS mode because the image capture has finished. The overlay
+                // can be hidden later, once the authentication result arrives.
                 return true;
             case FINGERPRINT_ACQUIRED_UNKNOWN:
             default:
+                // Keep the UDFPS mode in case of an unknown message.
                 return false;
         }
     }
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 52cef0f..00bccc6 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -31,6 +31,7 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 import android.window.DisplayWindowPolicyController;
+import android.window.ScreenCapture;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -118,7 +119,7 @@
      * @param displayId The display id to take the screenshot of.
      * @return The buffer or null if we have failed.
      */
-    public abstract SurfaceControl.ScreenshotHardwareBuffer systemScreenshot(int displayId);
+    public abstract ScreenCapture.ScreenshotHardwareBuffer systemScreenshot(int displayId);
 
     /**
      * General screenshot functionality that excludes secure layers and applies appropriate
@@ -127,7 +128,7 @@
      * @param displayId The display id to take the screenshot of.
      * @return The buffer or null if we have failed.
      */
-    public abstract SurfaceControl.ScreenshotHardwareBuffer userScreenshot(int displayId);
+    public abstract ScreenCapture.ScreenshotHardwareBuffer userScreenshot(int displayId);
 
     /**
      * Returns information about the specified logical display.
@@ -398,6 +399,11 @@
     public abstract DisplayWindowPolicyController getDisplayWindowPolicyController(int displayId);
 
     /**
+     * Get DisplayPrimaries from SF for a particular display.
+     */
+    public abstract SurfaceControl.DisplayPrimaries getDisplayNativePrimaries(int displayId);
+
+    /**
      * Describes the requested power state of the display.
      *
      * This object is intended to describe the general characteristics of the
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index ca3e580..fa3c450 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -184,4 +184,9 @@
 
     // Query for DISPLAY_DECORATION support.
     DisplayDecorationSupport getDisplayDecorationSupport(int displayId);
+
+    // This method is to support behavior that was calling hidden APIs. The caller was requesting
+    // to set the layerStack after the display was created, which is not something we support in
+    // DMS. This should be deleted in V release.
+    void setDisplayIdToMirror(in IBinder token, int displayId);
 }
diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java
index 71cbd20..02ab8be 100644
--- a/core/java/android/hardware/display/VirtualDisplay.java
+++ b/core/java/android/hardware/display/VirtualDisplay.java
@@ -68,6 +68,13 @@
     }
 
     /**
+     * @hide
+     */
+    public IVirtualDisplayCallback getToken() {
+        return mToken;
+    }
+
+    /**
      * Sets the surface that backs the virtual display.
      * <p>
      * Detaching the surface that backs a virtual display has a similar effect to
diff --git a/core/java/android/hardware/input/VirtualDpad.java b/core/java/android/hardware/input/VirtualDpad.java
new file mode 100644
index 0000000..d7cda9e
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualDpad.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.companion.virtual.IVirtualDevice;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.KeyEvent;
+
+import java.io.Closeable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A virtual dpad representing a key input mechanism on a remote device.
+ *
+ * This registers an InputDevice that is interpreted like a physically-connected device and
+ * dispatches received events to it.
+ *
+ * @hide
+ */
+@SystemApi
+public class VirtualDpad implements Closeable {
+
+    private final Set<Integer> mSupportedKeyCodes =
+            Collections.unmodifiableSet(
+                    new HashSet<>(
+                            Arrays.asList(
+                                    KeyEvent.KEYCODE_DPAD_UP,
+                                    KeyEvent.KEYCODE_DPAD_DOWN,
+                                    KeyEvent.KEYCODE_DPAD_LEFT,
+                                    KeyEvent.KEYCODE_DPAD_RIGHT,
+                                    KeyEvent.KEYCODE_DPAD_CENTER)));
+    private final IVirtualDevice mVirtualDevice;
+    private final IBinder mToken;
+
+    /** @hide */
+    public VirtualDpad(IVirtualDevice virtualDevice, IBinder token) {
+        mVirtualDevice = virtualDevice;
+        mToken = token;
+    }
+
+    @Override
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public void close() {
+        try {
+            mVirtualDevice.unregisterInputDevice(mToken);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sends a key event to the system.
+     *
+     * Supported key codes are KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT,
+     * KEYCODE_DPAD_RIGHT and KEYCODE_DPAD_CENTER,
+     *
+     * @param event the event to send
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public void sendKeyEvent(@NonNull VirtualKeyEvent event) {
+        try {
+            if (!mSupportedKeyCodes.contains(event.getKeyCode())) {
+                throw new IllegalArgumentException(
+                        "Unsupported key code "
+                                + event.getKeyCode()
+                                + " sent to a VirtualDpad input device.");
+            }
+            mVirtualDevice.sendDpadKeyEvent(mToken, event);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/core/java/android/hardware/input/VirtualKeyEvent.java b/core/java/android/hardware/input/VirtualKeyEvent.java
index 80a49c9..dc30e55 100644
--- a/core/java/android/hardware/input/VirtualKeyEvent.java
+++ b/core/java/android/hardware/input/VirtualKeyEvent.java
@@ -158,6 +158,7 @@
             KeyEvent.KEYCODE_DPAD_UP,
             KeyEvent.KEYCODE_DPAD_LEFT,
             KeyEvent.KEYCODE_DPAD_RIGHT,
+            KeyEvent.KEYCODE_DPAD_CENTER,
             KeyEvent.KEYCODE_MOVE_END,
             KeyEvent.KEYCODE_MOVE_HOME,
             KeyEvent.KEYCODE_PAGE_DOWN,
diff --git a/core/java/android/hardware/input/VirtualKeyboard.java b/core/java/android/hardware/input/VirtualKeyboard.java
index ee9b659..901401fe 100644
--- a/core/java/android/hardware/input/VirtualKeyboard.java
+++ b/core/java/android/hardware/input/VirtualKeyboard.java
@@ -22,6 +22,7 @@
 import android.companion.virtual.IVirtualDevice;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.view.KeyEvent;
 
 import java.io.Closeable;
 
@@ -37,6 +38,7 @@
 @SystemApi
 public class VirtualKeyboard implements Closeable {
 
+    private final int mUnsupportedKeyCode = KeyEvent.KEYCODE_DPAD_CENTER;
     private final IVirtualDevice mVirtualDevice;
     private final IBinder mToken;
 
@@ -64,6 +66,11 @@
     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     public void sendKeyEvent(@NonNull VirtualKeyEvent event) {
         try {
+            if (mUnsupportedKeyCode == event.getKeyCode()) {
+                throw new IllegalArgumentException(
+                    "Unsupported key code " + event.getKeyCode()
+                        + " sent to a VirtualKeyboard input device.");
+            }
             mVirtualDevice.sendKeyEvent(mToken, event);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
diff --git a/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java b/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
index 5ce38e9..6f758de 100644
--- a/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
+++ b/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
@@ -27,6 +27,7 @@
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.CorrectionInfo;
 import android.view.inputmethod.DeleteGesture;
+import android.view.inputmethod.DeleteRangeGesture;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.HandwritingGesture;
@@ -36,6 +37,7 @@
 import android.view.inputmethod.JoinOrSplitGesture;
 import android.view.inputmethod.RemoveSpaceGesture;
 import android.view.inputmethod.SelectGesture;
+import android.view.inputmethod.SelectRangeGesture;
 import android.view.inputmethod.SurroundingText;
 import android.view.inputmethod.TextAttribute;
 
@@ -636,7 +638,9 @@
 
     /**
      * Invokes one of {@link IRemoteInputConnection#performHandwritingSelectGesture},
+     * {@link IRemoteInputConnection#performHandwritingSelectRangeGesture},
      * {@link IRemoteInputConnection#performHandwritingDeleteGesture},
+     * {@link IRemoteInputConnection#performHandwritingDeleteRangeGesture},
      * {@link IRemoteInputConnection#performHandwritingInsertGesture},
      * {@link IRemoteInputConnection#performHandwritingRemoveSpaceGesture},
      * {@link IRemoteInputConnection#performHandwritingJoinOrSplitGesture}.
@@ -655,12 +659,18 @@
             if (gesture instanceof SelectGesture) {
                 mConnection.performHandwritingSelectGesture(
                         createHeader(), (SelectGesture) gesture, resultReceiver);
+            } else if (gesture instanceof SelectRangeGesture) {
+                mConnection.performHandwritingSelectRangeGesture(
+                        createHeader(), (SelectRangeGesture) gesture, resultReceiver);
             } else if (gesture instanceof InsertGesture) {
                 mConnection.performHandwritingInsertGesture(
                         createHeader(), (InsertGesture) gesture, resultReceiver);
             } else if (gesture instanceof DeleteGesture) {
                 mConnection.performHandwritingDeleteGesture(
                         createHeader(), (DeleteGesture) gesture, resultReceiver);
+            } else if (gesture instanceof DeleteRangeGesture) {
+                mConnection.performHandwritingDeleteRangeGesture(
+                        createHeader(), (DeleteRangeGesture) gesture, resultReceiver);
             } else if (gesture instanceof RemoveSpaceGesture) {
                 mConnection.performHandwritingRemoveSpaceGesture(
                         createHeader(), (RemoveSpaceGesture) gesture, resultReceiver);
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 3a157d3..7436601 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1744,7 +1744,16 @@
     /**
      * Implement to return our standard {@link InputMethodImpl}.  Subclasses
      * can override to provide their own customized version.
+     *
+     * @deprecated IME developers don't need to override this method to get callbacks information.
+     * Most methods in {@link InputMethodImpl} have corresponding callbacks.
+     * Use {@link InputMethodService#onBindInput()}, {@link InputMethodService#onUnbindInput()},
+     * {@link InputMethodService#onWindowShown()}, {@link InputMethodService#onWindowHidden()}, etc.
+     *
+     * <p>Starting from Android U and later, override this method won't guarantee that IME works
+     * as previous platform behavior.</p>
      */
+    @Deprecated
     @Override
     public AbstractInputMethodImpl onCreateInputMethodInterface() {
         return new InputMethodImpl();
@@ -1753,7 +1762,15 @@
     /**
      * Implement to return our standard {@link InputMethodSessionImpl}.  Subclasses
      * can override to provide their own customized version.
+     *
+     * @deprecated IME developers don't need to override this method to get callbacks information.
+     * Most methods in {@link InputMethodSessionImpl} have corresponding callbacks.
+     * Use {@link InputMethodService#onFinishInput()},
+     * {@link InputMethodService#onDisplayCompletions(CompletionInfo[])},
+     * {@link InputMethodService#onUpdateExtractedText(int, ExtractedText)},
+     * {@link InputMethodService#onUpdateSelection(int, int, int, int, int, int)} instead.
      */
+    @Deprecated
     @Override
     public AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface() {
         return new InputMethodSessionImpl();
diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java
index 3979c6c..10ce3bf 100644
--- a/core/java/android/net/Ikev2VpnProfile.java
+++ b/core/java/android/net/Ikev2VpnProfile.java
@@ -483,9 +483,6 @@
         final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */,
                 mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation,
                 mIkeTunConnParams);
-
-        profile.server = getServerAddr();
-        profile.ipsecIdentifier = getUserIdentity();
         profile.proxy = mProxyInfo;
         profile.isBypassable = mIsBypassable;
         profile.isMetered = mIsMetered;
@@ -499,6 +496,8 @@
         }
 
         profile.type = mType;
+        profile.server = getServerAddr();
+        profile.ipsecIdentifier = getUserIdentity();
         profile.setAllowedAlgorithms(mAllowedAlgorithms);
         switch (mType) {
             case TYPE_IKEV2_IPSEC_USER_PASS:
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 88649cb..933769a 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -76,7 +76,7 @@
     String getUserAccount(int userId);
     void setUserAccount(int userId, String accountName);
     long getUserCreationTime(int userId);
-    boolean isUserSwitcherEnabled(int mUserId);
+    boolean isUserSwitcherEnabled(boolean showEvenIfNotActionable, int mUserId);
     boolean isRestricted(int userId);
     boolean canHaveRestrictedProfile(int userId);
     int getUserSerialNumber(int userId);
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 113a640..a6b62b0 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -441,7 +441,7 @@
      * different penalties for different detected actions.
      */
     public static final class ThreadPolicy {
-        /** The default, lax policy which doesn't catch anything. */
+        /** The lax policy which doesn't catch anything. */
         public static final ThreadPolicy LAX = new ThreadPolicy(0, null, null);
 
         @UnsupportedAppUsage
@@ -728,7 +728,7 @@
      * <p>The policy is enabled by {@link #setVmPolicy}.
      */
     public static final class VmPolicy {
-        /** The default, lax policy which doesn't catch anything. */
+        /** The lax policy which doesn't catch anything. */
         public static final VmPolicy LAX = new VmPolicy(0, EMPTY_CLASS_LIMIT_MAP, null, null);
 
         @UnsupportedAppUsage
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index ecea054..2b75a23 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -377,7 +377,7 @@
                 }
                 long currentNanos = elapsedRealtimeNanos();
                 long deltaMs = (currentNanos - time.getElapsedRealtimeNanos()) / 1000000L;
-                return time.getTime() + deltaMs;
+                return time.getUnixEpochTimeMillis() + deltaMs;
             }
         };
     }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index f6aaee8..5c809a1 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2843,7 +2843,6 @@
     /**
      * @hide
      */
-    @TestApi
     public static boolean isUsersOnSecondaryDisplaysEnabled() {
         return SystemProperties.getBoolean("fw.users_on_secondary_displays",
                 Resources.getSystem()
@@ -2853,10 +2852,12 @@
     /**
      * Returns whether the device allows users to run (and launch activities) on secondary displays.
      *
-     * @return {@code false} for most devices, except automotive vehicles with passenger displays.
+     * @return {@code false} for most devices, except on automotive builds for vehiches with
+     * passenger displays.
      *
      * @hide
      */
+    @TestApi
     public boolean isUsersOnSecondaryDisplaysSupported() {
         return isUsersOnSecondaryDisplaysEnabled();
     }
@@ -5264,36 +5265,10 @@
     public boolean isUserSwitcherEnabled(boolean showEvenIfNotActionable) {
 
         try {
-            if (!mService.isUserSwitcherEnabled(mUserId)) {
-                return false;
-            }
+            return mService.isUserSwitcherEnabled(showEvenIfNotActionable, mUserId);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
-
-        // The feature is enabled. But is it worth showing?
-        return showEvenIfNotActionable
-                || areThereUsersToWhichToSwitch() // There are switchable users.
-                || !hasUserRestrictionForUser(DISALLOW_ADD_USER, mUserId); // New users can be added
-    }
-
-    /** Returns whether there are any users (other than the current user) to which to switch. */
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.MANAGE_USERS,
-            android.Manifest.permission.CREATE_USERS
-    })
-    private boolean areThereUsersToWhichToSwitch() {
-        final List<UserInfo> users = getAliveUsers();
-        if (users == null) {
-            return false;
-        }
-        int switchableUserCount = 0;
-        for (UserInfo user : users) {
-            if (user.supportsSwitchToByUser()) {
-                ++switchableUserCount;
-            }
-        }
-        return switchableUserCount > 1;
     }
 
     /**
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 08de87e..c1606e8 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -2549,7 +2549,7 @@
      * called on first creation of a new file on external storage, and whenever the
      * media type of the file is updated later.
      *
-     * This API doesn't require any special permissions, though typical implementations
+     * This API requires MANAGE_EXTERNAL_STORAGE permission and typical implementations
      * will require being called from an SELinux domain that allows setting file attributes
      * related to quota (eg the GID or project ID).
      *
@@ -2568,11 +2568,16 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_EXTERNAL_STORAGE)
     public void updateExternalStorageFileQuotaType(@NonNull File path,
             @QuotaType int quotaType) throws IOException {
         long projectId;
         final String filePath = path.getCanonicalPath();
-        final StorageVolume volume = getStorageVolume(path);
+        // MANAGE_EXTERNAL_STORAGE permission is required as FLAG_INCLUDE_SHARED_PROFILE is being
+        // set while querying getVolumeList.
+        final StorageVolume[] availableVolumes = getVolumeList(mContext.getUserId(),
+                FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE | FLAG_INCLUDE_SHARED_PROFILE);
+        final StorageVolume volume = getStorageVolume(availableVolumes, path);
         if (volume == null) {
             Log.w(TAG, "Failed to update quota type for " + filePath);
             return;
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index fe46c9e..345486e 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -203,6 +203,15 @@
     @SystemApi
     public static final String NAMESPACE_TETHERING = "tethering";
 
+
+    /**
+     * Namespace for Nearby module.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_NEARBY = "nearby";
+
     /**
      * Namespace for content capture feature used by on-device machine intelligence
      * to provide suggestions in a privacy-safe manner.
@@ -776,6 +785,14 @@
     public static final String NAMESPACE_WEAR = "wear";
 
     /**
+     * Namespace for features relating to MBA transparency metadata.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_TRANSPARENCY_METADATA = "transparency_metadata";
+
+    /**
      * Namespace for the input method manager platform features.
      *
      * @hide
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a99d0f0..cab6acb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7462,6 +7462,13 @@
                 "trust_agents_initialized";
 
         /**
+         * Set to 1 by the system after the list of known trust agents have been initialized.
+         * @hide
+         */
+        public static final String KNOWN_TRUST_AGENTS_INITIALIZED =
+                "known_trust_agents_initialized";
+
+        /**
          * The Logging ID (a unique 64-bit value) as a hex string.
          * Used as a pseudonymous identifier for logging.
          * @deprecated This identifier is poorly initialized and has
@@ -9825,6 +9832,7 @@
          * Whether or not virtual sensors are enabled.
          * @hide
          */
+        @TestApi
         @Readable
         public static final String BIOMETRIC_VIRTUAL_ENABLED = "biometric_virtual_enabled";
 
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 154fcab..913efbd 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4820,5 +4820,12 @@
          * @hide
          */
         public static final String COLUMN_USAGE_SETTING = "usage_setting";
+
+        /**
+         * TelephonyProvider column name for user handle associated with this sim.
+         *
+         * @hide
+         */
+        public static final String COLUMN_USER_HANDLE = "user_handle";
     }
 }
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index f900558..8efc5eb 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -68,6 +68,8 @@
 
     public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200;
     public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202;
+    public static final int KM_TAG_RSA_OAEP_MGF_DIGEST = Tag.RSA_OAEP_MGF_DIGEST;
+            // KM_ENUM_REP | 203;
 
     public static final int KM_TAG_ACTIVE_DATETIME = Tag.ACTIVE_DATETIME; // KM_DATE | 400;
     public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME =
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index be8c140..e4c26e0 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -93,6 +93,7 @@
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.window.ClientWindowFrames;
+import android.window.ScreenCapture;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.HandlerCaller;
@@ -1989,9 +1990,9 @@
                 cleanUpScreenshotSurfaceControl();
             }
 
-            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                    SurfaceControl.captureLayers(
-                            new SurfaceControl.LayerCaptureArgs.Builder(mSurfaceControl)
+            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                    ScreenCapture.captureLayers(
+                            new ScreenCapture.LayerCaptureArgs.Builder(mSurfaceControl)
                                     // Needed because SurfaceFlinger#validateScreenshotPermissions
                                     // uses this parameter to check whether a caller only attempts
                                     // to screenshot itself when call doesn't come from the system.
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 537dffc..d48d566 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -170,7 +170,7 @@
      * mean using 12-hour in some locales and, in this case, is duplicated as the 'a' field.
      */
     @ChangeId
-    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT)
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
     static final long DISALLOW_DUPLICATE_FIELD_IN_SKELETON = 170233598L;
 
     /**
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 20f01ae..cb8f0af 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -96,13 +96,6 @@
     /** @hide */
     public static final String SETTINGS_AUTO_TEXT_WRAPPING = "settings_auto_text_wrapping";
 
-
-    /** Support Clear Calling feature.
-     *  @hide
-     */
-    public static final String SETTINGS_ENABLE_CLEAR_CALLING = "settings_enable_clear_calling";
-
-
     /** Flag to enable / disable the Simple Cursor accessibility feature in
      *  Settings.
      * @hide
@@ -122,6 +115,11 @@
      */
     public static final String SETTINGS_ENABLE_SPA = "settings_enable_spa";
 
+    /** Flag to enable/disable adb log metrics
+     *  @hide
+     */
+    public static final String SETTINGS_ADB_METRICS_WRITER = "settings_adb_metrics_writer";
+
     private static final Map<String, String> DEFAULT_FLAGS;
 
     static {
@@ -151,10 +149,10 @@
         DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true");
         DEFAULT_FLAGS.put(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE, "true");
         DEFAULT_FLAGS.put(SETTINGS_AUTO_TEXT_WRAPPING, "false");
-        DEFAULT_FLAGS.put(SETTINGS_ENABLE_CLEAR_CALLING, "false");
         DEFAULT_FLAGS.put(SETTINGS_ACCESSIBILITY_SIMPLE_CURSOR, "false");
         DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_UI, "false");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA, "false");
+        DEFAULT_FLAGS.put(SETTINGS_ADB_METRICS_WRITER, "false");
     }
 
     private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index f9bb880..57ba7e9 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -653,7 +653,7 @@
                 break;
 
             case MotionEvent.ACTION_MOVE:
-                if ((mCurrentDownEvent == null) || mInLongPress || mInContextClick) {
+                if (mInLongPress || mInContextClick) {
                     break;
                 }
 
@@ -736,9 +736,6 @@
                 break;
 
             case MotionEvent.ACTION_UP:
-                if (mCurrentDownEvent == null) {
-                    break;
-                }
                 mStillDown = false;
                 MotionEvent currentUpEvent = MotionEvent.obtain(ev);
                 if (mIsDoubleTapping) {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 229de31..067946e 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -67,6 +67,7 @@
 import android.view.displayhash.DisplayHash;
 import android.view.displayhash.VerifiedDisplayHash;
 import android.window.ITaskFpsCallback;
+import android.window.ScreenCapture;
 
 /**
  * System private interface to the window manager.
@@ -114,6 +115,7 @@
     @UnsupportedAppUsage
     int getInitialDisplayDensity(int displayId);
     int getBaseDisplayDensity(int displayId);
+    int getDisplayIdByUniqueId(String uniqueId);
     void setForcedDisplayDensityForUser(int displayId, int density, int userId);
     void clearForcedDisplayDensityForUser(int displayId, int userId);
     void setForcedDisplayScalingMode(int displayId, int mode); // 0 = auto, 1 = disable
@@ -967,4 +969,11 @@
      * treatment.
      */
     boolean isLetterboxBackgroundMultiColored();
+
+    /**
+     * 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.
+     */
+    oneway void captureDisplay(int displayId, in @nullable ScreenCapture.CaptureArgs captureArgs,
+            in ScreenCapture.ScreenCaptureListener listener);
 }
diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java
index a5ac948..d4875d4 100644
--- a/core/java/android/view/ImeFocusController.java
+++ b/core/java/android/view/ImeFocusController.java
@@ -43,8 +43,21 @@
 
     private final ViewRootImpl mViewRootImpl;
     private boolean mHasImeFocus = false;
+
+    /**
+     * This is the view that should currently be served by an input method,
+     * regardless of the state of setting that up.
+     * @see InputMethodManagerDelegate#getLockObject()
+     */
     private View mServedView;
+
+    /**
+     * This is the next view that will be served by the input method, when
+     * we get around to updating things.
+     * @see InputMethodManagerDelegate#getLockObject()
+     */
     private View mNextServedView;
+
     private InputMethodManagerDelegate mDelegate;
 
     @UiThread
@@ -123,45 +136,52 @@
 
         boolean forceFocus = false;
         final InputMethodManagerDelegate immDelegate = getImmDelegate();
-        if (immDelegate.isRestartOnNextWindowFocus(true /* reset */)) {
-            if (DEBUG) Log.v(TAG, "Restarting due to isRestartOnNextWindowFocus as true");
-            forceFocus = true;
+        synchronized (immDelegate.getLockObject()) {
+            // Update mNextServedView when focusedView changed.
+            onViewFocusChanged(viewForWindowFocus, true);
+
+            // Starting new input when the next focused view is same as served view but the
+            // currently active connection (if any) is not associated with it.
+            final boolean nextFocusIsServedView = mServedView == viewForWindowFocus;
+
+            if (nextFocusIsServedView && !immDelegate.hasActiveConnection(viewForWindowFocus)) {
+                forceFocus = true;
+            }
         }
 
-        // Update mNextServedView when focusedView changed.
-        onViewFocusChanged(viewForWindowFocus, true);
-
-        // Starting new input when the next focused view is same as served view but the currently
-        // active connection (if any) is not associated with it.
-        final boolean nextFocusIsServedView = mServedView == viewForWindowFocus;
-        if (nextFocusIsServedView && !immDelegate.hasActiveConnection(viewForWindowFocus)) {
-            forceFocus = true;
-        }
-
-        immDelegate.startInputAsyncOnWindowFocusGain(viewForWindowFocus,
+        immDelegate.startInputOnWindowFocusGain(viewForWindowFocus,
                 windowAttribute.softInputMode, windowAttribute.flags, forceFocus);
     }
 
+    /**
+     * @see InputMethodManager#checkFocus()
+     */
     public boolean checkFocus(boolean forceNewFocus, boolean startInput) {
         final InputMethodManagerDelegate immDelegate = getImmDelegate();
-        if (!immDelegate.isCurrentRootView(mViewRootImpl)
-                || (mServedView == mNextServedView && !forceNewFocus)) {
-            return false;
+        synchronized (immDelegate.getLockObject()) {
+            if (!immDelegate.isCurrentRootView(mViewRootImpl)) {
+                return false;
+            }
+            if (mServedView == mNextServedView && !forceNewFocus) {
+                return false;
+            }
+            if (DEBUG) {
+                Log.v(TAG, "checkFocus: view=" + mServedView
+                        + " next=" + mNextServedView
+                        + " force=" + forceNewFocus
+                        + " package="
+                        + (mServedView != null ? mServedView.getContext().getPackageName()
+                        : "<none>"));
+            }
+            // Close the connection when no next served view coming.
+            if (mNextServedView == null) {
+                immDelegate.finishInput();
+                immDelegate.closeCurrentIme();
+                return false;
+            }
+            mServedView = mNextServedView;
+            immDelegate.finishComposingText();
         }
-        if (DEBUG) Log.v(TAG, "checkFocus: view=" + mServedView
-                + " next=" + mNextServedView
-                + " force=" + forceNewFocus
-                + " package="
-                + (mServedView != null ? mServedView.getContext().getPackageName() : "<none>"));
-
-        // Close the connection when no next served view coming.
-        if (mNextServedView == null) {
-            immDelegate.finishInput();
-            immDelegate.closeCurrentIme();
-            return false;
-        }
-        mServedView = mNextServedView;
-        immDelegate.finishComposingText();
 
         if (startInput) {
             immDelegate.startInput(StartInputReason.CHECK_FOCUS, null /* focusedView */,
@@ -175,51 +195,61 @@
         if (view == null || view.isTemporarilyDetached()) {
             return;
         }
-        if (!getImmDelegate().isCurrentRootView(view.getViewRootImpl())) {
-            return;
-        }
-        if (!view.hasImeFocus() || !view.hasWindowFocus()) {
-            return;
-        }
-        if (DEBUG) Log.d(TAG, "onViewFocusChanged, view=" + InputMethodDebug.dumpViewInfo(view)
-                + ", mServedView=" + InputMethodDebug.dumpViewInfo(mServedView));
+        final InputMethodManagerDelegate immDelegate = getImmDelegate();
+        synchronized (immDelegate.getLockObject()) {
+            if (!immDelegate.isCurrentRootView(view.getViewRootImpl())) {
+                return;
+            }
+            if (!view.hasImeFocus() || !view.hasWindowFocus()) {
+                return;
+            }
+            if (DEBUG) {
+                Log.d(TAG, "onViewFocusChanged, view=" + InputMethodDebug.dumpViewInfo(view)
+                        + ", mServedView=" + InputMethodDebug.dumpViewInfo(mServedView));
+            }
 
-        // We don't need to track the next served view when the view lost focus here because:
-        // 1) The current view focus may be cleared temporary when in touch mode, closing input
-        //    at this moment isn't the right way.
-        // 2) We only care about the served view change when it focused, since changing input
-        //    connection when the focus target changed is reasonable.
-        // 3) Setting the next served view as null when no more served view should be handled in
-        //    other special events (e.g. view detached from window or the window dismissed).
-        if (hasFocus) {
-            mNextServedView = view;
+            // We don't need to track the next served view when the view lost focus here because:
+            // 1) The current view focus may be cleared temporary when in touch mode, closing input
+            //    at this moment isn't the right way.
+            // 2) We only care about the served view change when it focused, since changing input
+            //    connection when the focus target changed is reasonable.
+            // 3) Setting the next served view as null when no more served view should be handled in
+            //    other special events (e.g. view detached from window or the window dismissed).
+            if (hasFocus) {
+                mNextServedView = view;
+            }
         }
         mViewRootImpl.dispatchCheckFocus();
     }
 
     @UiThread
     void onViewDetachedFromWindow(View view) {
-        if (!getImmDelegate().isCurrentRootView(view.getViewRootImpl())) {
-            return;
-        }
-        if (mNextServedView == view) {
-            mNextServedView = null;
-        }
-        if (mServedView == view) {
-            mViewRootImpl.dispatchCheckFocus();
+        final InputMethodManagerDelegate immDelegate = getImmDelegate();
+        synchronized (immDelegate.getLockObject()) {
+            if (!immDelegate.isCurrentRootView(view.getViewRootImpl())) {
+                return;
+            }
+            if (mNextServedView == view) {
+                mNextServedView = null;
+            }
+            if (mServedView == view) {
+                mViewRootImpl.dispatchCheckFocus();
+            }
         }
     }
 
     @UiThread
     void onWindowDismissed() {
         final InputMethodManagerDelegate immDelegate = getImmDelegate();
-        if (!immDelegate.isCurrentRootView(mViewRootImpl)) {
-            return;
+        synchronized (immDelegate.getLockObject()) {
+            if (!immDelegate.isCurrentRootView(mViewRootImpl)) {
+                return;
+            }
+            if (mServedView != null) {
+                immDelegate.finishInput();
+            }
+            immDelegate.setCurrentRootView(null);
         }
-        if (mServedView != null) {
-            immDelegate.finishInput();
-        }
-        immDelegate.setCurrentRootView(null);
         mHasImeFocus = false;
     }
 
@@ -270,10 +300,22 @@
      * @hide
      */
     public interface InputMethodManagerDelegate {
+        /**
+         * Starts the input connection.
+         * Note that this method must not hold the {@link InputMethodManager} lock with
+         * {@link InputMethodManagerDelegate#getLockObject()} while {@link InputMethodManager}
+         * calling into app-code in different threads.
+         */
         boolean startInput(@StartInputReason int startInputReason, View focusedView,
                 @StartInputFlags int startInputFlags,
                 @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, int windowFlags);
-        void startInputAsyncOnWindowFocusGain(View rootView,
+        /**
+         * Starts the input connection when gaining the window focus.
+         * Note that this method must not hold the {@link InputMethodManager} lock with
+         * {@link InputMethodManagerDelegate#getLockObject()} while {@link InputMethodManager}
+         * calling into app-code in different threads.
+         */
+        void startInputOnWindowFocusGain(View rootView,
                 @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, int windowFlags,
                 boolean forceNewFocus);
         void finishInput();
@@ -282,24 +324,53 @@
         void finishComposingText();
         void setCurrentRootView(ViewRootImpl rootView);
         boolean isCurrentRootView(ViewRootImpl rootView);
-        boolean isRestartOnNextWindowFocus(boolean reset);
         boolean hasActiveConnection(View view);
+
+        /**
+         * Returns the {@code InputMethodManager#mH} lock object.
+         * Used for {@link ImeFocusController} to guard the served view being accessed by
+         * {@link InputMethodManager} in different threads.
+         */
+        Object getLockObject();
     }
 
-    public View getServedView() {
+    /**
+     * Returns The current IME served view for {@link InputMethodManager}.
+     * Used to start input connection or check the caller's validity when calling
+     * {@link InputMethodManager} APIs.
+     * Note that this method requires to be called inside {@code InputMethodManager#mH} lock for
+     * data consistency.
+     */
+    public View getServedViewLocked() {
         return mServedView;
     }
 
-    public View getNextServedView() {
+    /**
+     * Returns The next incoming IME served view for {@link InputMethodManager}.
+     * Note that this method requires to be called inside {@code InputMethodManager#mH} lock for
+     * data consistency.
+     */
+    public View getNextServedViewLocked() {
         return mNextServedView;
     }
 
-    public void setServedView(View view) {
-        mServedView = view;
-    }
-
-    public void setNextServedView(View view) {
-        mNextServedView = view;
+    /**
+     * Clears the served & the next served view when the controller triggers
+     * {@link InputMethodManagerDelegate#finishInput()} or
+     * {@link InputMethodManagerDelegate#finishInputAndReportToIme()}.
+     * Note that this method requires to be called inside {@code InputMethodManager#mH} lock for
+     * data consistency.
+     *
+     * @return The {@code mServedView} that has cleared, or {@code null} means nothing to clear.
+     */
+    public View clearServedViewsLocked() {
+        View clearedView = null;
+        mNextServedView = null;
+        if (mServedView != null) {
+            clearedView = mServedView;
+            mServedView = null;
+        }
+        return clearedView;
     }
 
     /**
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 6c238e5..9789b56 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -872,13 +872,33 @@
     public static final int KEYCODE_KEYBOARD_BACKLIGHT_UP = 306;
     /** Key code constant: Keyboard backlight toggle */
     public static final int KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE = 307;
+    /**
+     * Key code constant: The primary button on the barrel of a stylus.
+     * This is usually the button closest to the tip of the stylus.
+     */
+    public static final int KEYCODE_STYLUS_BUTTON_PRIMARY = 308;
+    /**
+     * Key code constant: The secondary button on the barrel of a stylus.
+     * This is usually the second button from the tip of the stylus.
+     */
+    public static final int KEYCODE_STYLUS_BUTTON_SECONDARY = 309;
+    /**
+     * Key code constant: The tertiary button on the barrel of a stylus.
+     * This is usually the third button from the tip of the stylus.
+     */
+    public static final int KEYCODE_STYLUS_BUTTON_TERTIARY = 310;
+    /**
+     * Key code constant: A button on the tail end of a stylus.
+     * The use of this button does not usually correspond to the function of an eraser.
+     */
+    public static final int KEYCODE_STYLUS_BUTTON_TAIL = 311;
 
    /**
      * Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.
      * @hide
      */
     @TestApi
-    public static final int LAST_KEYCODE = KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE;
+    public static final int LAST_KEYCODE = KEYCODE_STYLUS_BUTTON_TAIL;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index a0a1cb1..9322bf6 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -22,6 +22,7 @@
 import static android.graphics.Matrix.MSKEW_Y;
 import static android.graphics.Matrix.MTRANS_X;
 import static android.graphics.Matrix.MTRANS_Y;
+import static android.view.Display.INVALID_DISPLAY;
 import static android.view.SurfaceControlProto.HASH_CODE;
 import static android.view.SurfaceControlProto.LAYER_ID;
 import static android.view.SurfaceControlProto.NAME;
@@ -35,7 +36,7 @@
 import android.annotation.Size;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.graphics.Bitmap;
+import android.content.Context;
 import android.graphics.ColorSpace;
 import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
@@ -48,15 +49,23 @@
 import android.hardware.HardwareBuffer;
 import android.hardware.SyncFence;
 import android.hardware.display.DeviceProductInfo;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.display.DisplayedContentSample;
 import android.hardware.display.DisplayedContentSamplingAttributes;
+import android.hardware.display.IDisplayManager;
+import android.hardware.display.IVirtualDisplayCallback;
+import android.hardware.display.VirtualDisplay;
 import android.hardware.graphics.common.DisplayDecorationSupport;
+import android.media.projection.MediaProjectionGlobal;
 import android.opengl.EGLDisplay;
 import android.opengl.EGLSync;
 import android.os.Build;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseIntArray;
@@ -80,9 +89,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Objects;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 
 /**
@@ -107,10 +114,7 @@
     private static native void nativeRelease(long nativeObject);
     private static native void nativeDisconnect(long nativeObject);
     private static native void nativeUpdateDefaultBufferSize(long nativeObject, int width, int height);
-    private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs,
-            ScreenCaptureListener captureListener);
-    private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs,
-            ScreenCaptureListener captureListener);
+
     private static native long nativeMirrorSurface(long mirrorOfObject);
     private static native long nativeCreateTransaction();
     private static native long nativeGetNativeTransactionFinalizer();
@@ -172,8 +176,6 @@
 
     private static native long[] nativeGetPhysicalDisplayIds();
     private static native IBinder nativeGetPhysicalDisplayToken(long physicalDisplayId);
-    private static native IBinder nativeCreateDisplay(String name, boolean secure);
-    private static native void nativeDestroyDisplay(IBinder displayToken);
     private static native void nativeSetDisplaySurface(long transactionObj,
             IBinder displayToken, long nativeSurfaceObject);
     private static native void nativeSetDisplayLayerStack(long transactionObj,
@@ -522,7 +524,7 @@
      * be copied. In particular, screenshots and secondary, non-secure displays will render black
      * content instead of the surface content.
      *
-     * @see #createDisplay(String, boolean)
+     * @see com.android.server.display.DisplayControl#createDisplay(String, boolean)
      * @hide
      */
     public static final int SECURE = 0x00000080;
@@ -782,412 +784,6 @@
     public static final int METADATA_GAME_MODE = 8;
 
     /**
-     * A wrapper around HardwareBuffer that contains extra information about how to
-     * interpret the screenshot HardwareBuffer.
-     *
-     * @hide
-     */
-    public static class ScreenshotHardwareBuffer {
-        private final HardwareBuffer mHardwareBuffer;
-        private final ColorSpace mColorSpace;
-        private final boolean mContainsSecureLayers;
-        private final boolean mContainsHdrLayers;
-
-        public ScreenshotHardwareBuffer(HardwareBuffer hardwareBuffer, ColorSpace colorSpace,
-                boolean containsSecureLayers, boolean containsHdrLayers) {
-            mHardwareBuffer = hardwareBuffer;
-            mColorSpace = colorSpace;
-            mContainsSecureLayers = containsSecureLayers;
-            mContainsHdrLayers = containsHdrLayers;
-        }
-
-       /**
-        * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object.
-        * @param hardwareBuffer The existing HardwareBuffer object
-        * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
-        * @param containsSecureLayers Indicates whether this graphic buffer contains captured
-        *                             contents of secure layers, in which case the screenshot
-        *                             should not be persisted.
-        * @param containsHdrLayers Indicates whether this graphic buffer contains HDR content.
-        */
-        private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
-                int namedColorSpace, boolean containsSecureLayers, boolean containsHdrLayers) {
-            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
-            return new ScreenshotHardwareBuffer(
-                    hardwareBuffer, colorSpace, containsSecureLayers, containsHdrLayers);
-        }
-
-        public ColorSpace getColorSpace() {
-            return mColorSpace;
-        }
-
-        public HardwareBuffer getHardwareBuffer() {
-            return mHardwareBuffer;
-        }
-
-        public boolean containsSecureLayers() {
-            return mContainsSecureLayers;
-        }
-        /**
-         * Returns whether the screenshot contains at least one HDR layer.
-         * This information may be useful for informing the display whether this screenshot
-         * is allowed to be dimmed to SDR white.
-         */
-        public boolean containsHdrLayers() {
-            return mContainsHdrLayers;
-        }
-
-        /**
-         * Copy content of ScreenshotHardwareBuffer into a hardware bitmap and return it.
-         * Note: If you want to modify the Bitmap in software, you will need to copy the Bitmap
-         * into
-         * a software Bitmap using {@link Bitmap#copy(Bitmap.Config, boolean)}
-         *
-         * CAVEAT: This can be extremely slow; avoid use unless absolutely necessary; prefer to
-         * directly
-         * use the {@link HardwareBuffer} directly.
-         *
-         * @return Bitmap generated from the {@link HardwareBuffer}
-         */
-        public Bitmap asBitmap() {
-            if (mHardwareBuffer == null) {
-                Log.w(TAG, "Failed to take screenshot. Null screenshot object");
-                return null;
-            }
-            return Bitmap.wrapHardwareBuffer(mHardwareBuffer, mColorSpace);
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public interface ScreenCaptureListener {
-        /**
-         * The callback invoked when the screen capture is complete.
-         * @param hardwareBuffer Data containing info about the screen capture.
-         */
-        void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer);
-    }
-
-    private static class SyncScreenCaptureListener implements ScreenCaptureListener {
-        private static final int SCREENSHOT_WAIT_TIME_S = 1;
-        private ScreenshotHardwareBuffer mScreenshotHardwareBuffer;
-        private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
-
-        @Override
-        public void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer) {
-            mScreenshotHardwareBuffer = hardwareBuffer;
-            mCountDownLatch.countDown();
-        }
-
-        private ScreenshotHardwareBuffer waitForScreenshot() {
-            try {
-                mCountDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to wait for screen capture result", e);
-            }
-
-            return mScreenshotHardwareBuffer;
-        }
-    }
-
-    /**
-     * A common arguments class used for various screenshot requests. This contains arguments that
-     * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs}
-     * @hide
-     */
-    private abstract static class CaptureArgs {
-        private final int mPixelFormat;
-        private final Rect mSourceCrop = new Rect();
-        private final float mFrameScaleX;
-        private final float mFrameScaleY;
-        private final boolean mCaptureSecureLayers;
-        private final boolean mAllowProtected;
-        private final long mUid;
-        private final boolean mGrayscale;
-
-        private CaptureArgs(Builder<? extends Builder<?>> builder) {
-            mPixelFormat = builder.mPixelFormat;
-            mSourceCrop.set(builder.mSourceCrop);
-            mFrameScaleX = builder.mFrameScaleX;
-            mFrameScaleY = builder.mFrameScaleY;
-            mCaptureSecureLayers = builder.mCaptureSecureLayers;
-            mAllowProtected = builder.mAllowProtected;
-            mUid = builder.mUid;
-            mGrayscale = builder.mGrayscale;
-        }
-
-        /**
-         * The Builder class used to construct {@link CaptureArgs}
-         *
-         * @param <T> A builder that extends {@link Builder}
-         */
-        abstract static class Builder<T extends Builder<T>> {
-            private int mPixelFormat = PixelFormat.RGBA_8888;
-            private final Rect mSourceCrop = new Rect();
-            private float mFrameScaleX = 1;
-            private float mFrameScaleY = 1;
-            private boolean mCaptureSecureLayers;
-            private boolean mAllowProtected;
-            private long mUid = -1;
-            private boolean mGrayscale;
-
-            /**
-             * The desired pixel format of the returned buffer.
-             */
-            public T setPixelFormat(int pixelFormat) {
-                mPixelFormat = pixelFormat;
-                return getThis();
-            }
-
-            /**
-             * The portion of the screen to capture into the buffer. Caller may pass  in
-             * 'new Rect()' or null if no cropping is desired.
-             */
-            public T setSourceCrop(@Nullable Rect sourceCrop) {
-                if (sourceCrop == null) {
-                    mSourceCrop.setEmpty();
-                } else {
-                    mSourceCrop.set(sourceCrop);
-                }
-                return getThis();
-            }
-
-            /**
-             * The desired scale of the returned buffer. The raw screen will be scaled up/down.
-             */
-            public T setFrameScale(float frameScale) {
-                mFrameScaleX = frameScale;
-                mFrameScaleY = frameScale;
-                return getThis();
-            }
-
-            /**
-             * The desired scale of the returned buffer, allowing separate values for x and y scale.
-             * The raw screen will be scaled up/down.
-             */
-            public T setFrameScale(float frameScaleX, float frameScaleY) {
-                mFrameScaleX = frameScaleX;
-                mFrameScaleY = frameScaleY;
-                return getThis();
-            }
-
-            /**
-             * Whether to allow the screenshot of secure layers. Warning: This should only be done
-             * if the content will be placed in a secure SurfaceControl.
-             *
-             * @see ScreenshotHardwareBuffer#containsSecureLayers()
-             */
-            public T setCaptureSecureLayers(boolean captureSecureLayers) {
-                mCaptureSecureLayers = captureSecureLayers;
-                return getThis();
-            }
-
-            /**
-             * Whether to allow the screenshot of protected (DRM) content. Warning: The screenshot
-             * cannot be read in unprotected space.
-             *
-             * @see HardwareBuffer#USAGE_PROTECTED_CONTENT
-             */
-            public T setAllowProtected(boolean allowProtected) {
-                mAllowProtected = allowProtected;
-                return getThis();
-            }
-
-            /**
-             * Set the uid of the content that should be screenshot. The code will skip any surfaces
-             * that don't belong to the specified uid.
-             */
-            public T setUid(long uid) {
-                mUid = uid;
-                return getThis();
-            }
-
-            /**
-             * Set whether the screenshot should use grayscale or not.
-             */
-            public T setGrayscale(boolean grayscale) {
-                mGrayscale = grayscale;
-                return getThis();
-            }
-
-            /**
-             * Each sub class should return itself to allow the builder to chain properly
-             */
-            abstract T getThis();
-        }
-    }
-
-    /**
-     * The arguments class used to make display capture requests.
-     *
-     * @see #nativeCaptureDisplay(DisplayCaptureArgs, ScreenCaptureListener)
-     * @hide
-     */
-    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.
-     *
-     * @see #nativeCaptureLayers(LayerCaptureArgs, ScreenCaptureListener)
-     * @hide
-     */
-    public static class LayerCaptureArgs extends CaptureArgs {
-        private final long mNativeLayer;
-        private final long[] mNativeExcludeLayers;
-        private final boolean mChildrenOnly;
-
-        private LayerCaptureArgs(Builder builder) {
-            super(builder);
-            mChildrenOnly = builder.mChildrenOnly;
-            mNativeLayer = builder.mLayer.mNativeObject;
-            if (builder.mExcludeLayers != null) {
-                mNativeExcludeLayers = new long[builder.mExcludeLayers.length];
-                for (int i = 0; i < builder.mExcludeLayers.length; i++) {
-                    mNativeExcludeLayers[i] = builder.mExcludeLayers[i].mNativeObject;
-                }
-            } else {
-                mNativeExcludeLayers = null;
-            }
-        }
-
-        /**
-         * The Builder class used to construct {@link LayerCaptureArgs}
-         */
-        public static class Builder extends CaptureArgs.Builder<Builder> {
-            private SurfaceControl mLayer;
-            private SurfaceControl[] mExcludeLayers;
-            private boolean mChildrenOnly = true;
-
-            /**
-             * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder
-             * remains valid.
-             */
-            public LayerCaptureArgs build() {
-                if (mLayer == null) {
-                    throw new IllegalStateException(
-                            "Can't take screenshot with null layer");
-                }
-                return new LayerCaptureArgs(this);
-            }
-
-            public Builder(SurfaceControl layer) {
-                setLayer(layer);
-            }
-
-            /**
-             * The root layer to capture.
-             */
-            public Builder setLayer(SurfaceControl layer) {
-                mLayer = layer;
-                return this;
-            }
-
-
-            /**
-             * An array of layer handles to exclude.
-             */
-            public Builder setExcludeLayers(@Nullable SurfaceControl[] excludeLayers) {
-                mExcludeLayers = excludeLayers;
-                return this;
-            }
-
-            /**
-             * Whether to include the layer itself in the screenshot or just the children and their
-             * descendants.
-             */
-            public Builder setChildrenOnly(boolean childrenOnly) {
-                mChildrenOnly = childrenOnly;
-                return this;
-            }
-
-            @Override
-            Builder getThis() {
-                return this;
-            }
-
-        }
-    }
-
-    /**
      * Builder class for {@link SurfaceControl} objects.
      *
      * By default the surface will be hidden, and have "unset" bounds, meaning it can
@@ -2356,6 +1952,92 @@
     }
 
     /**
+     * Because this API is now going through {@link DisplayManager}, orientation and displayRect
+     * will automatically be computed based on configuration changes. Because of this, the params
+     * orientation and displayRect are ignored
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
+            publicAlternatives = "Use {@code VirtualDisplay#resize(int, int, int)} instead.",
+            trackingBug = 247078497)
+    public static void setDisplayProjection(IBinder displayToken, int orientation,
+            Rect layerStackRect, Rect displayRect) {
+        DisplayManagerGlobal.getInstance().resizeVirtualDisplay(
+                IVirtualDisplayCallback.Stub.asInterface(displayToken), layerStackRect.width(),
+                layerStackRect.height(), 1);
+    }
+
+    /**
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
+            publicAlternatives = "Use {@code MediaProjection#createVirtualDisplay()} with flag "
+                    + " {@code VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR} for mirroring instead.",
+            trackingBug = 247078497)
+    public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
+        IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
+        if (b == null) {
+            throw new UnsupportedOperationException();
+        }
+
+        IDisplayManager dm = IDisplayManager.Stub.asInterface(b);
+        try {
+            dm.setDisplayIdToMirror(displayToken, layerStack);
+        } catch (RemoteException e) {
+            throw new UnsupportedOperationException(e);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
+            publicAlternatives = "Use {@code VirtualDisplay#setSurface(Surface)} instead.",
+            trackingBug = 247078497)
+    public static void setDisplaySurface(IBinder displayToken, Surface surface) {
+        IVirtualDisplayCallback virtualDisplayCallback =
+                IVirtualDisplayCallback.Stub.asInterface(displayToken);
+        DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
+        dm.setVirtualDisplaySurface(virtualDisplayCallback, surface);
+    }
+
+    /**
+     * Secure is no longer supported because this is only called from outside system which cannot
+     * create secure displays.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
+            publicAlternatives = "Use {@code MediaProjection#createVirtualDisplay()} or "
+                    + "{@code DisplayManager#createVirtualDisplay()} instead.",
+            trackingBug = 247078497)
+    public static IBinder createDisplay(String name, boolean secure) {
+        if (name == null) {
+            throw new IllegalArgumentException("name must not be null");
+        }
+
+        // We don't have a size yet so pass in 1 for width and height since 0 is invalid
+        VirtualDisplay vd = MediaProjectionGlobal.getInstance().createVirtualDisplay(name,
+                1 /* width */, 1 /* height */, INVALID_DISPLAY, null /* Surface */);
+        return vd == null ? null : vd.getToken().asBinder();
+    }
+
+    /**
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
+            publicAlternatives = "Use {@code VirtualDisplay#release()} instead.",
+            trackingBug = 247078497)
+    public static void destroyDisplay(IBinder displayToken) {
+        if (displayToken == null) {
+            throw new IllegalArgumentException("displayToken must not be null");
+        }
+
+        DisplayManagerGlobal.getInstance().releaseVirtualDisplay(
+                IVirtualDisplayCallback.Stub.asInterface(displayToken));
+    }
+
+    /**
      * Overrides HDR modes for a display device.
      *
      * If the caller does not have ACCESS_SURFACE_FLINGER permission, this will throw a Security
@@ -2370,28 +2052,6 @@
     /**
      * @hide
      */
-    @UnsupportedAppUsage
-    public static IBinder createDisplay(String name, boolean secure) {
-        if (name == null) {
-            throw new IllegalArgumentException("name must not be null");
-        }
-        return nativeCreateDisplay(name, secure);
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static void destroyDisplay(IBinder displayToken) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
-        }
-        nativeDestroyDisplay(displayToken);
-    }
-
-    /**
-     * @hide
-     */
     public static long[] getPhysicalDisplayIds() {
         return nativeGetPhysicalDisplayIds();
     }
@@ -2419,119 +2079,6 @@
     }
 
     /**
-     * @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);
-    }
-
-    /**
-     * Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with
-     * the content.
-     *
-     * @hide
-     */
-    public static ScreenshotHardwareBuffer captureDisplay(DisplayCaptureArgs captureArgs) {
-        SyncScreenCaptureListener screenCaptureListener = new SyncScreenCaptureListener();
-
-        int status = captureDisplay(captureArgs, screenCaptureListener);
-        if (status != 0) {
-            return null;
-        }
-
-        return screenCaptureListener.waitForScreenshot();
-    }
-
-    /**
-     * Captures a layer and its children and returns a {@link HardwareBuffer} with the content.
-     *
-     * @param layer            The root layer to capture.
-     * @param sourceCrop       The portion of the root surface to capture; caller may pass in 'new
-     *                         Rect()' or null if no cropping is desired. If the root layer does not
-     *                         have a buffer or a crop set, then a non-empty source crop must be
-     *                         specified.
-     * @param frameScale       The desired scale of the returned buffer; the raw
-     *                         screen will be scaled up/down.
-     *
-     * @return Returns a HardwareBuffer that contains the layer capture.
-     * @hide
-     */
-    public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
-            float frameScale) {
-        return captureLayers(layer, sourceCrop, frameScale, PixelFormat.RGBA_8888);
-    }
-
-    /**
-     * Captures a layer and its children and returns a {@link HardwareBuffer} with the content.
-     *
-     * @param layer            The root layer to capture.
-     * @param sourceCrop       The portion of the root surface to capture; caller may pass in 'new
-     *                         Rect()' or null if no cropping is desired. If the root layer does not
-     *                         have a buffer or a crop set, then a non-empty source crop must be
-     *                         specified.
-     * @param frameScale       The desired scale of the returned buffer; the raw
-     *                         screen will be scaled up/down.
-     * @param format           The desired pixel format of the returned buffer.
-     *
-     * @return Returns a HardwareBuffer that contains the layer capture.
-     * @hide
-     */
-    public static ScreenshotHardwareBuffer captureLayers(@NonNull SurfaceControl layer,
-            @Nullable Rect sourceCrop, float frameScale, int format) {
-        LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer)
-                .setSourceCrop(sourceCrop)
-                .setFrameScale(frameScale)
-                .setPixelFormat(format)
-                .build();
-
-        return captureLayers(captureArgs);
-    }
-
-    /**
-     * @hide
-     */
-    public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) {
-        SyncScreenCaptureListener screenCaptureListener = new SyncScreenCaptureListener();
-
-        int status = captureLayers(captureArgs, screenCaptureListener);
-        if (status != 0) {
-            return null;
-        }
-
-        return screenCaptureListener.waitForScreenshot();
-    }
-
-    /**
-     * Like {@link #captureLayers(SurfaceControl, Rect, float, int)} but with an array of layer
-     * handles to exclude.
-     * @hide
-     */
-    public static ScreenshotHardwareBuffer captureLayersExcluding(SurfaceControl layer,
-            Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) {
-        LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer)
-                .setSourceCrop(sourceCrop)
-                .setFrameScale(frameScale)
-                .setPixelFormat(format)
-                .setExcludeLayers(exclude)
-                .build();
-
-        return captureLayers(captureArgs);
-    }
-
-    /**
-     * @param captureArgs Arguments about how to take the screenshot
-     * @param captureListener A listener to receive the screenshot callback
-     * @hide
-     */
-    public static int captureLayers(@NonNull LayerCaptureArgs captureArgs,
-            @NonNull ScreenCaptureListener captureListener) {
-        return nativeCaptureLayers(captureArgs, captureListener);
-    }
-
-    /**
      * Returns whether protected content is supported in GPU composition.
      * @hide
      */
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 7acf319..9075de1 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -107,6 +107,14 @@
  * and scaling a SurfaceView on screen will not cause rendering artifacts. Such
  * artifacts may occur on previous versions of the platform when its window is
  * positioned asynchronously.</p>
+ *
+ * <p class="note"><strong>Note:</strong> Starting in platform version
+ * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, SurfaceView will support arbitrary
+ * alpha blending. Prior platform versions ignored alpha values on the SurfaceView if they were
+ * between 0 and 1. If the SurfaceView is configured with Z-above, then the alpha is applied
+ * directly to the Surface. If the SurfaceView is configured with Z-below, then the alpha is
+ * applied to the hole punch directly. Note that when using Z-below, overlapping SurfaceViews
+ * may not blend properly as a consequence of not applying alpha to the surface content directly.
  */
 public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCallback {
     private static final String TAG = "SurfaceView";
@@ -146,6 +154,7 @@
     Paint mRoundedViewportPaint;
 
     int mSubLayer = APPLICATION_MEDIA_SUBLAYER;
+    int mRequestedSubLayer = APPLICATION_MEDIA_SUBLAYER;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     boolean mIsCreating = false;
@@ -177,8 +186,7 @@
     @UnsupportedAppUsage
     int mRequestedFormat = PixelFormat.RGB_565;
 
-    boolean mUseAlpha = false;
-    float mSurfaceAlpha = 1f;
+    float mAlpha = 1f;
     boolean mClipSurfaceToBounds;
     int mBackgroundColor = Color.BLACK;
 
@@ -335,58 +343,25 @@
      * @hide
      */
     public void setUseAlpha() {
-        if (!mUseAlpha) {
-            mUseAlpha = true;
-            updateSurfaceAlpha();
-        }
+        // TODO(b/241474646): Remove me
+        return;
     }
 
     @Override
     public void setAlpha(float alpha) {
-        // Sets the opacity of the view to a value, where 0 means the view is completely transparent
-        // and 1 means the view is completely opaque.
-        //
-        // Note: Alpha value of this view is ignored by default. To enable alpha blending, you need
-        // to call setUseAlpha() as well.
-        // This view doesn't support translucent opacity if the view is located z-below, since the
-        // logic to punch a hole in the view hierarchy cannot handle such case. See also
-        // #clearSurfaceViewPort(Canvas)
         if (DEBUG) {
             Log.d(TAG, System.identityHashCode(this)
-                    + " setAlpha: mUseAlpha = " + mUseAlpha + " alpha=" + alpha);
+                    + " setAlpha: alpha=" + alpha);
         }
         super.setAlpha(alpha);
-        updateSurfaceAlpha();
     }
 
-    private float getFixedAlpha() {
-        // Compute alpha value to be set on the underlying surface.
-        final float alpha = getAlpha();
-        return mUseAlpha && (mSubLayer > 0 || alpha == 0f) ? alpha : 1f;
-    }
-
-    private void updateSurfaceAlpha() {
-        if (!mUseAlpha || !mHaveFrame || mSurfaceControl == null) {
-            return;
+    @Override
+    protected boolean onSetAlpha(int alpha) {
+        if (Math.round(mAlpha * 255) != alpha) {
+            updateSurface();
         }
-        final float viewAlpha = getAlpha();
-        if (mSubLayer < 0 && 0f < viewAlpha && viewAlpha < 1f) {
-            Log.w(TAG, System.identityHashCode(this)
-                    + " updateSurfaceAlpha:"
-                    + " translucent color is not supported for a surface placed z-below.");
-        }
-        final ViewRootImpl viewRoot = getViewRootImpl();
-        if (viewRoot == null) {
-            return;
-        }
-        final float alpha = getFixedAlpha();
-        if (alpha != mSurfaceAlpha) {
-            final Transaction transaction = new Transaction();
-            transaction.setAlpha(mSurfaceControl, alpha);
-            viewRoot.applyTransactionOnDraw(transaction);
-            damageInParent();
-            mSurfaceAlpha = alpha;
-        }
+        return true;
     }
 
     private void performDrawFinished() {
@@ -534,7 +509,15 @@
         invalidate();
     }
 
+    @Override
+    public boolean hasOverlappingRendering() {
+        // SurfaceViews only alpha composite by modulating the Surface alpha for Z-above, or
+        // applying alpha on the hole punch for Z-below - no deferral to a layer is necessary.
+        return false;
+    }
+
     private void clearSurfaceViewPort(Canvas canvas) {
+        final float alpha = getAlpha();
         if (mCornerRadius > 0f) {
             canvas.getClipBounds(mTmpRect);
             if (mClipSurfaceToBounds && mClipBounds != null) {
@@ -546,10 +529,11 @@
                     mTmpRect.right,
                     mTmpRect.bottom,
                     mCornerRadius,
-                    mCornerRadius
+                    mCornerRadius,
+                    alpha
             );
         } else {
-            canvas.punchHole(0f, 0f, getWidth(), getHeight(), 0f, 0f);
+            canvas.punchHole(0f, 0f, getWidth(), getHeight(), 0f, 0f, alpha);
         }
     }
 
@@ -626,7 +610,7 @@
      * @hide
      */
     public boolean isZOrderedOnTop() {
-        return mSubLayer > 0;
+        return mRequestedSubLayer > 0;
     }
 
     /**
@@ -652,10 +636,10 @@
         } else {
             subLayer = APPLICATION_MEDIA_SUBLAYER;
         }
-        if (mSubLayer == subLayer) {
+        if (mRequestedSubLayer == subLayer) {
             return false;
         }
-        mSubLayer = subLayer;
+        mRequestedSubLayer = subLayer;
 
         if (!allowDynamicChange) {
             return false;
@@ -667,9 +651,8 @@
         if (viewRoot == null) {
             return true;
         }
-        final Transaction transaction = new SurfaceControl.Transaction();
-        updateRelativeZ(transaction);
-        viewRoot.applyTransactionOnDraw(transaction);
+
+        updateSurface();
         invalidate();
         return true;
     }
@@ -722,8 +705,7 @@
     }
 
     private void releaseSurfaces(boolean releaseSurfacePackage) {
-        mSurfaceAlpha = 1f;
-
+        mAlpha = 1f;
         synchronized (mSurfaceControlLock) {
             mSurface.destroy();
             if (mBlastBufferQueue != null) {
@@ -770,7 +752,7 @@
     }
 
     private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
-            boolean creating, boolean sizeChanged, boolean hintChanged,
+            boolean creating, boolean sizeChanged, boolean hintChanged, boolean relativeZChanged,
             Transaction surfaceUpdateTransaction) {
         boolean realSizeChanged = false;
 
@@ -800,14 +782,20 @@
                 surfaceUpdateTransaction.hide(mSurfaceControl);
             }
 
-
-
             updateBackgroundVisibility(surfaceUpdateTransaction);
             updateBackgroundColor(surfaceUpdateTransaction);
-            if (mUseAlpha) {
-                float alpha = getFixedAlpha();
+            if (isAboveParent()) {
+                float alpha = getAlpha();
                 surfaceUpdateTransaction.setAlpha(mSurfaceControl, alpha);
-                mSurfaceAlpha = alpha;
+            }
+
+            if (relativeZChanged) {
+                if (!isAboveParent()) {
+                    // If we're moving from z-above to z-below, then restore the surface alpha back to 1
+                    // and let the holepunch drive visibility and blending.
+                    surfaceUpdateTransaction.setAlpha(mSurfaceControl, 1.f);
+                }
+                updateRelativeZ(surfaceUpdateTransaction);
             }
 
             surfaceUpdateTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
@@ -873,6 +861,7 @@
         } finally {
             mSurfaceLock.unlock();
         }
+
         return realSizeChanged;
     }
 
@@ -906,10 +895,10 @@
         int myHeight = mRequestedHeight;
         if (myHeight <= 0) myHeight = getHeight();
 
-        final float alpha = getFixedAlpha();
+        final float alpha = getAlpha();
         final boolean formatChanged = mFormat != mRequestedFormat;
         final boolean visibleChanged = mVisible != mRequestedVisible;
-        final boolean alphaChanged = mSurfaceAlpha != alpha;
+        final boolean alphaChanged = mAlpha != alpha;
         final boolean creating = (mSurfaceControl == null || formatChanged || visibleChanged)
                 && mRequestedVisible;
         final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
@@ -921,17 +910,17 @@
             || getHeight() != mScreenRect.height();
         final boolean hintChanged = (viewRoot.getBufferTransformHint() != mTransformHint)
                 && mRequestedVisible;
+        final boolean relativeZChanged = mSubLayer != mRequestedSubLayer;
 
-        if (creating || formatChanged || sizeChanged || visibleChanged ||
-                (mUseAlpha && alphaChanged) || windowVisibleChanged ||
-                positionChanged || layoutSizeChanged || hintChanged) {
+        if (creating || formatChanged || sizeChanged || visibleChanged
+                || alphaChanged || windowVisibleChanged || positionChanged
+                || layoutSizeChanged || hintChanged || relativeZChanged) {
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                     + "Changes: creating=" + creating
                     + " format=" + formatChanged + " size=" + sizeChanged
                     + " visible=" + visibleChanged + " alpha=" + alphaChanged
                     + " hint=" + hintChanged
-                    + " mUseAlpha=" + mUseAlpha
                     + " visible=" + visibleChanged
                     + " left=" + (mWindowSpaceLeft != mLocation[0])
                     + " top=" + (mWindowSpaceTop != mLocation[1]));
@@ -943,8 +932,10 @@
                 mSurfaceWidth = myWidth;
                 mSurfaceHeight = myHeight;
                 mFormat = mRequestedFormat;
+                mAlpha = alpha;
                 mLastWindowVisibility = mWindowVisibility;
                 mTransformHint = viewRoot.getBufferTransformHint();
+                mSubLayer = mRequestedSubLayer;
 
                 mScreenRect.left = mWindowSpaceLeft;
                 mScreenRect.top = mWindowSpaceTop;
@@ -968,7 +959,7 @@
                 }
 
                 final boolean redrawNeeded = sizeChanged || creating || hintChanged
-                        || (mVisible && !mDrawFinished);
+                        || (mVisible && !mDrawFinished) || alphaChanged || relativeZChanged;
                 boolean shouldSyncBuffer =
                         redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInLocalSync();
                 SyncBufferTransactionCallback syncBufferTransactionCallback = null;
@@ -979,8 +970,9 @@
                             syncBufferTransactionCallback::onTransactionReady);
                 }
 
-                final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
-                        translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
+                final boolean realSizeChanged = performSurfaceTransaction(viewRoot, translator,
+                        creating, sizeChanged, hintChanged, relativeZChanged,
+                        surfaceUpdateTransaction);
 
                 try {
                     SurfaceHolder.Callback[] callbacks = null;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b698316..894ce63 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3095,7 +3095,6 @@
      * <p>
      * Accessibility interactions from services without {@code isAccessibilityTool} set to true are
      * disallowed for any of the following conditions:
-     * <li>this view's window sets {@link WindowManager.LayoutParams#FLAG_SECURE}.</li>
      * <li>this view sets {@link #getFilterTouchesWhenObscured()}.</li>
      * <li>any parent of this view returns true from {@link #isAccessibilityDataPrivate()}.</li>
      * </p>
@@ -8326,10 +8325,17 @@
 
     /**
      * Visually distinct portion of a window with window-like semantics are considered panes for
-     * accessibility purposes. One example is the content view of a fragment that is replaced.
+     * accessibility purposes. One example is the content view of a large fragment that is replaced.
      * In order for accessibility services to understand a pane's window-like behavior, panes
-     * should have descriptive titles. Views with pane titles produce {@link AccessibilityEvent}s
-     * when they appear, disappear, or change title.
+     * should have descriptive titles. Views with pane titles produce
+     * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}s when they appear, disappear, or change
+     * title.
+     *
+     * <p>
+     * When transitioning from one Activity to another, instead of using
+     * setAccessibilityPaneTitle(), set a descriptive title for its window by using android:label
+     * for the matching <activity> entry in your application’s manifest or updating the title at
+     * runtime with{@link android.app.Activity#setTitle(CharSequence)}.
      *
      * @param accessibilityPaneTitle The pane's title. Setting to {@code null} indicates that this
      *                               View is not a pane.
@@ -14524,9 +14530,6 @@
         // Use the explicit value if set.
         if (mExplicitAccessibilityDataPrivate != ACCESSIBILITY_DATA_PRIVATE_AUTO) {
             mInferredAccessibilityDataPrivate = mExplicitAccessibilityDataPrivate;
-        } else if (mAttachInfo != null && mAttachInfo.mWindowSecure) {
-            // Views inside FLAG_SECURE windows default to accessibilityDataPrivate.
-            mInferredAccessibilityDataPrivate = ACCESSIBILITY_DATA_PRIVATE_YES;
         } else if (getFilterTouchesWhenObscured()) {
             // Views that set filterTouchesWhenObscured default to accessibilityDataPrivate.
             mInferredAccessibilityDataPrivate = ACCESSIBILITY_DATA_PRIVATE_YES;
@@ -24512,9 +24515,8 @@
     /**
      * Set the current default focus highlight.
      * @param highlight the highlight drawable, or {@code null} if it's no longer needed.
-     * @hide
      */
-    void setDefaultFocusHighlight(Drawable highlight) {
+    private void setDefaultFocusHighlight(Drawable highlight) {
         mDefaultFocusHighlight = highlight;
         mDefaultFocusHighlightSizeChanged = true;
         if (highlight != null) {
@@ -30255,11 +30257,6 @@
         int mWindowVisibility;
 
         /**
-         * Indicates whether the view's window sets {@link WindowManager.LayoutParams#FLAG_SECURE}.
-         */
-        boolean mWindowSecure;
-
-        /**
          * Indicates the time at which drawing started to occur.
          */
         @UnsupportedAppUsage
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 89a1557..b6f775d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2838,7 +2838,6 @@
             // However, windows are now always 32 bits by default, so choose 32 bits
             mAttachInfo.mUse32BitDrawingCache = true;
             mAttachInfo.mWindowVisibility = viewVisibility;
-            mAttachInfo.mWindowSecure = (lp.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0;
             mAttachInfo.mRecomputeGlobalAttributes = false;
             mLastConfigurationFromResources.setTo(config);
             mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
@@ -3099,7 +3098,8 @@
                 // WindowManagerService has reported back a frame from a configuration not yet
                 // handled by the client. In this case, we need to accept the configuration so we
                 // do not lay out and draw with the wrong configuration.
-                if (!mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) {
+                if (mRelayoutRequested
+                        && !mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) {
                     if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: "
                             + mPendingMergedConfiguration.getMergedConfiguration());
                     performConfigurationChange(new MergedConfiguration(mPendingMergedConfiguration),
@@ -3815,13 +3815,6 @@
                 if (mAttachInfo.mTooltipHost != null) {
                     mAttachInfo.mTooltipHost.hideTooltip();
                 }
-                if (!hasWindowFocus) {
-                    // Clear focus highlight if its window lost focus.
-                    final View focused = mView.findFocus();
-                    if (focused != null) {
-                        focused.setDefaultFocusHighlight(null);
-                    }
-                }
             }
 
             // Note: must be done after the focus change callbacks,
@@ -5853,13 +5846,7 @@
             // be when the window is first being added, and mFocused isn't
             // set yet.
             final View focused = mView.findFocus();
-            if (focused == null) {
-                return false;
-            }
-
-            // Clear default focus highlight if it entered touch mode.
-            focused.setDefaultFocusHighlight(null);
-            if (!focused.isFocusableInTouchMode()) {
+            if (focused != null && !focused.isFocusableInTouchMode()) {
                 final ViewGroup ancestorToTakeFocus = findAncestorToTakeFocusInTouchMode(focused);
                 if (ancestorToTakeFocus != null) {
                     // there is an ancestor that wants focus after its
@@ -8159,7 +8146,8 @@
         final int measuredWidth = mView.getMeasuredWidth();
         final int measuredHeight = mView.getMeasuredHeight();
         final boolean relayoutAsync;
-        if (LOCAL_LAYOUT && !mFirst && viewVisibility == mViewVisibility
+        if (LOCAL_LAYOUT
+                && (mViewFrameInfo.flags & FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED) == 0
                 && mWindowAttributes.type != TYPE_APPLICATION_STARTING
                 && mSyncSeqId <= mLastSyncSeqId
                 && winConfigFromAm.diff(winConfigFromWm, false /* compareUndefined */) == 0) {
@@ -8226,6 +8214,7 @@
                     mLastSyncSeqId, mTmpFrames, mPendingMergedConfiguration, mSurfaceControl,
                     mTempInsets, mTempControls, mRelayoutBundle);
             mRelayoutRequested = true;
+
             final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid");
             if (maybeSyncSeqId > 0) {
                 mSyncSeqId = maybeSyncSeqId;
@@ -8266,6 +8255,12 @@
             }
         }
 
+        if (mSurfaceControl.isValid() && !HardwareRenderer.isDrawingEnabled()) {
+            // When drawing is disabled the window layer won't have a valid buffer.
+            // Set a window crop so input can get delivered to the window.
+            mTransaction.setWindowCrop(mSurfaceControl, mSurfaceSize.x, mSurfaceSize.y).apply();
+        }
+
         mLastTransformHint = transformHint;
       
         mSurfaceControl.setTransformHint(transformHint);
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index e89f836..7528e2a 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -585,6 +585,18 @@
 
     /**
      * Returns if the accessibility in the system is enabled.
+     * <p>
+     * <b>Note:</b> This query is used for sending {@link AccessibilityEvent}s, since events are
+     * only needed if accessibility is on. Avoid changing UI or app behavior based on the state of
+     * accessibility. While well-intentioned, doing this creates brittle, less
+     * well-maintained code that works for some users but not others. Shared code leads to more
+     * equitable experiences and less technical debt.
+     *
+     *<p>
+     * For example, if you want to expose a unique interaction with your app, use
+     * ViewCompat#addAccessibilityAction in AndroidX to make this interaction - ideally
+     * with the same code path used for non-accessibility users - available to accessibility
+     * services. Services can then expose this action in the way best fit for their users.
      *
      * @return True if accessibility is enabled, false otherwise.
      */
@@ -597,6 +609,13 @@
 
     /**
      * Returns if the touch exploration in the system is enabled.
+     * <p>
+     * <b>Note:</b> This query is used for dispatching hover events, such as
+     * {@link android.view.MotionEvent#ACTION_HOVER_ENTER}, to accessibility services to manage
+     * touch exploration. Avoid changing UI or app behavior based on the state of accessibility.
+     * While well-intentioned, doing this creates brittle, less well-maintained code that works for
+     * som users but not others. Shared code leads to more equitable experiences and less technical
+     * debt.
      *
      * @return True if touch exploration is enabled, false otherwise.
      */
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 8d75072..a72f0d5 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -879,11 +879,8 @@
             Context context;
             if (mTargetView != null) {
                 context = mTargetView.getContext();
-            } else if (mIMM.mCurRootView != null) {
-                final View servedView = mIMM.mCurRootView.getImeFocusController().getServedView();
-                context = servedView != null ? servedView.getContext() : null;
             } else {
-                context = null;
+                context = mIMM.getFallbackContextFromServedView();
             }
             if (context != null) {
                 TypedArray ta = context.getTheme()
diff --git a/core/java/android/view/inputmethod/DeleteGesture.java b/core/java/android/view/inputmethod/DeleteGesture.java
index 9fadabf..c88158f 100644
--- a/core/java/android/view/inputmethod/DeleteGesture.java
+++ b/core/java/android/view/inputmethod/DeleteGesture.java
@@ -27,9 +27,11 @@
 import java.util.Objects;
 
 /**
- * A sub-class of {@link HandwritingGesture} for deleting an area of text.
+ * A sub-class of {@link HandwritingGesture} for deleting an area of text using single rectangle.
  * This class holds the information required for deletion of text in
  * toolkit widgets like {@link TextView}.
+ * <p>Note: This deletes all text <em>within</em> the given area. To delete a range <em>between</em>
+ * two areas, use {@link DeleteRangeGesture}.</p>
  */
 public final class DeleteGesture extends HandwritingGesture implements Parcelable {
 
diff --git a/core/java/android/view/inputmethod/DeleteRangeGesture.aidl b/core/java/android/view/inputmethod/DeleteRangeGesture.aidl
new file mode 100644
index 0000000..0ae8899
--- /dev/null
+++ b/core/java/android/view/inputmethod/DeleteRangeGesture.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+parcelable DeleteRangeGesture;
\ No newline at end of file
diff --git a/core/java/android/view/inputmethod/DeleteRangeGesture.java b/core/java/android/view/inputmethod/DeleteRangeGesture.java
new file mode 100644
index 0000000..53b4209
--- /dev/null
+++ b/core/java/android/view/inputmethod/DeleteRangeGesture.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.graphics.RectF;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.widget.TextView;
+
+import java.util.Objects;
+
+/**
+ * A subclass of {@link HandwritingGesture} for deleting a range of text by defining start and end
+ * rectangles. This can be useful when the range cannot be defined with a single rectangle.
+ * This class holds the information required for deletion of text in
+ * toolkit widgets like {@link TextView}.
+ * <p>Note: this deletes text within a range <em>between</em> two given areas. To delete all text
+ * <em>within</em> a single area, use {@link DeleteGesture}.</p>
+ */
+public final class DeleteRangeGesture extends HandwritingGesture implements Parcelable {
+
+    private @Granularity int mGranularity;
+    private RectF mStartArea;
+    private RectF mEndArea;
+
+    private DeleteRangeGesture(
+            int granularity, RectF startArea, RectF endArea, String fallbackText) {
+        mType = GESTURE_TYPE_DELETE_RANGE;
+        mStartArea = startArea;
+        mEndArea = endArea;
+        mGranularity = granularity;
+        mFallbackText = fallbackText;
+    }
+
+    private DeleteRangeGesture(@NonNull Parcel source) {
+        mType = GESTURE_TYPE_DELETE_RANGE;
+        mFallbackText = source.readString8();
+        mGranularity = source.readInt();
+        mStartArea = source.readTypedObject(RectF.CREATOR);
+        mEndArea = source.readTypedObject(RectF.CREATOR);
+    }
+
+    /**
+     * Returns Granular level on which text should be operated.
+     * @see #GRANULARITY_CHARACTER
+     * @see #GRANULARITY_WORD
+     */
+    @Granularity
+    public int getGranularity() {
+        return mGranularity;
+    }
+
+    /**
+     * Returns the Deletion start area {@link RectF} in screen coordinates.
+     *
+     * Getter for deletion area set with {@link Builder#setDeletionStartArea(RectF)}.
+     */
+    @NonNull
+    public RectF getDeletionStartArea() {
+        return mStartArea;
+    }
+
+    /**
+     * Returns the Deletion end area {@link RectF} in screen coordinates.
+     *
+     * Getter for deletion area set with {@link Builder#setDeletionEndArea(RectF)}.
+     */
+    @NonNull
+    public RectF getDeletionEndArea() {
+        return mEndArea;
+    }
+
+    /**
+     * Builder for {@link DeleteRangeGesture}. This class is not designed to be thread-safe.
+     */
+    public static final class Builder {
+        private int mGranularity;
+        private RectF mStartArea;
+        private RectF mEndArea;
+        private String mFallbackText;
+
+        /**
+         * Define text deletion granularity. Intersecting words/characters will be
+         * included in the operation.
+         * @param granularity {@link HandwritingGesture#GRANULARITY_WORD} or
+         * {@link HandwritingGesture#GRANULARITY_CHARACTER}.
+         * @return {@link Builder}.
+         */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setGranularity(@Granularity int granularity) {
+            mGranularity = granularity;
+            return this;
+        }
+
+        /**
+         * Set rectangular single/multiline start of text deletion area intersecting with text.
+         *
+         * The resulting deletion is performed from the start of first word/character in the start
+         * rectangle to the end of the last word/character in the end rectangle
+         * {@link #setDeletionEndArea(RectF)}.
+         * <br/>
+         * <img src="{@docRoot}reference/android/images/input_method/stylus_handwriting
+         * /delete_range_gesture_rects.png"
+         * height="300" alt="Deletion strategy using two rectangles"/>
+         *  <br/>
+         *
+         * Intersection is determined using
+         * {@link #setGranularity(int)}. e.g. {@link HandwritingGesture#GRANULARITY_WORD} includes
+         * all the words with their width/height center included in the deletion rectangle.
+         * @param startArea {@link RectF} (in screen coordinates) for start of deletion. This
+         * rectangle belongs to first line where deletion should start.
+         */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setDeletionStartArea(@NonNull RectF startArea) {
+            mStartArea = startArea;
+            return this;
+        }
+
+        /**
+         * Set rectangular single/multiline end of text deletion area intersecting with text.
+         *
+         * The resulting deletion is performed from the start of first word/character in the start
+         * rectangle {@link #setDeletionStartArea(RectF)} to the end of the last word/character in
+         * the end rectangle.
+         * <br/>
+         * <img src="{@docRoot}reference/android/images/input_method/stylus_handwriting
+         * /delete_range_gesture_rects.png"
+         * height="300" alt="Deletion strategy using two rectangles"/>
+         *
+         * Intersection is determined using
+         * {@link #setGranularity(int)}. e.g. {@link HandwritingGesture#GRANULARITY_WORD} includes
+         * all the words with their width/height center included in the deletion rectangle.
+         * @param endArea {@link RectF} (in screen coordinates) for start of deletion. This
+         * rectangle belongs to the last line where deletion should end.
+         */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setDeletionEndArea(@NonNull RectF endArea) {
+            mEndArea = endArea;
+            return this;
+        }
+
+        /**
+         * Set fallback text that will be committed at current cursor position if there is no
+         * applicable text beneath the area of gesture.
+         * @param fallbackText text to set
+         */
+        @NonNull
+        public Builder setFallbackText(@Nullable String fallbackText) {
+            mFallbackText = fallbackText;
+            return this;
+        }
+
+        /**
+         * @return {@link DeleteRangeGesture} using parameters in this
+         * {@link DeleteRangeGesture.Builder}.
+         * @throws IllegalArgumentException if one or more positional parameters are not specified.
+         */
+        @NonNull
+        public DeleteRangeGesture build() {
+            if (mStartArea == null || mStartArea.isEmpty() || mEndArea == null
+                    || mEndArea.isEmpty()) {
+                throw new IllegalArgumentException("Deletion area must be set.");
+            }
+            if (mGranularity <= GRANULARITY_UNDEFINED) {
+                throw new IllegalArgumentException("Deletion granularity must be set.");
+            }
+            return new DeleteRangeGesture(mGranularity, mStartArea, mEndArea, mFallbackText);
+        }
+    }
+
+    /**
+     * Used to make this class parcelable.
+     */
+    @NonNull
+    public static final Creator<DeleteRangeGesture> CREATOR =
+            new Creator<DeleteRangeGesture>() {
+                @Override
+                public DeleteRangeGesture createFromParcel(Parcel source) {
+                    return new DeleteRangeGesture(source);
+                }
+
+                @Override
+                public DeleteRangeGesture[] newArray(int size) {
+                    return new DeleteRangeGesture[size];
+                }
+            };
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mGranularity, mStartArea, mEndArea, mFallbackText);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof DeleteRangeGesture)) return false;
+
+        DeleteRangeGesture that = (DeleteRangeGesture) o;
+
+        if (mGranularity != that.mGranularity) return false;
+        if (!Objects.equals(mFallbackText, that.mFallbackText)) return false;
+        if (!Objects.equals(mStartArea, that.mStartArea)) return false;
+        return Objects.equals(mEndArea, that.mEndArea);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Used to package this object into a {@link Parcel}.
+     *
+     * @param dest The {@link Parcel} to be written.
+     * @param flags The flags used for parceling.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString8(mFallbackText);
+        dest.writeInt(mGranularity);
+        dest.writeTypedObject(mStartArea, flags);
+        dest.writeTypedObject(mEndArea, flags);
+    }
+}
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index c3b32c9..4a79ba6 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -557,10 +557,14 @@
             Objects.requireNonNull(gesture);
             if (gesture.equals(SelectGesture.class)) {
                 supportedTypes |= HandwritingGesture.GESTURE_TYPE_SELECT;
+            } else if (gesture.equals(SelectRangeGesture.class)) {
+                supportedTypes |= HandwritingGesture.GESTURE_TYPE_SELECT_RANGE;
             } else if (gesture.equals(InsertGesture.class)) {
                 supportedTypes |= HandwritingGesture.GESTURE_TYPE_INSERT;
             } else if (gesture.equals(DeleteGesture.class)) {
                 supportedTypes |= HandwritingGesture.GESTURE_TYPE_DELETE;
+            } else if (gesture.equals(DeleteRangeGesture.class)) {
+                supportedTypes |= HandwritingGesture.GESTURE_TYPE_DELETE_RANGE;
             } else if (gesture.equals(RemoveSpaceGesture.class)) {
                 supportedTypes |= HandwritingGesture.GESTURE_TYPE_REMOVE_SPACE;
             } else if (gesture.equals(JoinOrSplitGesture.class)) {
diff --git a/core/java/android/view/inputmethod/HandwritingGesture.java b/core/java/android/view/inputmethod/HandwritingGesture.java
index 494aaaa..07b1e1f 100644
--- a/core/java/android/view/inputmethod/HandwritingGesture.java
+++ b/core/java/android/view/inputmethod/HandwritingGesture.java
@@ -25,6 +25,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.function.IntConsumer;
 
@@ -106,14 +107,26 @@
     public static final int GESTURE_TYPE_JOIN_OR_SPLIT = 1 << 4;
 
     /**
+     * Gesture of type {@link SelectRangeGesture} to select range of text.
+     */
+    public static final int GESTURE_TYPE_SELECT_RANGE = 1 << 5;
+
+    /**
+     * Gesture of type {@link DeleteRangeGesture} to delete range of text.
+     */
+    public static final int GESTURE_TYPE_DELETE_RANGE = 1 << 6;
+
+    /**
      * Type of gesture like {@link #GESTURE_TYPE_SELECT}, {@link #GESTURE_TYPE_INSERT},
      * or {@link #GESTURE_TYPE_DELETE}.
      */
     @IntDef(prefix = {"GESTURE_TYPE_"}, value = {
             GESTURE_TYPE_NONE,
             GESTURE_TYPE_SELECT,
+            GESTURE_TYPE_SELECT_RANGE,
             GESTURE_TYPE_INSERT,
             GESTURE_TYPE_DELETE,
+            GESTURE_TYPE_DELETE_RANGE,
             GESTURE_TYPE_REMOVE_SPACE,
             GESTURE_TYPE_JOIN_OR_SPLIT})
     @Retention(RetentionPolicy.SOURCE)
@@ -123,13 +136,15 @@
      * Flags which can be any combination of {@link #GESTURE_TYPE_SELECT},
      * {@link #GESTURE_TYPE_INSERT}, or {@link #GESTURE_TYPE_DELETE}.
      * {@link GestureTypeFlags} can be used by editors to declare what gestures are supported
-     *  and report them in {@link EditorInfo#setSupportedHandwritingGestureTypes(int)}.
+     *  and report them in {@link EditorInfo#setSupportedHandwritingGestures(List)}.
      * @hide
      */
     @IntDef(flag = true, prefix = {"GESTURE_TYPE_"}, value = {
             GESTURE_TYPE_SELECT,
+            GESTURE_TYPE_SELECT_RANGE,
             GESTURE_TYPE_INSERT,
             GESTURE_TYPE_DELETE,
+            GESTURE_TYPE_DELETE_RANGE,
             GESTURE_TYPE_REMOVE_SPACE,
             GESTURE_TYPE_JOIN_OR_SPLIT})
     @Retention(RetentionPolicy.SOURCE)
@@ -140,7 +155,7 @@
     /**
      * Returns the gesture type {@link GestureType}.
      * {@link GestureType} can be used by editors to declare what gestures are supported and report
-     * them in {@link EditorInfo#setSupportedHandwritingGestureTypes(int)}.
+     * them in {@link EditorInfo#setSupportedHandwritingGestures(List)}.
      * @hide
      */
     @TestApi
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 0c7c163..7794b7c 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -677,6 +677,21 @@
         return fallbackImm;
     }
 
+    /**
+     * An internal API that returns the {@link Context} of the current served view connected to
+     * an input method.
+     * @hide
+     */
+    Context getFallbackContextFromServedView() {
+        synchronized (mH) {
+            if (mCurRootView == null) {
+                return null;
+            }
+            final View servedView = mCurRootView.getImeFocusController().getServedViewLocked();
+            return servedView != null ? servedView.getContext() : null;
+        }
+    }
+
     private static boolean canStartInput(View servedView) {
         // We can start input ether the servedView has window focus
         // or the activity is showing autofill ui.
@@ -756,10 +771,10 @@
         }
 
         /**
-         * For {@link ImeFocusController} to start input asynchronously when focus gain.
+         * For {@link ImeFocusController} to start input when gaining the window focus.
          */
         @Override
-        public void startInputAsyncOnWindowFocusGain(View focusedView,
+        public void startInputOnWindowFocusGain(View focusedView,
                 @SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus) {
             int startInputFlags = getStartInputFlags(focusedView, 0);
             startInputFlags |= StartInputFlags.WINDOW_GAINED_FOCUS;
@@ -772,6 +787,15 @@
             if (controller == null) {
                 return;
             }
+
+            synchronized (mH) {
+                if (mRestartOnNextWindowFocus) {
+                    if (DEBUG) Log.v(TAG, "Restarting due to mRestartOnNextWindowFocus as true");
+                    mRestartOnNextWindowFocus = false;
+                    forceNewFocus = true;
+                }
+            }
+
             if (controller.checkFocus(forceNewFocus, false)) {
                 // We need to restart input on the current focus view.  This
                 // should be done in conjunction with telling the system service
@@ -786,9 +810,9 @@
             synchronized (mH) {
                 // For some reason we didn't do a startInput + windowFocusGain, so
                 // we'll just do a window focus gain and call it a day.
-                View servedView = controller.getServedView();
+                View servedView = controller.getServedViewLocked();
                 boolean nextFocusHasConnection = servedView != null && servedView == focusedView
-                        && hasActiveConnection(focusedView);
+                        && hasActiveInputConnectionInternal(focusedView);
                 if (DEBUG) {
                     Log.v(TAG, "Reporting focus gain, without startInput"
                             + ", nextFocusIsServedView=" + nextFocusHasConnection);
@@ -845,38 +869,23 @@
         }
 
         /**
-         * For {@link ImeFocusController#checkFocus} if needed to force check new focus.
-         */
-        @Override
-        public boolean isRestartOnNextWindowFocus(boolean reset) {
-            synchronized (mH) {
-                final boolean result = mRestartOnNextWindowFocus;
-                if (reset) {
-                    mRestartOnNextWindowFocus = false;
-                }
-                return result;
-            }
-        }
-
-        /**
          * Checks whether the active input connection (if any) is for the given view.
          *
-         * TODO(b/182259171): Clean-up hasActiveConnection to simplify the logic.
-         *
-         * Note that this method is only intended for restarting input after focus gain
-         * (e.g. b/160391516), DO NOT leverage this method to do another check.
+         * @see #hasActiveInputConnectionInternal(View)}
          */
         @Override
         public boolean hasActiveConnection(View view) {
-            synchronized (mH) {
-                if (!hasServedByInputMethodLocked(view) || !isImeSessionAvailableLocked()) {
-                    return false;
-                }
+            return hasActiveInputConnectionInternal(view);
+        }
 
-                return mServedInputConnection != null
-                        && mServedInputConnection.isActive()
-                        && mServedInputConnection.getServedView() == view;
-            }
+        /**
+         * Returns the {@link InputMethodManager#mH} lock object.
+         * Used for {@link ImeFocusController} to guard the served view being accessed by
+         * {@link InputMethodManager} in different threads.
+         */
+        @Override
+        public Object getLockObject() {
+            return mH;
         }
     }
 
@@ -889,36 +898,43 @@
      * Checks whether the active input connection (if any) is for the given view.
      *
      * @hide
-     * @see ImeFocusController#getImmDelegate()#hasActiveInputConnection(View)
+     * @see #hasActiveInputConnectionInternal(View)}
      */
     @TestApi
     public boolean hasActiveInputConnection(@Nullable View view) {
-        return mDelegate.hasActiveConnection(view);
+        return hasActiveInputConnectionInternal(view);
+    }
+
+    /**
+     * Checks whether the active input connection (if any) is for the given view.
+     *
+     * TODO(b/182259171): Clean-up hasActiveConnection to simplify the logic.
+     *
+     * Note that this method is only intended for restarting input after focus gain
+     * (e.g. b/160391516), DO NOT leverage this method to do another check.
+     */
+    private boolean hasActiveInputConnectionInternal(@Nullable View view) {
+        synchronized (mH) {
+            if (!hasServedByInputMethodLocked(view) || !isImeSessionAvailableLocked()) {
+                return false;
+            }
+
+            return mServedInputConnection != null
+                    && mServedInputConnection.isActive()
+                    && mServedInputConnection.getServedView() == view;
+        }
     }
 
     @GuardedBy("mH")
     private View getServedViewLocked() {
-        return mCurRootView != null ? mCurRootView.getImeFocusController().getServedView() : null;
-    }
-
-    @GuardedBy("mH")
-    private View getNextServedViewLocked() {
-        return mCurRootView != null ? mCurRootView.getImeFocusController().getNextServedView()
+        return mCurRootView != null ? mCurRootView.getImeFocusController().getServedViewLocked()
                 : null;
     }
 
     @GuardedBy("mH")
-    private void setServedViewLocked(View view) {
-        if (mCurRootView != null) {
-            mCurRootView.getImeFocusController().setServedView(view);
-        }
-    }
-
-    @GuardedBy("mH")
-    private void setNextServedViewLocked(View view) {
-        if (mCurRootView != null) {
-            mCurRootView.getImeFocusController().setNextServedView(view);
-        }
+    private View getNextServedViewLocked() {
+        return mCurRootView != null ? mCurRootView.getImeFocusController().getNextServedViewLocked()
+                : null;
     }
 
     private ImeFocusController getFocusController() {
@@ -1767,13 +1783,13 @@
     @GuardedBy("mH")
     void finishInputLocked() {
         mVirtualDisplayToScreenMatrix = null;
-        setNextServedViewLocked(null);
-        if (getServedViewLocked() != null) {
+        final ImeFocusController controller = getFocusController();
+        final View clearedView = controller != null ? controller.clearServedViewsLocked() : null;
+        if (clearedView != null) {
             if (DEBUG) {
                 Log.v(TAG, "FINISH INPUT: mServedView="
-                        + InputMethodDebug.dumpViewInfo(getServedViewLocked()));
+                        + InputMethodDebug.dumpViewInfo(clearedView));
             }
-            setServedViewLocked(null);
             mCompletions = null;
             mServedConnecting = false;
             clearConnectionLocked();
diff --git a/core/java/android/view/inputmethod/SelectGesture.java b/core/java/android/view/inputmethod/SelectGesture.java
index 2f02e66..6dc4ed2 100644
--- a/core/java/android/view/inputmethod/SelectGesture.java
+++ b/core/java/android/view/inputmethod/SelectGesture.java
@@ -27,9 +27,11 @@
 import java.util.Objects;
 
 /**
- * A sub-class of {@link HandwritingGesture} for selecting an area of text.
+ * A sub-class of {@link HandwritingGesture} for selecting an area of text using single rectangle.
  * This class holds the information required for selection of text in
  * toolkit widgets like {@link TextView}.
+ * <p>Note: This selects all text <em>within</em> the given area. To select a range <em>between</em>
+ * two areas, use {@link SelectRangeGesture}.</p>
  */
 public final class SelectGesture extends HandwritingGesture implements Parcelable {
 
diff --git a/core/java/android/view/inputmethod/SelectRangeGesture.aidl b/core/java/android/view/inputmethod/SelectRangeGesture.aidl
new file mode 100644
index 0000000..a7bce0a
--- /dev/null
+++ b/core/java/android/view/inputmethod/SelectRangeGesture.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+parcelable SelectRangeGesture;
\ No newline at end of file
diff --git a/core/java/android/view/inputmethod/SelectRangeGesture.java b/core/java/android/view/inputmethod/SelectRangeGesture.java
new file mode 100644
index 0000000..7cb6002
--- /dev/null
+++ b/core/java/android/view/inputmethod/SelectRangeGesture.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.graphics.RectF;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.widget.TextView;
+
+import java.util.Objects;
+
+/**
+ * A subclass of {@link HandwritingGesture} for selecting a range of text by defining start and end
+ * rectangles. This can be useful when the range cannot be defined with a single rectangle.
+ * This class holds the information required for selection of text in
+ * toolkit widgets like {@link TextView}.
+ * <p>Note: this selects text within a range <em>between</em> two given areas. To select all text
+ * <em>within</em> a single area, use {@link SelectGesture}</p>
+ */
+public final class SelectRangeGesture extends HandwritingGesture implements Parcelable {
+
+    private @Granularity int mGranularity;
+    private RectF mStartArea;
+    private RectF mEndArea;
+
+    private SelectRangeGesture(
+            int granularity, RectF startArea, RectF endArea, String fallbackText) {
+        mType = GESTURE_TYPE_SELECT_RANGE;
+        mStartArea = startArea;
+        mEndArea = endArea;
+        mGranularity = granularity;
+        mFallbackText = fallbackText;
+    }
+
+    private SelectRangeGesture(@NonNull Parcel source) {
+        mType = GESTURE_TYPE_SELECT_RANGE;
+        mFallbackText = source.readString8();
+        mGranularity = source.readInt();
+        mStartArea = source.readTypedObject(RectF.CREATOR);
+        mEndArea = source.readTypedObject(RectF.CREATOR);
+    }
+
+    /**
+     * Returns Granular level on which text should be operated.
+     * @see #GRANULARITY_CHARACTER
+     * @see #GRANULARITY_WORD
+     */
+    @Granularity
+    public int getGranularity() {
+        return mGranularity;
+    }
+
+    /**
+     * Returns the Selection start area {@link RectF} in screen coordinates.
+     *
+     * Getter for selection area set with {@link Builder#setSelectionStartArea(RectF)}.
+     */
+    @NonNull
+    public RectF getSelectionStartArea() {
+        return mStartArea;
+    }
+
+    /**
+     * Returns the Selection end area {@link RectF} in screen coordinates.
+     *
+     * Getter for selection area set with {@link Builder#setSelectionEndArea(RectF)}.
+     */
+    @NonNull
+    public RectF getSelectionEndArea() {
+        return mEndArea;
+    }
+
+
+    /**
+     * Builder for {@link SelectRangeGesture}. This class is not designed to be thread-safe.
+     */
+    public static final class Builder {
+        private int mGranularity;
+        private RectF mStartArea;
+        private RectF mEndArea;
+        private String mFallbackText;
+
+        /**
+         * Define text selection granularity. Intersecting words/characters will be
+         * included in the operation.
+         * @param granularity {@link HandwritingGesture#GRANULARITY_WORD} or
+         * {@link HandwritingGesture#GRANULARITY_CHARACTER}.
+         * @return {@link Builder}.
+         */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setGranularity(@HandwritingGesture.Granularity int granularity) {
+            mGranularity = granularity;
+            return this;
+        }
+
+        /**
+         * Set rectangular single/multiline start of text selection area intersecting with text.
+         *
+         * The resulting selection is performed from the start of first word/character in the start
+         * rectangle to the end of the last word/character in the end rectangle
+         * {@link #setSelectionEndArea(RectF)}.
+         * <br/>
+         * <img src="{@docRoot}reference/android/images/input_method/stylus_handwriting
+         * /select_range_gesture_rects.png"
+         * height="300" alt="Selection strategy using two rectangles"/>
+         *  <br/>
+         *
+         * Intersection is determined using
+         * {@link #setGranularity(int)}. e.g. {@link HandwritingGesture#GRANULARITY_WORD} includes
+         * all the words with their width/height center included in the selection rectangle.
+         * @param startArea {@link RectF} (in screen coordinates) for start of selection. This
+         * rectangle belongs to first line where selection should start.
+         */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setSelectionStartArea(@NonNull RectF startArea) {
+            mStartArea = startArea;
+            return this;
+        }
+
+        /**
+         * Set rectangular single/multiline end of text selection area intersecting with text.
+         *
+         * The resulting selection is performed from the start of first word/character in the start
+         * rectangle {@link #setSelectionStartArea(RectF)} to the end of the last word/character in
+         * the end rectangle.
+         * <br/>
+         * <img src="{@docRoot}reference/android/images/input_method/stylus_handwriting
+         * /select_range_gesture_rects.png"
+         * height="300" alt="Selection strategy using two rectangles"/>
+         *  <br/>
+         *
+         * The selection includes the first word/character in the rectangle, the last
+         * word/character in the rectangle, and everything in between even if it's not in the
+         * rectangle.
+         *
+         * Intersection is determined using
+         * {@link #setGranularity(int)}. e.g. {@link HandwritingGesture#GRANULARITY_WORD} includes
+         * all the words with their width/height center included in the selection rectangle.
+         * @param endArea {@link RectF} (in screen coordinates) for start of selection. This
+         * rectangle belongs to the last line where selection should end.
+         */
+        @NonNull
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setSelectionEndArea(@NonNull RectF endArea) {
+            mEndArea = endArea;
+            return this;
+        }
+
+        /**
+         * Set fallback text that will be committed at current cursor position if there is no
+         * applicable text beneath the area of gesture.
+         * @param fallbackText text to set
+         */
+        @NonNull
+        public Builder setFallbackText(@Nullable String fallbackText) {
+            mFallbackText = fallbackText;
+            return this;
+        }
+
+        /**
+         * @return {@link SelectRangeGesture} using parameters in this
+         * {@link SelectRangeGesture.Builder}.
+         * @throws IllegalArgumentException if one or more positional parameters are not specified.
+         */
+        @NonNull
+        public SelectRangeGesture build() {
+            if (mStartArea == null || mStartArea.isEmpty() || mEndArea == null
+                    || mEndArea.isEmpty()) {
+                throw new IllegalArgumentException("Selection area must be set.");
+            }
+            if (mGranularity <= GRANULARITY_UNDEFINED) {
+                throw new IllegalArgumentException("Selection granularity must be set.");
+            }
+            return new SelectRangeGesture(mGranularity, mStartArea, mEndArea, mFallbackText);
+        }
+    }
+
+    /**
+     * Used to make this class parcelable.
+     */
+    @NonNull
+    public static final Parcelable.Creator<SelectRangeGesture> CREATOR =
+            new Parcelable.Creator<SelectRangeGesture>() {
+                @Override
+                public SelectRangeGesture createFromParcel(Parcel source) {
+                    return new SelectRangeGesture(source);
+                }
+
+                @Override
+                public SelectRangeGesture[] newArray(int size) {
+                    return new SelectRangeGesture[size];
+                }
+            };
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mGranularity, mStartArea, mEndArea, mFallbackText);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof SelectRangeGesture)) return false;
+
+        SelectRangeGesture that = (SelectRangeGesture) o;
+
+        if (mGranularity != that.mGranularity) return false;
+        if (!Objects.equals(mFallbackText, that.mFallbackText)) return false;
+        if (!Objects.equals(mStartArea, that.mStartArea)) return false;
+        return Objects.equals(mEndArea, that.mEndArea);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Used to package this object into a {@link Parcel}.
+     *
+     * @param dest The {@link Parcel} to be written.
+     * @param flags The flags used for parceling.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString8(mFallbackText);
+        dest.writeInt(mGranularity);
+        dest.writeTypedObject(mStartArea, flags);
+        dest.writeTypedObject(mEndArea, flags);
+    }
+}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index cebaa76..424b8ae 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -2875,6 +2875,17 @@
         }
     }
 
+    /**
+     *
+     * @return whether the Blink runnable is blinking or not, if null return false.
+     * @hide
+     */
+    @VisibleForTesting
+    public boolean isBlinking() {
+        if (mBlink == null) return false;
+        return !mBlink.mCancelled;
+    }
+
     private class Blink implements Runnable {
         private boolean mCancelled;
 
@@ -4583,7 +4594,6 @@
      */
     private final class CursorAnchorInfoNotifier implements TextViewPositionListener {
         final CursorAnchorInfo.Builder mSelectionInfoBuilder = new CursorAnchorInfo.Builder();
-        final int[] mTmpIntOffset = new int[2];
         final Matrix mViewToScreenMatrix = new Matrix();
 
         @Override
@@ -4635,9 +4645,8 @@
             builder.setSelectionRange(selectionStart, mTextView.getSelectionEnd());
 
             // Construct transformation matrix from view local coordinates to screen coordinates.
-            mViewToScreenMatrix.set(mTextView.getMatrix());
-            mTextView.getLocationOnScreen(mTmpIntOffset);
-            mViewToScreenMatrix.postTranslate(mTmpIntOffset[0], mTmpIntOffset[1]);
+            mViewToScreenMatrix.reset();
+            mTextView.transformMatrixToGlobal(mViewToScreenMatrix);
             builder.setMatrix(mViewToScreenMatrix);
 
             if (includeEditorBounds) {
diff --git a/core/java/android/window/ScreenCapture.aidl b/core/java/android/window/ScreenCapture.aidl
new file mode 100644
index 0000000..267a7c6
--- /dev/null
+++ b/core/java/android/window/ScreenCapture.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+/** @hide */
+parcelable ScreenCapture.CaptureArgs;
+
+/** @hide */
+parcelable ScreenCapture.ScreenshotHardwareBuffer;
+
+/** @hide */
+parcelable ScreenCapture.ScreenCaptureListener;
\ No newline at end of file
diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java
new file mode 100644
index 0000000..b8f39a9
--- /dev/null
+++ b/core/java/android/window/ScreenCapture.java
@@ -0,0 +1,707 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.view.SurfaceControl;
+
+import libcore.util.NativeAllocationRegistry;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * Handles display and layer captures for the system.
+ *
+ * @hide
+ */
+public class ScreenCapture {
+    private static final String TAG = "ScreenCapture";
+
+    private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs,
+            long captureListener);
+    private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs,
+            long captureListener);
+    private static native long nativeCreateScreenCaptureListener(
+            Consumer<ScreenshotHardwareBuffer> consumer);
+    private static native void nativeWriteListenerToParcel(long nativeObject, Parcel out);
+    private static native long nativeReadListenerFromParcel(Parcel in);
+    private static native long getNativeListenerFinalizer();
+
+    /**
+     * @param captureArgs     Arguments about how to take the screenshot
+     * @param captureListener A listener to receive the screenshot callback
+     * @hide
+     */
+    public static int captureDisplay(@NonNull DisplayCaptureArgs captureArgs,
+            @NonNull ScreenCaptureListener captureListener) {
+        return nativeCaptureDisplay(captureArgs, captureListener.mNativeObject);
+    }
+
+    /**
+     * Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with
+     * the content.
+     *
+     * @hide
+     */
+    public static ScreenshotHardwareBuffer captureDisplay(
+            DisplayCaptureArgs captureArgs) {
+        SyncScreenCaptureListener screenCaptureListener = new SyncScreenCaptureListener();
+        int status = captureDisplay(captureArgs, screenCaptureListener.getScreenCaptureListener());
+        if (status != 0) {
+            return null;
+        }
+
+        return screenCaptureListener.waitForScreenshot();
+    }
+
+    /**
+     * Captures a layer and its children and returns a {@link HardwareBuffer} with the content.
+     *
+     * @param layer      The root layer to capture.
+     * @param sourceCrop The portion of the root surface to capture; caller may pass in 'new
+     *                   Rect()' or null if no cropping is desired. If the root layer does not
+     *                   have a buffer or a crop set, then a non-empty source crop must be
+     *                   specified.
+     * @param frameScale The desired scale of the returned buffer; the raw screen will be scaled
+     *                   up/down.
+     * @return Returns a HardwareBuffer that contains the layer capture.
+     * @hide
+     */
+    public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
+            float frameScale) {
+        return captureLayers(layer, sourceCrop, frameScale, PixelFormat.RGBA_8888);
+    }
+
+    /**
+     * Captures a layer and its children and returns a {@link HardwareBuffer} with the content.
+     *
+     * @param layer      The root layer to capture.
+     * @param sourceCrop The portion of the root surface to capture; caller may pass in 'new
+     *                   Rect()' or null if no cropping is desired. If the root layer does not
+     *                   have a buffer or a crop set, then a non-empty source crop must be
+     *                   specified.
+     * @param frameScale The desired scale of the returned buffer; the raw screen will be scaled
+     *                   up/down.
+     * @param format     The desired pixel format of the returned buffer.
+     * @return Returns a HardwareBuffer that contains the layer capture.
+     * @hide
+     */
+    public static ScreenshotHardwareBuffer captureLayers(@NonNull SurfaceControl layer,
+            @Nullable Rect sourceCrop, float frameScale, int format) {
+        LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer)
+                .setSourceCrop(sourceCrop)
+                .setFrameScale(frameScale)
+                .setPixelFormat(format)
+                .build();
+
+        return captureLayers(captureArgs);
+    }
+
+    /**
+     * @hide
+     */
+    public static ScreenshotHardwareBuffer captureLayers(
+            LayerCaptureArgs captureArgs) {
+        SyncScreenCaptureListener screenCaptureListener = new SyncScreenCaptureListener();
+
+        int status = captureLayers(captureArgs, screenCaptureListener.getScreenCaptureListener());
+        if (status != 0) {
+            return null;
+        }
+
+        return screenCaptureListener.waitForScreenshot();
+    }
+
+    /**
+     * Like {@link #captureLayers(SurfaceControl, Rect, float, int)} but with an array of layer
+     * handles to exclude.
+     *
+     * @hide
+     */
+    public static ScreenshotHardwareBuffer captureLayersExcluding(SurfaceControl layer,
+            Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) {
+        LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer)
+                .setSourceCrop(sourceCrop)
+                .setFrameScale(frameScale)
+                .setPixelFormat(format)
+                .setExcludeLayers(exclude)
+                .build();
+
+        return captureLayers(captureArgs);
+    }
+
+    /**
+     * @param captureArgs     Arguments about how to take the screenshot
+     * @param captureListener A listener to receive the screenshot callback
+     * @hide
+     */
+    public static int captureLayers(@NonNull LayerCaptureArgs captureArgs,
+            @NonNull ScreenCaptureListener captureListener) {
+        return nativeCaptureLayers(captureArgs, captureListener.mNativeObject);
+    }
+
+    /**
+     * A wrapper around HardwareBuffer that contains extra information about how to
+     * interpret the screenshot HardwareBuffer.
+     *
+     * @hide
+     */
+    public static class ScreenshotHardwareBuffer {
+        private final HardwareBuffer mHardwareBuffer;
+        private final ColorSpace mColorSpace;
+        private final boolean mContainsSecureLayers;
+        private final boolean mContainsHdrLayers;
+
+        public ScreenshotHardwareBuffer(HardwareBuffer hardwareBuffer, ColorSpace colorSpace,
+                boolean containsSecureLayers, boolean containsHdrLayers) {
+            mHardwareBuffer = hardwareBuffer;
+            mColorSpace = colorSpace;
+            mContainsSecureLayers = containsSecureLayers;
+            mContainsHdrLayers = containsHdrLayers;
+        }
+
+        /**
+         * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object.
+         *
+         * @param hardwareBuffer       The existing HardwareBuffer object
+         * @param namedColorSpace      Integer value of a named color space {@link ColorSpace.Named}
+         * @param containsSecureLayers Indicates whether this graphic buffer contains captured
+         *                             contents of secure layers, in which case the screenshot
+         *                             should not be persisted.
+         * @param containsHdrLayers    Indicates whether this graphic buffer contains HDR content.
+         */
+        private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
+                int namedColorSpace, boolean containsSecureLayers, boolean containsHdrLayers) {
+            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
+            return new ScreenshotHardwareBuffer(
+                    hardwareBuffer, colorSpace, containsSecureLayers, containsHdrLayers);
+        }
+
+        public ColorSpace getColorSpace() {
+            return mColorSpace;
+        }
+
+        public HardwareBuffer getHardwareBuffer() {
+            return mHardwareBuffer;
+        }
+
+        /**
+         * Whether this screenshot contains secure layers
+         */
+        public boolean containsSecureLayers() {
+            return mContainsSecureLayers;
+        }
+
+        /**
+         * Returns whether the screenshot contains at least one HDR layer.
+         * This information may be useful for informing the display whether this screenshot
+         * is allowed to be dimmed to SDR white.
+         */
+        public boolean containsHdrLayers() {
+            return mContainsHdrLayers;
+        }
+
+        /**
+         * Copy content of ScreenshotHardwareBuffer into a hardware bitmap and return it.
+         * Note: If you want to modify the Bitmap in software, you will need to copy the Bitmap
+         * into
+         * a software Bitmap using {@link Bitmap#copy(Bitmap.Config, boolean)}
+         * <p>
+         * CAVEAT: This can be extremely slow; avoid use unless absolutely necessary; prefer to
+         * directly
+         * use the {@link HardwareBuffer} directly.
+         *
+         * @return Bitmap generated from the {@link HardwareBuffer}
+         */
+        public Bitmap asBitmap() {
+            if (mHardwareBuffer == null) {
+                Log.w(TAG, "Failed to take screenshot. Null screenshot object");
+                return null;
+            }
+            return Bitmap.wrapHardwareBuffer(mHardwareBuffer, mColorSpace);
+        }
+    }
+
+    /**
+     * A common arguments class used for various screenshot requests. This contains arguments that
+     * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs}
+     *
+     * @hide
+     */
+    public static class CaptureArgs implements Parcelable {
+        public final int mPixelFormat;
+        public final Rect mSourceCrop = new Rect();
+        public final float mFrameScaleX;
+        public final float mFrameScaleY;
+        public final boolean mCaptureSecureLayers;
+        public final boolean mAllowProtected;
+        public final long mUid;
+        public final boolean mGrayscale;
+
+        private CaptureArgs(CaptureArgs.Builder<? extends CaptureArgs.Builder<?>> builder) {
+            mPixelFormat = builder.mPixelFormat;
+            mSourceCrop.set(builder.mSourceCrop);
+            mFrameScaleX = builder.mFrameScaleX;
+            mFrameScaleY = builder.mFrameScaleY;
+            mCaptureSecureLayers = builder.mCaptureSecureLayers;
+            mAllowProtected = builder.mAllowProtected;
+            mUid = builder.mUid;
+            mGrayscale = builder.mGrayscale;
+        }
+
+        private CaptureArgs(Parcel in) {
+            mPixelFormat = in.readInt();
+            mSourceCrop.readFromParcel(in);
+            mFrameScaleX = in.readFloat();
+            mFrameScaleY = in.readFloat();
+            mCaptureSecureLayers = in.readBoolean();
+            mAllowProtected = in.readBoolean();
+            mUid = in.readLong();
+            mGrayscale = in.readBoolean();
+        }
+
+        /**
+         * The Builder class used to construct {@link CaptureArgs}
+         *
+         * @param <T> A builder that extends {@link CaptureArgs.Builder}
+         */
+        public static class Builder<T extends CaptureArgs.Builder<T>> {
+            private int mPixelFormat = PixelFormat.RGBA_8888;
+            private final Rect mSourceCrop = new Rect();
+            private float mFrameScaleX = 1;
+            private float mFrameScaleY = 1;
+            private boolean mCaptureSecureLayers;
+            private boolean mAllowProtected;
+            private long mUid = -1;
+            private boolean mGrayscale;
+
+            /**
+             * Construct a new {@link CaptureArgs} with the set parameters. The builder remains
+             * valid.
+             */
+            public CaptureArgs build() {
+                return new CaptureArgs(this);
+            }
+
+            /**
+             * The desired pixel format of the returned buffer.
+             */
+            public T setPixelFormat(int pixelFormat) {
+                mPixelFormat = pixelFormat;
+                return getThis();
+            }
+
+            /**
+             * The portion of the screen to capture into the buffer. Caller may pass  in
+             * 'new Rect()' or null if no cropping is desired.
+             */
+            public T setSourceCrop(@Nullable Rect sourceCrop) {
+                if (sourceCrop == null) {
+                    mSourceCrop.setEmpty();
+                } else {
+                    mSourceCrop.set(sourceCrop);
+                }
+                return getThis();
+            }
+
+            /**
+             * The desired scale of the returned buffer. The raw screen will be scaled up/down.
+             */
+            public T setFrameScale(float frameScale) {
+                mFrameScaleX = frameScale;
+                mFrameScaleY = frameScale;
+                return getThis();
+            }
+
+            /**
+             * The desired scale of the returned buffer, allowing separate values for x and y scale.
+             * The raw screen will be scaled up/down.
+             */
+            public T setFrameScale(float frameScaleX, float frameScaleY) {
+                mFrameScaleX = frameScaleX;
+                mFrameScaleY = frameScaleY;
+                return getThis();
+            }
+
+            /**
+             * Whether to allow the screenshot of secure layers. Warning: This should only be done
+             * if the content will be placed in a secure SurfaceControl.
+             *
+             * @see ScreenshotHardwareBuffer#containsSecureLayers()
+             */
+            public T setCaptureSecureLayers(boolean captureSecureLayers) {
+                mCaptureSecureLayers = captureSecureLayers;
+                return getThis();
+            }
+
+            /**
+             * Whether to allow the screenshot of protected (DRM) content. Warning: The screenshot
+             * cannot be read in unprotected space.
+             *
+             * @see HardwareBuffer#USAGE_PROTECTED_CONTENT
+             */
+            public T setAllowProtected(boolean allowProtected) {
+                mAllowProtected = allowProtected;
+                return getThis();
+            }
+
+            /**
+             * Set the uid of the content that should be screenshot. The code will skip any surfaces
+             * that don't belong to the specified uid.
+             */
+            public T setUid(long uid) {
+                mUid = uid;
+                return getThis();
+            }
+
+            /**
+             * Set whether the screenshot should use grayscale or not.
+             */
+            public T setGrayscale(boolean grayscale) {
+                mGrayscale = grayscale;
+                return getThis();
+            }
+
+            /**
+             * Each sub class should return itself to allow the builder to chain properly
+             */
+            T getThis() {
+                return (T) this;
+            }
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeInt(mPixelFormat);
+            mSourceCrop.writeToParcel(dest, flags);
+            dest.writeFloat(mFrameScaleX);
+            dest.writeFloat(mFrameScaleY);
+            dest.writeBoolean(mCaptureSecureLayers);
+            dest.writeBoolean(mAllowProtected);
+            dest.writeLong(mUid);
+            dest.writeBoolean(mGrayscale);
+        }
+
+        public static final Parcelable.Creator<CaptureArgs> CREATOR =
+                new Parcelable.Creator<CaptureArgs>() {
+                    @Override
+                    public CaptureArgs createFromParcel(Parcel in) {
+                        return new CaptureArgs(in);
+                    }
+
+                    @Override
+                    public CaptureArgs[] newArray(int size) {
+                        return new CaptureArgs[size];
+                    }
+                };
+    }
+
+    /**
+     * 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
+     * @see #nativeCaptureLayers(LayerCaptureArgs, long)
+     */
+    public static class LayerCaptureArgs extends CaptureArgs {
+        private final long mNativeLayer;
+        private final long[] mNativeExcludeLayers;
+        private final boolean mChildrenOnly;
+
+        private LayerCaptureArgs(Builder builder) {
+            super(builder);
+            mChildrenOnly = builder.mChildrenOnly;
+            mNativeLayer = builder.mLayer.mNativeObject;
+            if (builder.mExcludeLayers != null) {
+                mNativeExcludeLayers = new long[builder.mExcludeLayers.length];
+                for (int i = 0; i < builder.mExcludeLayers.length; i++) {
+                    mNativeExcludeLayers[i] = builder.mExcludeLayers[i].mNativeObject;
+                }
+            } else {
+                mNativeExcludeLayers = null;
+            }
+        }
+
+        /**
+         * The Builder class used to construct {@link LayerCaptureArgs}
+         */
+        public static class Builder extends CaptureArgs.Builder<Builder> {
+            private SurfaceControl mLayer;
+            private SurfaceControl[] mExcludeLayers;
+            private boolean mChildrenOnly = true;
+
+            /**
+             * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder
+             * remains valid.
+             */
+            public LayerCaptureArgs build() {
+                if (mLayer == null) {
+                    throw new IllegalStateException(
+                            "Can't take screenshot with null layer");
+                }
+                return new LayerCaptureArgs(this);
+            }
+
+            public Builder(SurfaceControl layer, CaptureArgs args) {
+                setLayer(layer);
+                setPixelFormat(args.mPixelFormat);
+                setSourceCrop(args.mSourceCrop);
+                setFrameScale(args.mFrameScaleX, args.mFrameScaleY);
+                setCaptureSecureLayers(args.mCaptureSecureLayers);
+                setAllowProtected(args.mAllowProtected);
+                setUid(args.mUid);
+                setGrayscale(args.mGrayscale);
+            }
+
+            public Builder(SurfaceControl layer) {
+                setLayer(layer);
+            }
+
+            /**
+             * The root layer to capture.
+             */
+            public Builder setLayer(SurfaceControl layer) {
+                mLayer = layer;
+                return this;
+            }
+
+            /**
+             * An array of layer handles to exclude.
+             */
+            public Builder setExcludeLayers(@Nullable SurfaceControl[] excludeLayers) {
+                mExcludeLayers = excludeLayers;
+                return this;
+            }
+
+            /**
+             * Whether to include the layer itself in the screenshot or just the children and their
+             * descendants.
+             */
+            public Builder setChildrenOnly(boolean childrenOnly) {
+                mChildrenOnly = childrenOnly;
+                return this;
+            }
+
+            @Override
+            Builder getThis() {
+                return this;
+            }
+        }
+    }
+
+    /**
+     * The object used to receive the results when invoking screen capture requests via
+     * {@link #captureDisplay(DisplayCaptureArgs, ScreenCaptureListener)} or
+     * {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)}
+     */
+    public static class ScreenCaptureListener implements Parcelable {
+        private final long mNativeObject;
+        private static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                        ScreenCaptureListener.class.getClassLoader(), getNativeListenerFinalizer());
+
+        /**
+         * @param consumer The callback invoked when the screen capture is complete.
+         */
+        public ScreenCaptureListener(Consumer<ScreenshotHardwareBuffer> consumer) {
+            mNativeObject = nativeCreateScreenCaptureListener(consumer);
+            sRegistry.registerNativeAllocation(this, mNativeObject);
+        }
+
+        private ScreenCaptureListener(Parcel in) {
+            if (in.readBoolean()) {
+                mNativeObject = nativeReadListenerFromParcel(in);
+                sRegistry.registerNativeAllocation(this, mNativeObject);
+            } else {
+                mNativeObject = 0;
+            }
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            if (mNativeObject == 0) {
+                dest.writeBoolean(false);
+            } else {
+                dest.writeBoolean(true);
+                nativeWriteListenerToParcel(mNativeObject, dest);
+            }
+        }
+
+        public static final Parcelable.Creator<ScreenCaptureListener> CREATOR =
+                new Parcelable.Creator<ScreenCaptureListener>() {
+                    @Override
+                    public ScreenCaptureListener createFromParcel(Parcel in) {
+                        return new ScreenCaptureListener(in);
+                    }
+
+                    @Override
+                    public ScreenCaptureListener[] newArray(int size) {
+                        return new ScreenCaptureListener[0];
+                    }
+                };
+    }
+
+    /**
+     * A helper class to handle the async screencapture callbacks synchronously. This should only
+     * be used if the screencapture caller doesn't care that it blocks waiting for a screenshot.
+     */
+    public static class SyncScreenCaptureListener {
+        private static final int SCREENSHOT_WAIT_TIME_S = 1;
+        private ScreenshotHardwareBuffer mScreenshotHardwareBuffer;
+        private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
+        private final ScreenCaptureListener mScreenCaptureListener;
+
+        public SyncScreenCaptureListener() {
+            mScreenCaptureListener = new ScreenCaptureListener(screenshotHardwareBuffer -> {
+                mScreenshotHardwareBuffer = screenshotHardwareBuffer;
+                mCountDownLatch.countDown();
+            });
+        }
+
+        /**
+         * @return The underlying {@link ScreenCaptureListener}
+         */
+        public ScreenCaptureListener getScreenCaptureListener() {
+            return mScreenCaptureListener;
+        }
+
+        /**
+         * Waits until the screenshot callback has been invoked and the screenshot is ready. This
+         * can return {@code null} if the screenshot callback wasn't invoked after
+         * {@link #SCREENSHOT_WAIT_TIME_S} or the screencapture request resulted in an error
+         *
+         * @return A ScreenshotHardwareBuffer for the content that was captured.
+         */
+        @Nullable
+        public ScreenshotHardwareBuffer waitForScreenshot() {
+            try {
+                mCountDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
+            } catch (Exception e) {
+                Log.e(TAG, "Failed to wait for screen capture result", e);
+            }
+
+            return mScreenshotHardwareBuffer;
+        }
+    }
+}
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 8ca763e..33ea2e4 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -110,11 +110,11 @@
     /** The container is an input-method window. */
     public static final int FLAG_IS_INPUT_METHOD = 1 << 8;
 
-    /** The container is ActivityEmbedding embedded. */
-    public static final int FLAG_IS_EMBEDDED = 1 << 9;
+    /** The container is in a Task with embedded activity. */
+    public static final int FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY = 1 << 9;
 
-    /** The first unused bit. This can be used by remotes to attach custom flags to this change. */
-    public static final int FLAG_FIRST_CUSTOM = 1 << 10;
+    /** The container fills its parent Task before and after the transition. */
+    public static final int FLAG_FILLS_TASK = 1 << 10;
 
     /** The container is going to show IME on its task after the transition. */
     public static final int FLAG_WILL_IME_SHOWN = 1 << 11;
@@ -125,6 +125,9 @@
     /** The container attaches work profile thumbnail for cross profile animation. */
     public static final int FLAG_CROSS_PROFILE_WORK_THUMBNAIL = 1 << 13;
 
+    /** The first unused bit. This can be used by remotes to attach custom flags to this change. */
+    public static final int FLAG_FIRST_CUSTOM = 1 << 14;
+
     /** @hide */
     @IntDef(prefix = { "FLAG_" }, value = {
             FLAG_NONE,
@@ -137,9 +140,12 @@
             FLAG_OCCLUDES_KEYGUARD,
             FLAG_DISPLAY_HAS_ALERT_WINDOWS,
             FLAG_IS_INPUT_METHOD,
-            FLAG_IS_EMBEDDED,
-            FLAG_FIRST_CUSTOM,
-            FLAG_WILL_IME_SHOWN
+            FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY,
+            FLAG_FILLS_TASK,
+            FLAG_WILL_IME_SHOWN,
+            FLAG_CROSS_PROFILE_OWNER_THUMBNAIL,
+            FLAG_CROSS_PROFILE_WORK_THUMBNAIL,
+            FLAG_FIRST_CUSTOM
     })
     public @interface ChangeFlags {}
 
@@ -322,28 +328,31 @@
             sb.append("IS_INPUT_METHOD");
         }
         if ((flags & FLAG_TRANSLUCENT) != 0) {
-            sb.append((sb.length() == 0 ? "" : "|") + "TRANSLUCENT");
+            sb.append(sb.length() == 0 ? "" : "|").append("TRANSLUCENT");
         }
         if ((flags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) {
-            sb.append((sb.length() == 0 ? "" : "|") + "STARTING_WINDOW_TRANSFER");
+            sb.append(sb.length() == 0 ? "" : "|").append("STARTING_WINDOW_TRANSFER");
         }
         if ((flags & FLAG_IS_VOICE_INTERACTION) != 0) {
-            sb.append((sb.length() == 0 ? "" : "|") + "IS_VOICE_INTERACTION");
+            sb.append(sb.length() == 0 ? "" : "|").append("IS_VOICE_INTERACTION");
         }
         if ((flags & FLAG_IS_DISPLAY) != 0) {
-            sb.append((sb.length() == 0 ? "" : "|") + "IS_DISPLAY");
+            sb.append(sb.length() == 0 ? "" : "|").append("IS_DISPLAY");
         }
         if ((flags & FLAG_OCCLUDES_KEYGUARD) != 0) {
-            sb.append((sb.length() == 0 ? "" : "|") + "OCCLUDES_KEYGUARD");
+            sb.append(sb.length() == 0 ? "" : "|").append("OCCLUDES_KEYGUARD");
         }
         if ((flags & FLAG_DISPLAY_HAS_ALERT_WINDOWS) != 0) {
-            sb.append((sb.length() == 0 ? "" : "|") + "DISPLAY_HAS_ALERT_WINDOWS");
+            sb.append(sb.length() == 0 ? "" : "|").append("DISPLAY_HAS_ALERT_WINDOWS");
         }
-        if ((flags & FLAG_IS_EMBEDDED) != 0) {
-            sb.append((sb.length() == 0 ? "" : "|") + "IS_EMBEDDED");
+        if ((flags & FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY) != 0) {
+            sb.append(sb.length() == 0 ? "" : "|").append("IN_TASK_WITH_EMBEDDED_ACTIVITY");
+        }
+        if ((flags & FLAG_FILLS_TASK) != 0) {
+            sb.append(sb.length() == 0 ? "" : "|").append("FILLS_TASK");
         }
         if ((flags & FLAG_FIRST_CUSTOM) != 0) {
-            sb.append((sb.length() == 0 ? "" : "|") + "FIRST_CUSTOM");
+            sb.append(sb.length() == 0 ? "" : "|").append("FIRST_CUSTOM");
         }
         return sb.toString();
     }
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 83bf801..8d51c9c 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -270,7 +270,6 @@
      */
     void shutdownHotwordDetectionService();
 
-    @EnforcePermission(allOf={"RECORD_AUDIO", "CAPTURE_AUDIO_HOTWORD"})
     void startListeningFromMic(
         in AudioFormat audioFormat,
         in IMicrophoneHotwordDetectionVoiceInteractionCallback callback);
@@ -286,7 +285,6 @@
     /**
      * Test API to simulate to trigger hardware recognition event for test.
      */
-    @EnforcePermission(allOf={"RECORD_AUDIO", "CAPTURE_AUDIO_HOTWORD"})
     void triggerHardwareRecognitionEventForTest(
             in SoundTrigger.KeyphraseRecognitionEvent event,
             in IHotwordRecognitionStatusCallback callback);
diff --git a/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl b/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
index f456e85..17f9b7d 100644
--- a/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
+++ b/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
@@ -22,12 +22,14 @@
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.CorrectionInfo;
 import android.view.inputmethod.DeleteGesture;
+import android.view.inputmethod.DeleteRangeGesture;
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.InputContentInfo;
 import android.view.inputmethod.InsertGesture;
 import android.view.inputmethod.JoinOrSplitGesture;
 import android.view.inputmethod.RemoveSpaceGesture;
 import android.view.inputmethod.SelectGesture;
+import android.view.inputmethod.SelectRangeGesture;
 import android.view.inputmethod.TextAttribute;
 
 import com.android.internal.infra.AndroidFuture;
@@ -95,12 +97,18 @@
     void performHandwritingSelectGesture(in InputConnectionCommandHeader header,
             in SelectGesture gesture, in ResultReceiver resultReceiver);
 
+    void performHandwritingSelectRangeGesture(in InputConnectionCommandHeader header,
+            in SelectRangeGesture gesture, in ResultReceiver resultReceiver);
+
     void performHandwritingInsertGesture(in InputConnectionCommandHeader header,
             in InsertGesture gesture, in ResultReceiver resultReceiver);
 
     void performHandwritingDeleteGesture(in InputConnectionCommandHeader header,
             in DeleteGesture gesture, in ResultReceiver resultReceiver);
 
+    void performHandwritingDeleteRangeGesture(in InputConnectionCommandHeader header,
+                in DeleteRangeGesture gesture, in ResultReceiver resultReceiver);
+
     void performHandwritingRemoveSpaceGesture(in InputConnectionCommandHeader header,
             in RemoveSpaceGesture gesture, in ResultReceiver resultReceiver);
 
diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
index bbf0a76..7f3144b 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
@@ -272,19 +272,24 @@
         if ((gestureTypeFlags & HandwritingGesture.GESTURE_TYPE_SELECT) != 0) {
             joiner.add("SELECT");
         }
+        if ((gestureTypeFlags & HandwritingGesture.GESTURE_TYPE_SELECT_RANGE) != 0) {
+            joiner.add("SELECT_RANGE");
+        }
         if ((gestureTypeFlags & HandwritingGesture.GESTURE_TYPE_INSERT) != 0) {
             joiner.add("INSERT");
         }
         if ((gestureTypeFlags & HandwritingGesture.GESTURE_TYPE_DELETE) != 0) {
             joiner.add("DELETE");
         }
+        if ((gestureTypeFlags & HandwritingGesture.GESTURE_TYPE_DELETE_RANGE) != 0) {
+            joiner.add("DELETE_RANGE");
+        }
         if ((gestureTypeFlags & HandwritingGesture.GESTURE_TYPE_REMOVE_SPACE) != 0) {
             joiner.add("REMOVE_SPACE");
         }
         if ((gestureTypeFlags & HandwritingGesture.GESTURE_TYPE_JOIN_OR_SPLIT) != 0) {
             joiner.add("JOIN_OR_SPLIT");
         }
-
         return joiner.setEmptyValue("(none)").toString();
     }
 
diff --git a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
index 6a7028d..713e913 100644
--- a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
+++ b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
@@ -41,6 +41,7 @@
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.CorrectionInfo;
 import android.view.inputmethod.DeleteGesture;
+import android.view.inputmethod.DeleteRangeGesture;
 import android.view.inputmethod.DumpableInputConnection;
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.HandwritingGesture;
@@ -51,6 +52,7 @@
 import android.view.inputmethod.JoinOrSplitGesture;
 import android.view.inputmethod.RemoveSpaceGesture;
 import android.view.inputmethod.SelectGesture;
+import android.view.inputmethod.SelectRangeGesture;
 import android.view.inputmethod.TextAttribute;
 import android.view.inputmethod.TextSnapshot;
 
@@ -985,6 +987,14 @@
 
     @Dispatching(cancellable = true)
     @Override
+    public void performHandwritingSelectRangeGesture(
+            InputConnectionCommandHeader header, SelectRangeGesture gesture,
+            ResultReceiver resultReceiver) {
+        performHandwritingGestureInternal(header, gesture, resultReceiver);
+    }
+
+    @Dispatching(cancellable = true)
+    @Override
     public void performHandwritingInsertGesture(
             InputConnectionCommandHeader header, InsertGesture gesture,
             ResultReceiver resultReceiver) {
@@ -1001,6 +1011,14 @@
 
     @Dispatching(cancellable = true)
     @Override
+    public void performHandwritingDeleteRangeGesture(
+            InputConnectionCommandHeader header, DeleteRangeGesture gesture,
+            ResultReceiver resultReceiver) {
+        performHandwritingGestureInternal(header, gesture, resultReceiver);
+    }
+
+    @Dispatching(cancellable = true)
+    @Override
     public void performHandwritingRemoveSpaceGesture(
             InputConnectionCommandHeader header, RemoveSpaceGesture gesture,
             ResultReceiver resultReceiver) {
diff --git a/core/java/com/android/internal/jank/TEST_MAPPING b/core/java/com/android/internal/jank/TEST_MAPPING
new file mode 100644
index 0000000..4e00ff1
--- /dev/null
+++ b/core/java/com/android/internal/jank/TEST_MAPPING
@@ -0,0 +1,22 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "com.android.internal.jank"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ],
+      "file_patterns": [
+        "core/java/com/android/internal/jank/.*",
+        "core/tests/coretests/src/com/android/internal/jank/.*"
+      ]
+    }
+  ]
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index f097bf7..5523344 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -247,6 +247,13 @@
                 SystemProperties.set("debug.tracing." + name, Integer.toString(value));
             }
         }
+
+        /**
+         * Records an instant event (one with no duration).
+         */
+        public void traceInstantEvent(@NonNull String track, @NonNull String name) {
+            Trace.instantForTrack(Trace.TRACE_TAG_POWER, track, name);
+        }
     }
 
     private TraceDelegate mTracer;
@@ -1165,6 +1172,25 @@
     }
 
     /**
+     * Writes event details into Atrace.
+     */
+    private void recordTraceEvents(int code, HistoryTag tag) {
+        if (code == HistoryItem.EVENT_NONE) return;
+        if (!mTracer.tracingEnabled()) return;
+
+        final int idx = code & HistoryItem.EVENT_TYPE_MASK;
+        final String prefix = (code & HistoryItem.EVENT_FLAG_START) != 0 ? "+" :
+                  (code & HistoryItem.EVENT_FLAG_FINISH) != 0 ? "-" : "";
+
+        final String[] names = BatteryStats.HISTORY_EVENT_NAMES;
+        if (idx < 0 || idx >= names.length) return;
+
+        final String track = "battery_stats." + names[idx];
+        final String name = prefix + names[idx] + "=" + tag.uid + ":\"" + tag.string + "\"";
+        mTracer.traceInstantEvent(track, name);
+    }
+
+    /**
      * Writes changes to a HistoryItem state bitmap to Atrace.
      */
     private void recordTraceCounters(int oldval, int newval, BitDescription[] descriptions) {
@@ -1229,6 +1255,7 @@
                     + Integer.toHexString(lastDiffStates2));
         }
 
+        recordTraceEvents(cur.eventCode, cur.eventTag);
         recordTraceCounters(mHistoryLastWritten.states,
                 cur.states & mActiveHistoryStates, BatteryStats.HISTORY_STATE_DESCRIPTIONS);
         recordTraceCounters(mHistoryLastWritten.states2,
diff --git a/core/java/com/android/internal/os/TimeoutRecord.java b/core/java/com/android/internal/os/TimeoutRecord.java
index a8885f9..be3f172 100644
--- a/core/java/com/android/internal/os/TimeoutRecord.java
+++ b/core/java/com/android/internal/os/TimeoutRecord.java
@@ -20,6 +20,8 @@
 import android.annotation.NonNull;
 import android.os.SystemClock;
 
+import com.android.internal.os.anr.AnrLatencyTracker;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -40,7 +42,7 @@
             TimeoutKind.APP_REGISTERED})
 
     @Retention(RetentionPolicy.SOURCE)
-    private @interface TimeoutKind {
+    public @interface TimeoutKind {
         int INPUT_DISPATCH_NO_FOCUSED_WINDOW = 1;
         int INPUT_DISPATCH_WINDOW_UNRESPONSIVE = 2;
         int BROADCAST_RECEIVER = 3;
@@ -66,12 +68,16 @@
      */
     public final boolean mEndTakenBeforeLocks;
 
+    /** Latency tracker associated with this instance. */
+    public final AnrLatencyTracker mLatencyTracker;
+
     private TimeoutRecord(@TimeoutKind int kind, @NonNull String reason, long endUptimeMillis,
             boolean endTakenBeforeLocks) {
         this.mKind = kind;
         this.mReason = reason;
         this.mEndUptimeMillis = endUptimeMillis;
         this.mEndTakenBeforeLocks = endTakenBeforeLocks;
+        this.mLatencyTracker = new AnrLatencyTracker(kind, endUptimeMillis);
     }
 
     private static TimeoutRecord endingNow(@TimeoutKind int kind, String reason) {
diff --git a/core/java/com/android/internal/os/anr/AnrLatencyTracker.java b/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
new file mode 100644
index 0000000..a182920
--- /dev/null
+++ b/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
@@ -0,0 +1,456 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os.anr;
+
+import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+
+import static com.android.internal.os.TimeoutRecord.TimeoutKind;
+import static com.android.internal.util.FrameworkStatsLog.ANRLATENCY_REPORTED__ANR_TYPE__BROADCAST_OF_INTENT;
+import static com.android.internal.util.FrameworkStatsLog.ANRLATENCY_REPORTED__ANR_TYPE__CONTENT_PROVIDER_NOT_RESPONDING;
+import static com.android.internal.util.FrameworkStatsLog.ANRLATENCY_REPORTED__ANR_TYPE__EXECUTING_SERVICE;
+import static com.android.internal.util.FrameworkStatsLog.ANRLATENCY_REPORTED__ANR_TYPE__INPUT_DISPATCHING_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.ANRLATENCY_REPORTED__ANR_TYPE__INPUT_DISPATCHING_TIMEOUT_NO_FOCUSED_WINDOW;
+import static com.android.internal.util.FrameworkStatsLog.ANRLATENCY_REPORTED__ANR_TYPE__START_FOREGROUND_SERVICE;
+import static com.android.internal.util.FrameworkStatsLog.ANRLATENCY_REPORTED__ANR_TYPE__UNKNOWN_ANR_TYPE;
+
+import android.os.SystemClock;
+import android.os.Trace;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Store different latencies from the ANR flow and trace functions, it records latency breakdown
+ * for key methods, lock acquisition and other potentially expensive operations in the ANR
+ * reporting flow and exports the data as comma separated text on calling
+ * dumpAsCommaSeparatedArrayWithHeader and as an atom to statsd on being closed.
+ */
+public class AnrLatencyTracker implements AutoCloseable {
+
+    private static final AtomicInteger sNextAnrRecordPlacedOnQueueCookieGenerator =
+            new AtomicInteger();
+
+    private long mAnrTriggerUptime;
+    private long mEndUptime;
+
+    private long mAppNotRespondingStartUptime;
+    private long mAnrRecordPlacedOnQueueUptime;
+    private long mAnrProcessingStartedUptime;
+    private long mDumpStackTracesStartUptime;
+
+    private long mUpdateCpuStatsNowLastCallUptime;
+    private long mUpdateCpuStatsNowTotalLatency = 0;
+    private long mCurrentPsiStateLastCallUptime;
+    private long mCurrentPsiStateTotalLatency = 0;
+    private long mProcessCpuTrackerMethodsLastCallUptime;
+    private long mProcessCpuTrackerMethodsTotalLatency = 0;
+    private long mCriticalEventLoglastCallUptime;
+    private long mCriticalEventLogTotalLatency = 0;
+
+    private long mGlobalLockLastTryAcquireStart;
+    private long mGlobalLockTotalContention = 0;
+    private long mPidLockLastTryAcquireStart;
+    private long mPidLockTotalContention = 0;
+    private long mAMSLockLastTryAcquireStart;
+    private long mAMSLockTotalContention = 0;
+    private long mProcLockLastTryAcquireStart;
+    private long mProcLockTotalContention = 0;
+    private long mAnrRecordLastTryAcquireStart;
+    private long mAnrRecordLockTotalContention = 0;
+
+    private int mAnrQueueSize;
+    private int mAnrType;
+    private int mDumpedProcessesCount = 0;
+
+    private long mFirstPidsDumpingStart;
+    private long mFirstPidsDumpingDuration = 0;
+    private long mNativePidsDumpingStart;
+    private long mNativePidsDumpingDuration = 0;
+    private long mExtraPidsDumpingStart;
+    private long mExtraPidsDumpingDuration = 0;
+
+    private boolean mIsPushed = false;
+    private boolean mIsSkipped = false;
+
+
+    private final int mAnrRecordPlacedOnQueueCookie =
+            sNextAnrRecordPlacedOnQueueCookieGenerator.incrementAndGet();
+
+    public AnrLatencyTracker(@TimeoutKind int timeoutKind, long anrTriggerUptime) {
+        mAnrTriggerUptime = anrTriggerUptime;
+        mAnrType = timeoutKindToAnrType(timeoutKind);
+
+    }
+
+    /** Records the start of AnrHelper#appNotResponding. */
+    public void appNotRespondingStarted() {
+        mAppNotRespondingStartUptime = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
+                "AnrHelper#appNotResponding()");
+    }
+
+    /** Records the end of AnrHelper#appNotResponding. */
+    public void appNotRespondingEnded() {
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the placing of the AnrHelper.AnrRecord instance on the processing queue. */
+    public void anrRecordPlacingOnQueueWithSize(int queueSize) {
+        mAnrRecordPlacedOnQueueUptime = getUptimeMillis();
+        Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
+                "anrRecordPlacedOnQueue", mAnrRecordPlacedOnQueueCookie);
+        mAnrQueueSize = queueSize;
+        // Since we are recording the anr record queue size after pushing the current
+        // record, we need to increment the current queue size by 1
+        Trace.traceCounter(TRACE_TAG_ACTIVITY_MANAGER, "anrRecordsQueueSize", queueSize + 1);
+    }
+
+    /** Records the start of ProcessErrorStateRecord#appNotResponding. */
+    public void anrProcessingStarted() {
+        mAnrProcessingStartedUptime = getUptimeMillis();
+        Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
+                "anrRecordPlacedOnQueue", mAnrRecordPlacedOnQueueCookie);
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
+                "anrProcessing");
+    }
+
+    /** Records the end of ProcessErrorStateRecord#appNotResponding, the tracker is closed here. */
+    public void anrProcessingEnded() {
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+        close();
+    }
+
+    /** Records the start of ActivityManagerService#dumpStackTraces. */
+    public void dumpStackTracesStarted() {
+        mDumpStackTracesStartUptime = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
+                "dumpStackTraces()");
+    }
+
+    /** Records the end of ActivityManagerService#dumpStackTraces. */
+    public void dumpStackTracesEnded() {
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of ActivityManagerService#updateCpuStatsNow. */
+    public void updateCpuStatsNowCalled() {
+        mUpdateCpuStatsNowLastCallUptime = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "updateCpuStatsNow()");
+    }
+
+    /** Records the return of ActivityManagerService#updateCpuStatsNow. */
+    public void updateCpuStatsNowReturned() {
+        mUpdateCpuStatsNowTotalLatency +=
+                getUptimeMillis() - mUpdateCpuStatsNowLastCallUptime;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of ResourcePressureUtil#currentPsiState. */
+    public void currentPsiStateCalled() {
+        mCurrentPsiStateLastCallUptime = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "currentPsiState()");
+    }
+
+    /** Records the return of ResourcePressureUtil#currentPsiState. */
+    public void currentPsiStateReturned() {
+        mCurrentPsiStateTotalLatency += getUptimeMillis() - mCurrentPsiStateLastCallUptime;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of ProcessCpuTracker methods. */
+    public void processCpuTrackerMethodsCalled() {
+        mProcessCpuTrackerMethodsLastCallUptime = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "processCpuTracker");
+    }
+
+    /** Records the return of ProcessCpuTracker methods. */
+    public void processCpuTrackerMethodsReturned() {
+        mProcessCpuTrackerMethodsTotalLatency +=
+                getUptimeMillis() - mProcessCpuTrackerMethodsLastCallUptime;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of ANR headers dumping to file (subject and criticalEventSection). */
+    public void criticalEventLogStarted() {
+        mCriticalEventLoglastCallUptime = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "criticalEventLog");
+    }
+
+    /** Records the end of ANR headers dumping to file (subject and criticalEventSection). */
+    public void criticalEventLogEnded() {
+        mCriticalEventLogTotalLatency +=
+                getUptimeMillis() - mCriticalEventLoglastCallUptime;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of native pid collection. */
+    public void nativePidCollectionStarted() {
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "nativePidCollection");
+    }
+
+    /** Records the end of native pid collection. */
+    public void nativePidCollectionEnded() {
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of pid dumping to file (subject and criticalEventSection). */
+    public void dumpingPidStarted(int pid) {
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dumpingPid#" + pid);
+    }
+
+    /** Records the end of pid dumping to file (subject and criticalEventSection). */
+    public void dumpingPidEnded() {
+        mDumpedProcessesCount++;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of pid dumping to file (subject and criticalEventSection). */
+    public void dumpingFirstPidsStarted() {
+        mFirstPidsDumpingStart = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dumpingFirstPids");
+    }
+
+    /** Records the end of pid dumping to file (subject and criticalEventSection). */
+    public void dumpingFirstPidsEnded() {
+        mFirstPidsDumpingDuration = getUptimeMillis() - mFirstPidsDumpingStart;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of pid dumping to file (subject and criticalEventSection). */
+    public void dumpingNativePidsStarted() {
+        mNativePidsDumpingStart = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dumpingNativePids");
+    }
+
+    /** Records the end of pid dumping to file (subject and criticalEventSection). */
+    public void dumpingNativePidsEnded() {
+        mNativePidsDumpingDuration =  getUptimeMillis() - mNativePidsDumpingStart;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of pid dumping to file (subject and criticalEventSection). */
+    public void dumpingExtraPidsStarted() {
+        mExtraPidsDumpingStart = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dumpingExtraPids");
+    }
+
+    /** Records the end of pid dumping to file (subject and criticalEventSection). */
+    public void dumpingExtraPidsEnded() {
+        mExtraPidsDumpingDuration =  getUptimeMillis() - mExtraPidsDumpingStart;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of contention on ActivityManagerService.mGlobalLock. */
+    public void waitingOnGlobalLockStarted() {
+        mGlobalLockLastTryAcquireStart = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "globalLock");
+    }
+
+    /** Records the end of contention on ActivityManagerService.mGlobalLock. */
+    public void waitingOnGlobalLockEnded() {
+        mGlobalLockTotalContention += getUptimeMillis() - mGlobalLockLastTryAcquireStart;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of contention on ActivityManagerService.mPidsSelfLocked. */
+    public void waitingOnPidLockStarted() {
+        mPidLockLastTryAcquireStart = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "pidLockContention");
+    }
+
+    /** Records the end of contention on ActivityManagerService.mPidsSelfLocked. */
+    public void waitingOnPidLockEnded() {
+        mPidLockTotalContention += getUptimeMillis() - mPidLockLastTryAcquireStart;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of contention on ActivityManagerService. */
+    public void waitingOnAMSLockStarted() {
+        mAMSLockLastTryAcquireStart = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "AMSLockContention");
+    }
+
+    /** Records the end of contention on ActivityManagerService. */
+    public void waitingOnAMSLockEnded() {
+        mAMSLockTotalContention += getUptimeMillis() - mAMSLockLastTryAcquireStart;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of contention on ActivityManagerService.mProcLock. */
+    public void waitingOnProcLockStarted() {
+        mProcLockLastTryAcquireStart = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "procLockContention");
+    }
+
+    /** Records the start of contention on ActivityManagerService.mProcLock. */
+    public void waitingOnProcLockEnded() {
+        mProcLockTotalContention += getUptimeMillis() - mProcLockLastTryAcquireStart;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Records the start of contention on AnrHelper.mAnrRecords. */
+    public void waitingOnAnrRecordLockStarted() {
+        mAnrRecordLastTryAcquireStart = getUptimeMillis();
+        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "anrRecordLockContention");
+    }
+
+    /** Records the end of contention on AnrHelper.mAnrRecords. */
+    public void waitingOnAnrRecordLockEnded() {
+        mAnrRecordLockTotalContention +=
+                getUptimeMillis() - mAnrRecordLastTryAcquireStart;
+        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
+    /** Counts the number of records in the records queue when the ANR record is popped. */
+    public void anrRecordsQueueSizeWhenPopped(int queueSize) {
+        Trace.traceCounter(TRACE_TAG_ACTIVITY_MANAGER, "anrRecordsQueueSize", queueSize);
+    }
+
+    /** Records a skipped ANR in ProcessErrorStateRecord#appNotResponding. */
+    public void anrSkippedProcessErrorStateRecordAppNotResponding() {
+        anrSkipped("appNotResponding");
+    }
+
+    /** Records a skipped ANR in ActivityManagerService#dumpStackTraces. */
+    public void anrSkippedDumpStackTraces() {
+        anrSkipped("dumpStackTraces");
+    }
+
+    /**
+     * Returns latency data as a comma separated value string for inclusion in ANR report.
+     */
+    public String dumpAsCommaSeparatedArrayWithHeader() {
+        return "DurationsV1: " + mAnrTriggerUptime
+                /* triggering_to_app_not_responding_duration = */
+                + "," + (mAppNotRespondingStartUptime -  mAnrTriggerUptime)
+                /* app_not_responding_duration = */
+                + "," + (mAnrRecordPlacedOnQueueUptime -  mAppNotRespondingStartUptime)
+                /* anr_record_placed_on_queue_duration = */
+                + "," + (mAnrProcessingStartedUptime - mAnrRecordPlacedOnQueueUptime)
+                /* anr_processing_duration = */
+                + "," + (mDumpStackTracesStartUptime - mAnrProcessingStartedUptime)
+
+                /* update_cpu_stats_now_total_duration = */
+                + "," + mUpdateCpuStatsNowTotalLatency
+                /* current_psi_state_total_duration = */
+                + "," + mCurrentPsiStateTotalLatency
+                /* process_cpu_tracker_methods_total_duration = */
+                + "," + mProcessCpuTrackerMethodsTotalLatency
+                /* critical_event_log_duration = */
+                + "," + mCriticalEventLogTotalLatency
+
+                /* global_lock_total_contention = */
+                + "," + mGlobalLockTotalContention
+                /* pid_lock_total_contention = */
+                + "," + mPidLockTotalContention
+                /* ams_lock_total_contention = */
+                + "," + mAMSLockTotalContention
+                /* proc_lock_total_contention = */
+                + "," + mProcLockTotalContention
+                /* anr_record_lock_total_contention = */
+                + "," + mAnrRecordLockTotalContention
+
+                /* anr_queue_size_when_pushed = */
+                + "," + mAnrQueueSize
+                /* dumped_processes_count = */
+                + "," + mDumpedProcessesCount
+                + "\n\n";
+
+    }
+
+    /**
+     * Closes the ANR latency instance by writing the atom to statsd, this method is idempotent.
+     */
+    @Override
+    public void close() {
+        if (!mIsSkipped && !mIsPushed) {
+            mEndUptime = getUptimeMillis();
+            pushAtom();
+            mIsPushed = true;
+        }
+    }
+
+    private static int timeoutKindToAnrType(@TimeoutKind int timeoutKind) {
+        switch (timeoutKind) {
+            case TimeoutKind.INPUT_DISPATCH_NO_FOCUSED_WINDOW:
+                return ANRLATENCY_REPORTED__ANR_TYPE__INPUT_DISPATCHING_TIMEOUT_NO_FOCUSED_WINDOW;
+            case TimeoutKind.INPUT_DISPATCH_WINDOW_UNRESPONSIVE:
+                return ANRLATENCY_REPORTED__ANR_TYPE__INPUT_DISPATCHING_TIMEOUT;
+            case TimeoutKind.BROADCAST_RECEIVER:
+                return ANRLATENCY_REPORTED__ANR_TYPE__BROADCAST_OF_INTENT;
+            case TimeoutKind.SERVICE_START:
+                return ANRLATENCY_REPORTED__ANR_TYPE__START_FOREGROUND_SERVICE;
+            case TimeoutKind.SERVICE_EXEC:
+                return ANRLATENCY_REPORTED__ANR_TYPE__EXECUTING_SERVICE;
+            case TimeoutKind.CONTENT_PROVIDER:
+                return ANRLATENCY_REPORTED__ANR_TYPE__CONTENT_PROVIDER_NOT_RESPONDING;
+            default:
+                return ANRLATENCY_REPORTED__ANR_TYPE__UNKNOWN_ANR_TYPE;
+        }
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public long getUptimeMillis() {
+        return SystemClock.uptimeMillis();
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public void pushAtom() {
+        FrameworkStatsLog.write(
+                FrameworkStatsLog.ANR_LATENCY_REPORTED,
+
+            /* total_duration = */ mEndUptime - mAnrTriggerUptime,
+            /* triggering_to_stack_dump_duration = */
+                    mFirstPidsDumpingStart - mAnrTriggerUptime,
+            /* triggering_to_app_not_responding_duration = */
+                    mAppNotRespondingStartUptime -  mAnrTriggerUptime,
+            /* app_not_responding_duration = */
+                    mAnrRecordPlacedOnQueueUptime - mAppNotRespondingStartUptime,
+            /* anr_record_placed_on_queue_duration = */
+                mAnrProcessingStartedUptime - mAnrRecordPlacedOnQueueUptime,
+            /* anr_processing_duration = */
+                mDumpStackTracesStartUptime - mAnrProcessingStartedUptime,
+            /* dump_stack_traces_duration = */ mFirstPidsDumpingDuration
+                + mNativePidsDumpingDuration
+                + mExtraPidsDumpingDuration,
+
+            /* update_cpu_stats_now_total_duration = */ mUpdateCpuStatsNowTotalLatency,
+            /* current_psi_state_total_duration = */ mCurrentPsiStateTotalLatency,
+            /* process_cpu_tracker_methods_total_duration = */
+                mProcessCpuTrackerMethodsTotalLatency,
+            /* critical_event_log_duration = */ mCriticalEventLogTotalLatency,
+
+            /* global_lock_total_contention = */ mGlobalLockTotalContention,
+            /* pid_lock_total_contention = */ mPidLockTotalContention,
+            /* ams_lock_total_contention = */ mAMSLockTotalContention,
+            /* proc_lock_total_contention = */ mProcLockTotalContention,
+            /* anr_record_lock_total_contention = */ mAnrRecordLockTotalContention,
+
+            /* anr_queue_size_when_pushed = */ mAnrQueueSize,
+            /* anr_type = */ mAnrType,
+            /* dumped_processes_count = */ mDumpedProcessesCount);
+    }
+
+    private void anrSkipped(String method) {
+        Trace.instant(TRACE_TAG_ACTIVITY_MANAGER, "AnrSkipped@" + method);
+        mIsSkipped = true;
+    }
+}
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 14a6d5e..d3f9e0a 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -16,6 +16,27 @@
 
 import static android.os.Trace.TRACE_TAG_APP;
 
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SWITCH_DISPLAY_UNFOLD;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TOGGLE_RECENTS;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__UNKNOWN_ACTION;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -30,6 +51,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.EventLogTags;
 import com.android.internal.os.BackgroundThread;
 
@@ -103,14 +125,14 @@
     public static final int ACTION_START_RECENTS_ANIMATION = 8;
 
     /**
-     * Time it takes the sensor to detect rotation.
-     */
-    public static final int ACTION_ROTATE_SCREEN_SENSOR = 9;
-
-    /**
      * Time it takes to for the camera based algorithm to rotate the screen.
      */
-    public static final int ACTION_ROTATE_SCREEN_CAMERA_CHECK = 10;
+    public static final int ACTION_ROTATE_SCREEN_CAMERA_CHECK = 9;
+
+    /**
+     * Time it takes the sensor to detect rotation.
+     */
+    public static final int ACTION_ROTATE_SCREEN_SENSOR = 10;
 
     /**
      * Time it takes to start unlock animation .
@@ -143,9 +165,14 @@
     public static final int ACTION_LOAD_SHARE_SHEET = 16;
 
     /**
+     * Time it takes for showing the selection toolbar.
+     */
+    public static final int ACTION_SHOW_SELECTION_TOOLBAR = 17;
+
+    /**
      * Time it takes to show AOD display after folding the device.
      */
-    public static final int ACTION_FOLD_TO_AOD = 17;
+    public static final int ACTION_FOLD_TO_AOD = 18;
 
     private static final int[] ACTIONS_ALL = {
         ACTION_EXPAND_PANEL,
@@ -157,14 +184,15 @@
         ACTION_ROTATE_SCREEN,
         ACTION_FACE_WAKE_AND_UNLOCK,
         ACTION_START_RECENTS_ANIMATION,
-        ACTION_ROTATE_SCREEN_SENSOR,
         ACTION_ROTATE_SCREEN_CAMERA_CHECK,
+        ACTION_ROTATE_SCREEN_SENSOR,
         ACTION_LOCKSCREEN_UNLOCK,
         ACTION_USER_SWITCH,
         ACTION_SWITCH_DISPLAY_UNFOLD,
         ACTION_UDFPS_ILLUMINATE,
         ACTION_SHOW_BACK_ARROW,
         ACTION_LOAD_SHARE_SHEET,
+        ACTION_SHOW_SELECTION_TOOLBAR,
         ACTION_FOLD_TO_AOD,
     };
 
@@ -179,39 +207,42 @@
         ACTION_ROTATE_SCREEN,
         ACTION_FACE_WAKE_AND_UNLOCK,
         ACTION_START_RECENTS_ANIMATION,
-        ACTION_ROTATE_SCREEN_SENSOR,
         ACTION_ROTATE_SCREEN_CAMERA_CHECK,
+        ACTION_ROTATE_SCREEN_SENSOR,
         ACTION_LOCKSCREEN_UNLOCK,
         ACTION_USER_SWITCH,
         ACTION_SWITCH_DISPLAY_UNFOLD,
         ACTION_UDFPS_ILLUMINATE,
         ACTION_SHOW_BACK_ARROW,
         ACTION_LOAD_SHARE_SHEET,
-        ACTION_FOLD_TO_AOD
+        ACTION_SHOW_SELECTION_TOOLBAR,
+        ACTION_FOLD_TO_AOD,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Action {
     }
 
-    private static final int[] STATSD_ACTION = new int[]{
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TOGGLE_RECENTS,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SWITCH_DISPLAY_UNFOLD,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD
+    @VisibleForTesting
+    public static final int[] STATSD_ACTION = new int[] {
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_TOGGLE_RECENTS,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_SWITCH_DISPLAY_UNFOLD,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD,
     };
 
     private static LatencyTracker sLatencyTracker;
@@ -269,43 +300,45 @@
     public static String getNameOfAction(int atomsProtoAction) {
         // Defined in AtomsProto.java
         switch (atomsProtoAction) {
-            case 0:
+            case UIACTION_LATENCY_REPORTED__ACTION__UNKNOWN_ACTION:
                 return "UNKNOWN";
-            case 1:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL:
                 return "ACTION_EXPAND_PANEL";
-            case 2:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_TOGGLE_RECENTS:
                 return "ACTION_TOGGLE_RECENTS";
-            case 3:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK:
                 return "ACTION_FINGERPRINT_WAKE_AND_UNLOCK";
-            case 4:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL:
                 return "ACTION_CHECK_CREDENTIAL";
-            case 5:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED:
                 return "ACTION_CHECK_CREDENTIAL_UNLOCKED";
-            case 6:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN:
                 return "ACTION_TURN_ON_SCREEN";
-            case 7:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN:
                 return "ACTION_ROTATE_SCREEN";
-            case 8:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK:
                 return "ACTION_FACE_WAKE_AND_UNLOCK";
-            case 9:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION:
                 return "ACTION_START_RECENTS_ANIMATION";
-            case 10:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK:
                 return "ACTION_ROTATE_SCREEN_CAMERA_CHECK";
-            case 11:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR:
                 return "ACTION_ROTATE_SCREEN_SENSOR";
-            case 12:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK:
                 return "ACTION_LOCKSCREEN_UNLOCK";
-            case 13:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH:
                 return "ACTION_USER_SWITCH";
-            case 14:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SWITCH_DISPLAY_UNFOLD:
                 return "ACTION_SWITCH_DISPLAY_UNFOLD";
-            case 15:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE:
                 return "ACTION_UDFPS_ILLUMINATE";
-            case 16:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW:
                 return "ACTION_SHOW_BACK_ARROW";
-            case 17:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET:
                 return "ACTION_LOAD_SHARE_SHEET";
-            case 19:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR:
+                return "ACTION_SHOW_SELECTION_TOOLBAR";
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD:
                 return "ACTION_FOLD_TO_AOD";
             default:
                 throw new IllegalArgumentException("Invalid action");
diff --git a/core/java/com/android/internal/util/TEST_MAPPING b/core/java/com/android/internal/util/TEST_MAPPING
index 41d59bb..00a8118 100644
--- a/core/java/com/android/internal/util/TEST_MAPPING
+++ b/core/java/com/android/internal/util/TEST_MAPPING
@@ -15,6 +15,21 @@
         }
       ],
       "file_patterns": ["Xml"]
+    },
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "com.android.internal.util.LatencyTrackerTest"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ],
+      "file_patterns": ["LatencyTracker.java"]
     }
   ]
 }
diff --git a/core/java/com/android/internal/util/TypedProperties.java b/core/java/com/android/internal/util/TypedProperties.java
index 5613999..c10dbe7 100644
--- a/core/java/com/android/internal/util/TypedProperties.java
+++ b/core/java/com/android/internal/util/TypedProperties.java
@@ -264,29 +264,29 @@
             // Ensure that the type can hold this value, and return.
             int width = (type >> 8) & 0xff;
             switch (width) {
-            case 1:
-                if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
-                    throw new ParseException(st, "8-bit integer constant");
-                }
-                return new Byte((byte)value);
-            case 2:
-                if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
-                    throw new ParseException(st, "16-bit integer constant");
-                }
-                return new Short((short)value);
-            case 4:
-                if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
-                    throw new ParseException(st, "32-bit integer constant");
-                }
-                return new Integer((int)value);
-            case 8:
-                if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
-                    throw new ParseException(st, "64-bit integer constant");
-                }
-                return new Long(value);
-            default:
-                throw new IllegalStateException(
-                    "Internal error; unexpected integer type width " + width);
+                case 1:
+                    if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
+                        throw new ParseException(st, "8-bit integer constant");
+                    }
+                    return Byte.valueOf((byte) value);
+                case 2:
+                    if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
+                        throw new ParseException(st, "16-bit integer constant");
+                    }
+                    return Short.valueOf((short) value);
+                case 4:
+                    if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
+                        throw new ParseException(st, "32-bit integer constant");
+                    }
+                    return Integer.valueOf((int) value);
+                case 8:
+                    if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
+                        throw new ParseException(st, "64-bit integer constant");
+                    }
+                    return Long.valueOf(value);
+                default:
+                    throw new IllegalStateException(
+                            "Internal error; unexpected integer type width " + width);
             }
         } else if ((type & 0xff) == 'F') {
             if (token != StreamTokenizer.TT_WORD) {
@@ -317,10 +317,10 @@
                         throw new ParseException(st, "32-bit float constant");
                     }
                 }
-                return new Float((float)value);
+                return Float.valueOf((float) value);
             } else {
                 // This property is a double; no need to truncate.
-                return new Double(value);
+                return Double.valueOf(value);
             }
         } else if (type == TYPE_STRING) {
             // Expect a quoted string or the word "null".
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 3e0a6cb..eb8e4fc 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -164,6 +164,7 @@
     private static final String LOCK_SCREEN_DEVICE_OWNER_INFO = "lockscreen.device_owner_info";
 
     private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents";
+    private static final String KNOWN_TRUST_AGENTS = "lockscreen.knowntrustagents";
     private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged";
 
     public static final String CURRENT_LSKF_BASED_PROTECTOR_ID_KEY = "sp-handle";
@@ -1089,31 +1090,50 @@
         return getString(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, userId) != null;
     }
 
+    /** Updates the list of enabled trust agent in LockSettings storage for the given user. */
     public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents, int userId) {
+        setString(ENABLED_TRUST_AGENTS, serializeTrustAgents(activeTrustAgents), userId);
+        getTrustManager().reportEnabledTrustAgentsChanged(userId);
+    }
+
+    /** Returns the list of enabled trust agent in LockSettings storage for the given user. */
+    public List<ComponentName> getEnabledTrustAgents(int userId) {
+        return deserializeTrustAgents(getString(ENABLED_TRUST_AGENTS, userId));
+    }
+
+    /** Updates the list of known trust agent in LockSettings storage for the given user. */
+    public void setKnownTrustAgents(Collection<ComponentName> knownTrustAgents, int userId) {
+        setString(KNOWN_TRUST_AGENTS, serializeTrustAgents(knownTrustAgents), userId);
+    }
+
+    /** Returns the list of known trust agent in LockSettings storage for the given user. */
+    public List<ComponentName> getKnownTrustAgents(int userId) {
+        return deserializeTrustAgents(getString(KNOWN_TRUST_AGENTS, userId));
+    }
+
+    private String serializeTrustAgents(Collection<ComponentName> trustAgents) {
         StringBuilder sb = new StringBuilder();
-        for (ComponentName cn : activeTrustAgents) {
+        for (ComponentName cn : trustAgents) {
             if (sb.length() > 0) {
                 sb.append(',');
             }
             sb.append(cn.flattenToShortString());
         }
-        setString(ENABLED_TRUST_AGENTS, sb.toString(), userId);
-        getTrustManager().reportEnabledTrustAgentsChanged(userId);
+        return sb.toString();
     }
 
-    public List<ComponentName> getEnabledTrustAgents(int userId) {
-        String serialized = getString(ENABLED_TRUST_AGENTS, userId);
-        if (TextUtils.isEmpty(serialized)) {
-            return new ArrayList<ComponentName>();
+    private List<ComponentName> deserializeTrustAgents(String serializedTrustAgents) {
+        if (TextUtils.isEmpty(serializedTrustAgents)) {
+            return new ArrayList<>();
         }
-        String[] split = serialized.split(",");
-        ArrayList<ComponentName> activeTrustAgents = new ArrayList<ComponentName>(split.length);
+        String[] split = serializedTrustAgents.split(",");
+        ArrayList<ComponentName> trustAgents = new ArrayList<>(split.length);
         for (String s : split) {
             if (!TextUtils.isEmpty(s)) {
-                activeTrustAgents.add(ComponentName.unflattenFromString(s));
+                trustAgents.add(ComponentName.unflattenFromString(s));
             }
         }
-        return activeTrustAgents;
+        return trustAgents;
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index 80d50ff..c08f264 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -18,6 +18,7 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Insets;
 import android.graphics.Paint;
@@ -32,6 +33,7 @@
 import android.os.SystemProperties;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.view.ISystemGestureExclusionListener;
 import android.view.InputDevice;
 import android.view.KeyEvent;
@@ -45,8 +47,6 @@
 import android.view.WindowManagerGlobal;
 import android.view.WindowManagerPolicyConstants.PointerEventListener;
 
-import java.util.ArrayList;
-
 public class PointerLocationView extends View implements InputDeviceListener,
         PointerEventListener {
     private static final String TAG = "Pointer";
@@ -61,6 +61,9 @@
      */
     private static final String GESTURE_EXCLUSION_PROP = "debug.pointerlocation.showexclusion";
 
+    // In case when it's in first time or no active pointer found, draw the empty state.
+    private static final PointerState EMPTY_POINTER_STATE = new PointerState();
+
     public static class PointerState {
         // Trace of previous points.
         private float[] mTraceX = new float[32];
@@ -149,7 +152,7 @@
     private int mMaxNumPointers;
     private int mActivePointerId;
     @UnsupportedAppUsage
-    private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>();
+    private final SparseArray<PointerState> mPointers = new SparseArray<PointerState>();
     private final PointerCoords mTempCoords = new PointerCoords();
 
     private final Region mSystemGestureExclusion = new Region();
@@ -175,8 +178,6 @@
         mVC = ViewConfiguration.get(c);
         mTextPaint = new Paint();
         mTextPaint.setAntiAlias(true);
-        mTextPaint.setTextSize(10
-                * getResources().getDisplayMetrics().density);
         mTextPaint.setARGB(255, 0, 0, 0);
         mTextBackgroundPaint = new Paint();
         mTextBackgroundPaint.setAntiAlias(false);
@@ -188,20 +189,19 @@
         mPaint.setAntiAlias(true);
         mPaint.setARGB(255, 255, 255, 255);
         mPaint.setStyle(Paint.Style.STROKE);
-        mPaint.setStrokeWidth(2);
         mCurrentPointPaint = new Paint();
         mCurrentPointPaint.setAntiAlias(true);
         mCurrentPointPaint.setARGB(255, 255, 0, 0);
         mCurrentPointPaint.setStyle(Paint.Style.STROKE);
-        mCurrentPointPaint.setStrokeWidth(2);
         mTargetPaint = new Paint();
         mTargetPaint.setAntiAlias(false);
         mTargetPaint.setARGB(255, 0, 0, 192);
         mPathPaint = new Paint();
         mPathPaint.setAntiAlias(false);
         mPathPaint.setARGB(255, 0, 96, 255);
-        mPaint.setStyle(Paint.Style.STROKE);
-        mPaint.setStrokeWidth(1);
+        mPathPaint.setStyle(Paint.Style.STROKE);
+
+        configureDensityDependentFactors();
 
         mSystemGestureExclusionPaint = new Paint();
         mSystemGestureExclusionPaint.setARGB(25, 255, 0, 0);
@@ -211,8 +211,6 @@
         mSystemGestureExclusionRejectedPaint.setARGB(25, 0, 0, 255);
         mSystemGestureExclusionRejectedPaint.setStyle(Paint.Style.FILL_AND_STROKE);
 
-        PointerState ps = new PointerState();
-        mPointers.add(ps);
         mActivePointerId = 0;
 
         mVelocity = VelocityTracker.obtain();
@@ -308,7 +306,7 @@
 
         // Pointer trace.
         for (int p = 0; p < NP; p++) {
-            final PointerState ps = mPointers.get(p);
+            final PointerState ps = mPointers.valueAt(p);
 
             // Draw path.
             final int N = ps.mTraceCount;
@@ -319,7 +317,7 @@
             for (int i=0; i < N; i++) {
                 float x = ps.mTraceX[i];
                 float y = ps.mTraceY[i];
-                if (Float.isNaN(x)) {
+                if (Float.isNaN(x) || Float.isNaN(y)) {
                     haveLast = false;
                     continue;
                 }
@@ -418,10 +416,6 @@
     }
 
     private void drawLabels(Canvas canvas) {
-        if (mActivePointerId < 0 || mActivePointerId >= mPointers.size()) {
-            return;
-        }
-
         final int w = getWidth() - mWaterfallInsets.left - mWaterfallInsets.right;
         final int itemW = w / 7;
         final int base = mHeaderPaddingTop - mTextMetrics.ascent + 1;
@@ -429,7 +423,7 @@
 
         canvas.save();
         canvas.translate(mWaterfallInsets.left, 0);
-        final PointerState ps = mPointers.get(mActivePointerId);
+        final PointerState ps = mPointers.get(mActivePointerId, EMPTY_POINTER_STATE);
 
         canvas.drawRect(0, mHeaderPaddingTop, itemW - 1, bottom, mTextBackgroundPaint);
         canvas.drawText(mText.clear()
@@ -600,18 +594,13 @@
     @Override
     public void onPointerEvent(MotionEvent event) {
         final int action = event.getAction();
-        int NP = mPointers.size();
 
         if (action == MotionEvent.ACTION_DOWN
                 || (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
             final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
                     >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for down
             if (action == MotionEvent.ACTION_DOWN) {
-                for (int p=0; p<NP; p++) {
-                    final PointerState ps = mPointers.get(p);
-                    ps.clearTrace();
-                    ps.mCurDown = false;
-                }
+                mPointers.clear();
                 mCurDown = true;
                 mCurNumPointers = 0;
                 mMaxNumPointers = 0;
@@ -627,18 +616,17 @@
             }
 
             final int id = event.getPointerId(index);
-            while (NP <= id) {
-                PointerState ps = new PointerState();
-                mPointers.add(ps);
-                NP++;
+            PointerState ps = mPointers.get(id);
+            if (ps == null) {
+                ps = new PointerState();
+                mPointers.put(id, ps);
             }
 
-            if (mActivePointerId < 0 || mActivePointerId >= NP
+            if (!mPointers.contains(mActivePointerId)
                     || !mPointers.get(mActivePointerId).mCurDown) {
                 mActivePointerId = id;
             }
 
-            final PointerState ps = mPointers.get(id);
             ps.mCurDown = true;
             InputDevice device = InputDevice.getDevice(event.getDeviceId());
             ps.mHasBoundingBox = device != null &&
@@ -707,13 +695,13 @@
                     >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for UP
 
             final int id = event.getPointerId(index);
-            if (id >= NP) {
-                Slog.wtf(TAG, "Got pointer ID out of bounds: id=" + id + " arraysize="
-                        + NP + " pointerindex=" + index
+            final PointerState ps = mPointers.get(id);
+            if (ps == null) {
+                Slog.wtf(TAG, "Could not find pointer id=" + id + " in mPointers map,"
+                        + " size=" + mPointers.size() + " pointerindex=" + index
                         + " action=0x" + Integer.toHexString(action));
                 return;
             }
-            final PointerState ps = mPointers.get(id);
             ps.mCurDown = false;
 
             if (action == MotionEvent.ACTION_UP
@@ -1016,4 +1004,19 @@
             }
         }
     };
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        configureDensityDependentFactors();
+    }
+
+    // Compute size by display density.
+    private void configureDensityDependentFactors() {
+        final float density = getResources().getDisplayMetrics().density;
+        mTextPaint.setTextSize(10 * density);
+        mPaint.setStrokeWidth(1 * density);
+        mCurrentPointPaint.setStrokeWidth(1 * density);
+        mPathPaint.setStrokeWidth(1 * density);
+    }
 }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 5498769..d59a51a 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -209,6 +209,7 @@
                 "android_content_res_ApkAssets.cpp",
                 "android_content_res_ObbScanner.cpp",
                 "android_content_res_Configuration.cpp",
+                "android_content_res_ResourceTimer.cpp",
                 "android_security_Scrypt.cpp",
                 "com_android_internal_content_om_OverlayConfig.cpp",
                 "com_android_internal_net_NetworkUtilsInternal.cpp",
@@ -231,6 +232,8 @@
                 "android_hardware_input_InputWindowHandle.cpp",
                 "android_hardware_input_InputApplicationHandle.cpp",
                 "android_window_WindowInfosListener.cpp",
+                "android_window_ScreenCapture.cpp",
+                "jni_common.cpp",
             ],
 
             static_libs: [
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 817b315..68db603 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -117,6 +117,7 @@
 extern int register_android_content_StringBlock(JNIEnv* env);
 extern int register_android_content_XmlBlock(JNIEnv* env);
 extern int register_android_content_res_ApkAssets(JNIEnv* env);
+extern int register_android_content_res_ResourceTimer(JNIEnv* env);
 extern int register_android_graphics_BLASTBufferQueue(JNIEnv* env);
 extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
 extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
@@ -211,6 +212,8 @@
 extern int register_com_android_internal_security_VerityUtils(JNIEnv* env);
 extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
 extern int register_android_window_WindowInfosListener(JNIEnv* env);
+extern int register_android_window_ScreenCapture(JNIEnv* env);
+extern int register_jni_common(JNIEnv* env);
 
 // Namespace for Android Runtime flags applied during boot time.
 static const char* RUNTIME_NATIVE_BOOT_NAMESPACE = "runtime_native_boot";
@@ -1504,6 +1507,7 @@
         REG_JNI(register_android_content_StringBlock),
         REG_JNI(register_android_content_XmlBlock),
         REG_JNI(register_android_content_res_ApkAssets),
+        REG_JNI(register_android_content_res_ResourceTimer),
         REG_JNI(register_android_text_AndroidCharacter),
         REG_JNI(register_android_text_Hyphenator),
         REG_JNI(register_android_view_InputDevice),
@@ -1647,6 +1651,8 @@
         REG_JNI(register_com_android_internal_os_KernelSingleUidTimeReader),
 
         REG_JNI(register_android_window_WindowInfosListener),
+        REG_JNI(register_android_window_ScreenCapture),
+        REG_JNI(register_jni_common),
 };
 
 /*
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 14699e7..a068008 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -22,7 +22,7 @@
 # WindowManager
 per-file android_graphics_BLASTBufferQueue.cpp = file:/services/core/java/com/android/server/wm/OWNERS
 per-file android_view_Surface* = file:/services/core/java/com/android/server/wm/OWNERS
-per-file android_window_WindowInfosListener.cpp = file:/services/core/java/com/android/server/wm/OWNERS
+per-file android_window_* = file:/services/core/java/com/android/server/wm/OWNERS
 
 # Resources
 per-file android_content_res_* = file:/core/java/android/content/res/OWNERS
diff --git a/core/jni/android_content_res_ResourceTimer.cpp b/core/jni/android_content_res_ResourceTimer.cpp
new file mode 100644
index 0000000..91e3c921
--- /dev/null
+++ b/core/jni/android_content_res_ResourceTimer.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+#include <core_jni_helpers.h>
+#include <utils/misc.h>
+#include <androidfw/ResourceTimer.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static struct {
+  jfieldID maxTimer;
+  jfieldID maxBuckets;
+  jfieldID maxLargest;
+  jfieldID timers;
+} gConfigOffsets;
+
+static struct {
+  jfieldID count;
+  jfieldID total;
+  jfieldID mintime;
+  jfieldID maxtime;
+  jfieldID largest;
+  jfieldID percentile;
+} gTimerOffsets;
+
+// ----------------------------------------------------------------------------
+
+
+static int NativeGetTimers(JNIEnv* env, jobject /*clazz*/, jobjectArray timer, jboolean reset) {
+  size_t size = ResourceTimer::counterSize;
+  if (jsize st = env->GetArrayLength(timer); st < size) {
+    // Shrink the size to the minimum of the available counters and the available space.
+    size = st;
+  }
+  for (size_t i = 0; i < size; i++) {
+    ResourceTimer::Timer src;
+    ResourceTimer::copy(i, src, reset);
+    jobject dst = env->GetObjectArrayElement(timer, i);
+    env->SetIntField(dst, gTimerOffsets.count, src.count);
+    if (src.count == 0) {
+      continue;
+    }
+
+    src.compute();
+    env->SetIntField(dst, gTimerOffsets.count, src.count);
+    env->SetLongField(dst, gTimerOffsets.total, src.total);
+    env->SetIntField(dst, gTimerOffsets.mintime, src.mintime);
+    env->SetIntField(dst, gTimerOffsets.maxtime, src.maxtime);
+    jintArray percentile =
+        reinterpret_cast<jintArray>(env->GetObjectField(dst, gTimerOffsets.percentile));
+    env->SetIntArrayRegion(percentile, 0, 1, &src.pvalues.p50.nominal);
+    env->SetIntArrayRegion(percentile, 1, 1, &src.pvalues.p90.nominal);
+    env->SetIntArrayRegion(percentile, 2, 1, &src.pvalues.p95.nominal);
+    env->SetIntArrayRegion(percentile, 3, 1, &src.pvalues.p99.nominal);
+    jintArray largest =
+        reinterpret_cast<jintArray>(env->GetObjectField(dst, gTimerOffsets.largest));
+    env->SetIntArrayRegion(largest, 0, ResourceTimer::Timer::MaxLargest, src.largest);
+  }
+  return size;
+}
+
+static jstring counterName(JNIEnv *env, int counter) {
+  char const *s = ResourceTimer::toString(static_cast<ResourceTimer::Counter>(counter));
+  return env->NewStringUTF(s);
+}
+
+static int NativeEnableTimers(JNIEnv* env, jobject /*clazz*/, jobject config) {
+  ResourceTimer::enable();
+
+  env->SetIntField(config, gConfigOffsets.maxTimer, ResourceTimer::counterSize);
+  env->SetIntField(config, gConfigOffsets.maxBuckets, 4);       // Number of ints in PValues
+  env->SetIntField(config, gConfigOffsets.maxLargest, ResourceTimer::Timer::MaxLargest);
+
+  jclass str = env->FindClass("java/lang/String");
+  jstring empty = counterName(env, 0);
+  jobjectArray timers = env->NewObjectArray(ResourceTimer::counterSize, str, empty);
+  for (int i = 0; i < ResourceTimer::counterSize; i++) {
+    env->SetObjectArrayElement(timers, i, counterName(env, i));
+  }
+  env->SetObjectField(config, gConfigOffsets.timers, timers);
+  return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+// JNI registration.
+static const JNINativeMethod gResourceTimerMethods[] = {
+  {"nativeEnableTimers", "(Landroid/content/res/ResourceTimer$Config;)I",
+   (void *) NativeEnableTimers},
+  {"nativeGetTimers", "([Landroid/content/res/ResourceTimer$Timer;Z)I",
+   (void *) NativeGetTimers},
+};
+
+int register_android_content_res_ResourceTimer(JNIEnv* env) {
+  jclass config = FindClassOrDie(env, "android/content/res/ResourceTimer$Config");
+  gConfigOffsets.maxTimer = GetFieldIDOrDie(env, config, "maxTimer", "I");
+  gConfigOffsets.maxBuckets = GetFieldIDOrDie(env, config, "maxBuckets", "I");
+  gConfigOffsets.maxLargest = GetFieldIDOrDie(env, config, "maxLargest", "I");
+  gConfigOffsets.timers = GetFieldIDOrDie(env, config, "timers", "[Ljava/lang/String;");
+
+  jclass timers = FindClassOrDie(env, "android/content/res/ResourceTimer$Timer");
+  gTimerOffsets.count = GetFieldIDOrDie(env, timers, "count", "I");
+  gTimerOffsets.total = GetFieldIDOrDie(env, timers, "total", "J");
+  gTimerOffsets.mintime = GetFieldIDOrDie(env, timers, "mintime", "I");
+  gTimerOffsets.maxtime = GetFieldIDOrDie(env, timers, "maxtime", "I");
+  gTimerOffsets.largest = GetFieldIDOrDie(env, timers, "largest", "[I");
+  gTimerOffsets.percentile = GetFieldIDOrDie(env, timers, "percentile", "[I");
+
+  return RegisterMethodsOrDie(env, "android/content/res/ResourceTimer", gResourceTimerMethods,
+                              NELEM(gResourceTimerMethods));
+}
+
+}; // namespace android
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 746f88c..77317d1 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2937,13 +2937,14 @@
 
     for (const auto &audioProfile : audioProfiles) {
         jobject jAudioProfile;
-        jStatus = convertAudioProfileFromNative(env, &jAudioProfile, &audioProfile, false);
-        if (jStatus == AUDIO_JAVA_BAD_VALUE) {
+        jint jConvertProfileStatus = convertAudioProfileFromNative(
+                                        env, &jAudioProfile, &audioProfile, false);
+        if (jConvertProfileStatus == AUDIO_JAVA_BAD_VALUE) {
             // skipping Java layer unsupported audio formats
             continue;
         }
-        if (jStatus != AUDIO_JAVA_SUCCESS) {
-            return jStatus;
+        if (jConvertProfileStatus != AUDIO_JAVA_SUCCESS) {
+            return jConvertProfileStatus;
         }
         env->CallBooleanMethod(jAudioProfilesList, gArrayListMethods.add, jAudioProfile);
         env->DeleteLocalRef(jAudioProfile);
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 2d68359..4ad995a 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -21,7 +21,6 @@
 #include <android-base/chrono_utils.h>
 #include <android/graphics/properties.h>
 #include <android/graphics/region.h>
-#include <android/gui/BnScreenCaptureListener.h>
 #include <android/gui/BnWindowInfosReportedListener.h>
 #include <android/hardware/display/IDeviceProductInfoConstants.h>
 #include <android/os/IInputConstants.h>
@@ -61,12 +60,12 @@
 #include "android_os_Parcel.h"
 #include "android_util_Binder.h"
 #include "core_jni_helpers.h"
+#include "jni_common.h"
 
 // ----------------------------------------------------------------------------
 
 namespace android {
 
-using gui::CaptureArgs;
 using gui::FocusRequest;
 
 static void doThrowNPE(JNIEnv* env) {
@@ -131,37 +130,6 @@
     jfieldID group;
 } gDisplayModeClassInfo;
 
-static struct {
-    jfieldID bottom;
-    jfieldID left;
-    jfieldID right;
-    jfieldID top;
-} gRectClassInfo;
-
-static struct {
-    jfieldID pixelFormat;
-    jfieldID sourceCrop;
-    jfieldID frameScaleX;
-    jfieldID frameScaleY;
-    jfieldID captureSecureLayers;
-    jfieldID allowProtected;
-    jfieldID uid;
-    jfieldID grayscale;
-} gCaptureArgsClassInfo;
-
-static struct {
-    jfieldID displayToken;
-    jfieldID width;
-    jfieldID height;
-    jfieldID useIdentityTransform;
-} gDisplayCaptureArgsClassInfo;
-
-static struct {
-    jfieldID layer;
-    jfieldID excludeLayers;
-    jfieldID childrenOnly;
-} gLayerCaptureArgsClassInfo;
-
 // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
 void DeleteScreenshot(void* addr, void* context) {
     delete ((ScreenshotClient*) context);
@@ -221,16 +189,6 @@
 
 static struct {
     jclass clazz;
-    jmethodID builder;
-} gScreenshotHardwareBufferClassInfo;
-
-static struct {
-    jclass clazz;
-    jmethodID onScreenCaptureComplete;
-} gScreenCaptureListenerClassInfo;
-
-static struct {
-    jclass clazz;
     jmethodID ctor;
     jfieldID defaultMode;
     jfieldID allowGroupSwitching;
@@ -273,24 +231,6 @@
     jmethodID invokeReleaseCallback;
 } gSurfaceControlClassInfo;
 
-class JNamedColorSpace {
-public:
-    // ColorSpace.Named.SRGB.ordinal() = 0;
-    static constexpr jint SRGB = 0;
-
-    // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
-    static constexpr jint DISPLAY_P3 = 7;
-};
-
-constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
-    switch (dataspace) {
-        case ui::Dataspace::DISPLAY_P3:
-            return JNamedColorSpace::DISPLAY_P3;
-        default:
-            return JNamedColorSpace::SRGB;
-    }
-}
-
 constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
     switch (colorMode) {
         case ui::ColorMode::DISPLAY_P3:
@@ -303,59 +243,6 @@
     }
 }
 
-class ScreenCaptureListenerWrapper : public gui::BnScreenCaptureListener {
-public:
-    explicit ScreenCaptureListenerWrapper(JNIEnv* env, jobject jobject) {
-        env->GetJavaVM(&mVm);
-        screenCaptureListenerObject = env->NewGlobalRef(jobject);
-        LOG_ALWAYS_FATAL_IF(!screenCaptureListenerObject, "Failed to make global ref");
-    }
-
-    ~ScreenCaptureListenerWrapper() {
-        if (screenCaptureListenerObject) {
-            getenv()->DeleteGlobalRef(screenCaptureListenerObject);
-            screenCaptureListenerObject = nullptr;
-        }
-    }
-
-    binder::Status onScreenCaptureCompleted(
-            const gui::ScreenCaptureResults& captureResults) override {
-        JNIEnv* env = getenv();
-        if (!captureResults.fenceResult.ok() || captureResults.buffer == nullptr) {
-            env->CallVoidMethod(screenCaptureListenerObject,
-                                gScreenCaptureListenerClassInfo.onScreenCaptureComplete, nullptr);
-            return binder::Status::ok();
-        }
-        captureResults.fenceResult.value()->waitForever("");
-        jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
-                env, captureResults.buffer->toAHardwareBuffer());
-        const jint namedColorSpace =
-                fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
-        jobject screenshotHardwareBuffer =
-                env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
-                                            gScreenshotHardwareBufferClassInfo.builder,
-                                            jhardwareBuffer, namedColorSpace,
-                                            captureResults.capturedSecureLayers,
-                                            captureResults.capturedHdrLayers);
-        env->CallVoidMethod(screenCaptureListenerObject,
-                            gScreenCaptureListenerClassInfo.onScreenCaptureComplete,
-                            screenshotHardwareBuffer);
-        env->DeleteLocalRef(jhardwareBuffer);
-        env->DeleteLocalRef(screenshotHardwareBuffer);
-        return binder::Status::ok();
-    }
-
-private:
-    jobject screenCaptureListenerObject;
-    JavaVM* mVm;
-
-    JNIEnv* getenv() {
-        JNIEnv* env;
-        mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
-        return env;
-    }
-};
-
 class TransactionCommittedListenerWrapper {
 public:
     explicit TransactionCommittedListenerWrapper(JNIEnv* env, jobject object) {
@@ -501,102 +388,6 @@
     }
 }
 
-static Rect rectFromObj(JNIEnv* env, jobject rectObj) {
-    int left = env->GetIntField(rectObj, gRectClassInfo.left);
-    int top = env->GetIntField(rectObj, gRectClassInfo.top);
-    int right = env->GetIntField(rectObj, gRectClassInfo.right);
-    int bottom = env->GetIntField(rectObj, gRectClassInfo.bottom);
-    return Rect(left, top, right, bottom);
-}
-
-static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& captureArgs) {
-    captureArgs.pixelFormat = static_cast<ui::PixelFormat>(
-            env->GetIntField(captureArgsObject, gCaptureArgsClassInfo.pixelFormat));
-    captureArgs.sourceCrop =
-            rectFromObj(env,
-                        env->GetObjectField(captureArgsObject, gCaptureArgsClassInfo.sourceCrop));
-    captureArgs.frameScaleX =
-            env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScaleX);
-    captureArgs.frameScaleY =
-            env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScaleY);
-    captureArgs.captureSecureLayers =
-            env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers);
-    captureArgs.allowProtected =
-            env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.allowProtected);
-    captureArgs.uid = env->GetLongField(captureArgsObject, gCaptureArgsClassInfo.uid);
-    captureArgs.grayscale =
-            env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.grayscale);
-}
-
-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,
-                                 jobject screenCaptureListenerObject) {
-    const DisplayCaptureArgs captureArgs =
-            displayCaptureArgsFromObject(env, displayCaptureArgsObject);
-
-    if (captureArgs.displayToken == NULL) {
-        return BAD_VALUE;
-    }
-
-    sp<IScreenCaptureListener> captureListener =
-            new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject);
-    return ScreenshotClient::captureDisplay(captureArgs, captureListener);
-}
-
-static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject,
-                                jobject screenCaptureListenerObject) {
-    LayerCaptureArgs captureArgs;
-    getCaptureArgs(env, layerCaptureArgsObject, captureArgs);
-    SurfaceControl* layer = reinterpret_cast<SurfaceControl*>(
-            env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer));
-    if (layer == nullptr) {
-        return BAD_VALUE;
-    }
-
-    captureArgs.layerHandle = layer->getHandle();
-    captureArgs.childrenOnly =
-            env->GetBooleanField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.childrenOnly);
-    jlongArray excludeObjectArray = reinterpret_cast<jlongArray>(
-            env->GetObjectField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.excludeLayers));
-    if (excludeObjectArray != NULL) {
-        const jsize len = env->GetArrayLength(excludeObjectArray);
-        captureArgs.excludeHandles.reserve(len);
-
-        const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr);
-        for (jsize i = 0; i < len; i++) {
-            auto excludeObject = reinterpret_cast<SurfaceControl *>(objects[i]);
-            if (excludeObject == nullptr) {
-                jniThrowNullPointerException(env, "Exclude layer is null");
-                return NULL;
-            }
-            captureArgs.excludeHandles.emplace(excludeObject->getHandle());
-        }
-        env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
-    }
-
-    sp<IScreenCaptureListener> captureListener =
-            new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject);
-    return ScreenshotClient::captureLayers(captureArgs, captureListener);
-}
-
 static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
     transaction->apply(sync);
@@ -671,12 +462,12 @@
 
     Rect source, dst;
     if (sourceObj != NULL) {
-        source = rectFromObj(env, sourceObj);
+        source = JNICommon::rectFromObj(env, sourceObj);
     } else {
         source.makeInvalid();
     }
     if (dstObj != NULL) {
-        dst = rectFromObj(env, dstObj);
+        dst = JNICommon::rectFromObj(env, dstObj);
     } else {
         dst.makeInvalid();
     }
@@ -1191,20 +982,6 @@
                           histogramComponent3);
 }
 
-static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
-        jboolean secure) {
-    ScopedUtfChars name(env, nameObj);
-    sp<IBinder> token(SurfaceComposerClient::createDisplay(
-            String8(name.c_str()), bool(secure)));
-    return javaObjectForIBinder(env, token);
-}
-
-static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
-    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
-    if (token == NULL) return;
-    SurfaceComposerClient::destroyDisplay(token);
-}
-
 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
         jlong transactionObj,
         jobject tokenObj, jlong nativeSurfaceObject) {
@@ -2240,10 +2017,6 @@
             (void*)nativeGetPhysicalDisplayIds },
     {"nativeGetPhysicalDisplayToken", "(J)Landroid/os/IBinder;",
             (void*)nativeGetPhysicalDisplayToken },
-    {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
-            (void*)nativeCreateDisplay },
-    {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
-            (void*)nativeDestroyDisplay },
     {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
             (void*)nativeSetDisplaySurface },
     {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
@@ -2299,12 +2072,6 @@
             (void*)nativeGetProtectedContentSupport },
     {"nativeReparent", "(JJJ)V",
             (void*)nativeReparent },
-    {"nativeCaptureDisplay",
-            "(Landroid/view/SurfaceControl$DisplayCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I",
-            (void*)nativeCaptureDisplay },
-    {"nativeCaptureLayers",
-            "(Landroid/view/SurfaceControl$LayerCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I",
-            (void*)nativeCaptureLayers },
     {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
             (void*)nativeSetInputWindowInfo },
     {"nativeSetMetadata", "(JJILandroid/os/Parcel;)V",
@@ -2446,12 +2213,6 @@
             GetFieldIDOrDie(env, modeClazz, "presentationDeadlineNanos", "J");
     gDisplayModeClassInfo.group = GetFieldIDOrDie(env, modeClazz, "group", "I");
 
-    jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
-    gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
-    gRectClassInfo.left =   GetFieldIDOrDie(env, rectClazz, "left", "I");
-    gRectClassInfo.right =  GetFieldIDOrDie(env, rectClazz, "right", "I");
-    gRectClassInfo.top =    GetFieldIDOrDie(env, rectClazz, "top", "I");
-
     jclass frameStatsClazz = FindClassOrDie(env, "android/view/FrameStats");
     jfieldID undefined_time_nano_field = GetStaticFieldIDOrDie(env,
             frameStatsClazz, "UNDEFINED_TIME_NANO", "J");
@@ -2492,15 +2253,6 @@
             GetMethodIDOrDie(env, deviceProductInfoManufactureDateClazz, "<init>",
                              "(Ljava/lang/Integer;Ljava/lang/Integer;)V");
 
-    jclass screenshotGraphicsBufferClazz =
-            FindClassOrDie(env, "android/view/SurfaceControl$ScreenshotHardwareBuffer");
-    gScreenshotHardwareBufferClassInfo.clazz =
-            MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
-    gScreenshotHardwareBufferClassInfo.builder =
-            GetStaticMethodIDOrDie(env, screenshotGraphicsBufferClazz, "createFromNative",
-                                   "(Landroid/hardware/HardwareBuffer;IZZ)Landroid/view/"
-                                   "SurfaceControl$ScreenshotHardwareBuffer;");
-
     jclass displayedContentSampleClazz = FindClassOrDie(env,
             "android/hardware/display/DisplayedContentSample");
     gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
@@ -2553,46 +2305,6 @@
     gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMax =
             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRefreshRateMax", "F");
 
-    jclass captureArgsClazz = FindClassOrDie(env, "android/view/SurfaceControl$CaptureArgs");
-    gCaptureArgsClassInfo.pixelFormat = GetFieldIDOrDie(env, captureArgsClazz, "mPixelFormat", "I");
-    gCaptureArgsClassInfo.sourceCrop =
-            GetFieldIDOrDie(env, captureArgsClazz, "mSourceCrop", "Landroid/graphics/Rect;");
-    gCaptureArgsClassInfo.frameScaleX = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScaleX", "F");
-    gCaptureArgsClassInfo.frameScaleY = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScaleY", "F");
-    gCaptureArgsClassInfo.captureSecureLayers =
-            GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z");
-    gCaptureArgsClassInfo.allowProtected =
-            GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z");
-    gCaptureArgsClassInfo.uid = GetFieldIDOrDie(env, captureArgsClazz, "mUid", "J");
-    gCaptureArgsClassInfo.grayscale = GetFieldIDOrDie(env, captureArgsClazz, "mGrayscale", "Z");
-
-    jclass displayCaptureArgsClazz =
-            FindClassOrDie(env, "android/view/SurfaceControl$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/view/SurfaceControl$LayerCaptureArgs");
-    gLayerCaptureArgsClassInfo.layer =
-            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeLayer", "J");
-    gLayerCaptureArgsClassInfo.excludeLayers =
-            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeExcludeLayers", "[J");
-    gLayerCaptureArgsClassInfo.childrenOnly =
-            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mChildrenOnly", "Z");
-
-    jclass screenCaptureListenerClazz =
-            FindClassOrDie(env, "android/view/SurfaceControl$ScreenCaptureListener");
-    gScreenCaptureListenerClassInfo.clazz = MakeGlobalRefOrDie(env, screenCaptureListenerClazz);
-    gScreenCaptureListenerClassInfo.onScreenCaptureComplete =
-            GetMethodIDOrDie(env, screenCaptureListenerClazz, "onScreenCaptureComplete",
-                             "(Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;)V");
-
     jclass jankDataClazz =
                 FindClassOrDie(env, "android/view/SurfaceControl$JankData");
     gJankDataClassInfo.clazz = MakeGlobalRefOrDie(env, jankDataClazz);
diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp
new file mode 100644
index 0000000..c1929c6
--- /dev/null
+++ b/core/jni/android_window_ScreenCapture.cpp
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ScreenCapture"
+// #define LOG_NDEBUG 0
+
+#include <android/gui/BnScreenCaptureListener.h>
+#include <android_runtime/android_hardware_HardwareBuffer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <ui/GraphicTypes.h>
+
+#include "android_os_Parcel.h"
+#include "android_util_Binder.h"
+#include "core_jni_helpers.h"
+#include "jni_common.h"
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+using gui::CaptureArgs;
+
+static struct {
+    jfieldID pixelFormat;
+    jfieldID sourceCrop;
+    jfieldID frameScaleX;
+    jfieldID frameScaleY;
+    jfieldID captureSecureLayers;
+    jfieldID allowProtected;
+    jfieldID uid;
+    jfieldID grayscale;
+} gCaptureArgsClassInfo;
+
+static struct {
+    jfieldID displayToken;
+    jfieldID width;
+    jfieldID height;
+    jfieldID useIdentityTransform;
+} gDisplayCaptureArgsClassInfo;
+
+static struct {
+    jfieldID layer;
+    jfieldID excludeLayers;
+    jfieldID childrenOnly;
+} gLayerCaptureArgsClassInfo;
+
+static struct {
+    jmethodID accept;
+} gConsumerClassInfo;
+
+static struct {
+    jclass clazz;
+    jmethodID builder;
+} gScreenshotHardwareBufferClassInfo;
+
+enum JNamedColorSpace : jint {
+    // ColorSpace.Named.SRGB.ordinal() = 0;
+    SRGB = 0,
+
+    // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
+    DISPLAY_P3 = 7,
+};
+
+constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
+    switch (dataspace) {
+        case ui::Dataspace::DISPLAY_P3:
+            return JNamedColorSpace::DISPLAY_P3;
+        default:
+            return JNamedColorSpace::SRGB;
+    }
+}
+
+static void checkAndClearException(JNIEnv* env, const char* methodName) {
+    if (env->ExceptionCheck()) {
+        ALOGE("An exception was thrown by callback '%s'.", methodName);
+        env->ExceptionClear();
+    }
+}
+
+class ScreenCaptureListenerWrapper : public gui::BnScreenCaptureListener {
+public:
+    explicit ScreenCaptureListenerWrapper(JNIEnv* env, jobject jobject) {
+        env->GetJavaVM(&mVm);
+        mConsumerObject = env->NewGlobalRef(jobject);
+        LOG_ALWAYS_FATAL_IF(!mConsumerObject, "Failed to make global ref");
+    }
+
+    ~ScreenCaptureListenerWrapper() {
+        if (mConsumerObject) {
+            getenv()->DeleteGlobalRef(mConsumerObject);
+            mConsumerObject = nullptr;
+        }
+    }
+
+    binder::Status onScreenCaptureCompleted(
+            const gui::ScreenCaptureResults& captureResults) override {
+        JNIEnv* env = getenv();
+        if (!captureResults.fenceResult.ok() || captureResults.buffer == nullptr) {
+            env->CallVoidMethod(mConsumerObject, gConsumerClassInfo.accept, nullptr);
+            checkAndClearException(env, "accept");
+            return binder::Status::ok();
+        }
+        captureResults.fenceResult.value()->waitForever(LOG_TAG);
+        jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
+                env, captureResults.buffer->toAHardwareBuffer());
+        const jint namedColorSpace =
+                fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
+        jobject screenshotHardwareBuffer =
+                env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
+                                            gScreenshotHardwareBufferClassInfo.builder,
+                                            jhardwareBuffer, namedColorSpace,
+                                            captureResults.capturedSecureLayers,
+                                            captureResults.capturedHdrLayers);
+        checkAndClearException(env, "builder");
+        env->CallVoidMethod(mConsumerObject, gConsumerClassInfo.accept, screenshotHardwareBuffer);
+        checkAndClearException(env, "accept");
+        env->DeleteLocalRef(jhardwareBuffer);
+        env->DeleteLocalRef(screenshotHardwareBuffer);
+        return binder::Status::ok();
+    }
+
+private:
+    jobject mConsumerObject;
+    JavaVM* mVm;
+
+    JNIEnv* getenv() {
+        JNIEnv* env;
+        if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+            if (mVm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
+                LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!");
+            }
+        }
+        return env;
+    }
+};
+
+static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& captureArgs) {
+    captureArgs.pixelFormat = static_cast<ui::PixelFormat>(
+            env->GetIntField(captureArgsObject, gCaptureArgsClassInfo.pixelFormat));
+    captureArgs.sourceCrop =
+            JNICommon::rectFromObj(env,
+                                   env->GetObjectField(captureArgsObject,
+                                                       gCaptureArgsClassInfo.sourceCrop));
+    captureArgs.frameScaleX =
+            env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScaleX);
+    captureArgs.frameScaleY =
+            env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScaleY);
+    captureArgs.captureSecureLayers =
+            env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers);
+    captureArgs.allowProtected =
+            env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.allowProtected);
+    captureArgs.uid = env->GetLongField(captureArgsObject, gCaptureArgsClassInfo.uid);
+    captureArgs.grayscale =
+            env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.grayscale);
+}
+
+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;
+    getCaptureArgs(env, layerCaptureArgsObject, captureArgs);
+    SurfaceControl* layer = reinterpret_cast<SurfaceControl*>(
+            env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer));
+    if (layer == nullptr) {
+        return BAD_VALUE;
+    }
+
+    captureArgs.layerHandle = layer->getHandle();
+    captureArgs.childrenOnly =
+            env->GetBooleanField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.childrenOnly);
+
+    jlongArray excludeObjectArray = reinterpret_cast<jlongArray>(
+            env->GetObjectField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.excludeLayers));
+    if (excludeObjectArray != nullptr) {
+        ScopedLongArrayRO excludeArray(env, excludeObjectArray);
+        const jsize len = excludeArray.size();
+        captureArgs.excludeHandles.reserve(len);
+
+        for (jsize i = 0; i < len; i++) {
+            auto excludeObject = reinterpret_cast<SurfaceControl*>(excludeArray[i]);
+            if (excludeObject == nullptr) {
+                jniThrowNullPointerException(env, "Exclude layer is null");
+                return BAD_VALUE;
+            }
+            captureArgs.excludeHandles.emplace(excludeObject->getHandle());
+        }
+    }
+
+    sp<gui::IScreenCaptureListener> captureListener =
+            reinterpret_cast<gui::IScreenCaptureListener*>(screenCaptureListenerObject);
+    return ScreenshotClient::captureLayers(captureArgs, captureListener);
+}
+
+static jlong nativeCreateScreenCaptureListener(JNIEnv* env, jclass clazz, jobject consumerObj) {
+    sp<gui::IScreenCaptureListener> listener =
+            sp<ScreenCaptureListenerWrapper>::make(env, consumerObj);
+    listener->incStrong((void*)nativeCreateScreenCaptureListener);
+    return reinterpret_cast<jlong>(listener.get());
+}
+
+static void nativeWriteListenerToParcel(JNIEnv* env, jclass clazz, jlong nativeObject,
+                                        jobject parcelObj) {
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (parcel == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+    ScreenCaptureListenerWrapper* const self =
+            reinterpret_cast<ScreenCaptureListenerWrapper*>(nativeObject);
+    if (self != nullptr) {
+        parcel->writeStrongBinder(IInterface::asBinder(self));
+    }
+}
+
+static jlong nativeReadListenerFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (parcel == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return 0;
+    }
+    sp<gui::IScreenCaptureListener> listener =
+            interface_cast<gui::IScreenCaptureListener>(parcel->readStrongBinder());
+    if (listener == nullptr) {
+        return 0;
+    }
+    listener->incStrong((void*)nativeCreateScreenCaptureListener);
+    return reinterpret_cast<jlong>(listener.get());
+}
+
+void destroyNativeListener(void* ptr) {
+    ScreenCaptureListenerWrapper* listener = reinterpret_cast<ScreenCaptureListenerWrapper*>(ptr);
+    listener->decStrong((void*)nativeCreateScreenCaptureListener);
+}
+
+static jlong getNativeListenerFinalizer(JNIEnv* env, jclass clazz) {
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeListener));
+}
+
+// ----------------------------------------------------------------------------
+
+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/Consumer;)J",
+            (void*)nativeCreateScreenCaptureListener },
+    {"nativeWriteListenerToParcel", "(JLandroid/os/Parcel;)V", (void*)nativeWriteListenerToParcel },
+    {"nativeReadListenerFromParcel", "(Landroid/os/Parcel;)J",
+            (void*)nativeReadListenerFromParcel },
+    {"getNativeListenerFinalizer", "()J", (void*)getNativeListenerFinalizer },
+        // clang-format on
+};
+
+int register_android_window_ScreenCapture(JNIEnv* env) {
+    int err = RegisterMethodsOrDie(env, "android/window/ScreenCapture", sScreenCaptureMethods,
+                                   NELEM(sScreenCaptureMethods));
+
+    jclass captureArgsClazz = FindClassOrDie(env, "android/window/ScreenCapture$CaptureArgs");
+    gCaptureArgsClassInfo.pixelFormat = GetFieldIDOrDie(env, captureArgsClazz, "mPixelFormat", "I");
+    gCaptureArgsClassInfo.sourceCrop =
+            GetFieldIDOrDie(env, captureArgsClazz, "mSourceCrop", "Landroid/graphics/Rect;");
+    gCaptureArgsClassInfo.frameScaleX = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScaleX", "F");
+    gCaptureArgsClassInfo.frameScaleY = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScaleY", "F");
+    gCaptureArgsClassInfo.captureSecureLayers =
+            GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z");
+    gCaptureArgsClassInfo.allowProtected =
+            GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z");
+    gCaptureArgsClassInfo.uid = GetFieldIDOrDie(env, captureArgsClazz, "mUid", "J");
+    gCaptureArgsClassInfo.grayscale = GetFieldIDOrDie(env, captureArgsClazz, "mGrayscale", "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 =
+            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeLayer", "J");
+    gLayerCaptureArgsClassInfo.excludeLayers =
+            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeExcludeLayers", "[J");
+    gLayerCaptureArgsClassInfo.childrenOnly =
+            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mChildrenOnly", "Z");
+
+    jclass consumer = FindClassOrDie(env, "java/util/function/Consumer");
+    gConsumerClassInfo.accept = GetMethodIDOrDie(env, consumer, "accept", "(Ljava/lang/Object;)V");
+
+    jclass screenshotGraphicsBufferClazz =
+            FindClassOrDie(env, "android/window/ScreenCapture$ScreenshotHardwareBuffer");
+    gScreenshotHardwareBufferClassInfo.clazz =
+            MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
+    gScreenshotHardwareBufferClassInfo.builder =
+            GetStaticMethodIDOrDie(env, screenshotGraphicsBufferClazz, "createFromNative",
+                                   "(Landroid/hardware/HardwareBuffer;IZZ)Landroid/window/"
+                                   "ScreenCapture$ScreenshotHardwareBuffer;");
+
+    return err;
+}
+
+} // namespace android
diff --git a/core/jni/jni_common.cpp b/core/jni/jni_common.cpp
new file mode 100644
index 0000000..8d376cf
--- /dev/null
+++ b/core/jni/jni_common.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "jni_common.h"
+
+#include <jni.h>
+#include <ui/GraphicTypes.h>
+#include <ui/Rect.h>
+
+#include "core_jni_helpers.h"
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+static struct {
+    jfieldID bottom;
+    jfieldID left;
+    jfieldID right;
+    jfieldID top;
+} gRectClassInfo;
+
+Rect JNICommon::rectFromObj(JNIEnv* env, jobject rectObj) {
+    int left = env->GetIntField(rectObj, gRectClassInfo.left);
+    int top = env->GetIntField(rectObj, gRectClassInfo.top);
+    int right = env->GetIntField(rectObj, gRectClassInfo.right);
+    int bottom = env->GetIntField(rectObj, gRectClassInfo.bottom);
+    return Rect(left, top, right, bottom);
+}
+
+int register_jni_common(JNIEnv* env) {
+    jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
+    gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
+    gRectClassInfo.left = GetFieldIDOrDie(env, rectClazz, "left", "I");
+    gRectClassInfo.right = GetFieldIDOrDie(env, rectClazz, "right", "I");
+    gRectClassInfo.top = GetFieldIDOrDie(env, rectClazz, "top", "I");
+    return 0;
+}
+
+} // namespace android
diff --git a/core/jni/jni_common.h b/core/jni/jni_common.h
new file mode 100644
index 0000000..a2bf6fb
--- /dev/null
+++ b/core/jni/jni_common.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <jni.h>
+
+namespace android {
+
+class Rect;
+
+class JNICommon {
+public:
+    static Rect rectFromObj(JNIEnv* env, jobject rectObj);
+};
+} // namespace android
\ No newline at end of file
diff --git a/core/res/OWNERS b/core/res/OWNERS
index d8fc218..22f40a1 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -36,6 +36,9 @@
 # Car
 per-file res/values/dimens_car.xml = file:/platform/packages/services/Car:/OWNERS
 
+# Device Idle
+per-file res/values/config_device_idle.xml = file:/apex/jobscheduler/OWNERS
+
 # Wear
 per-file res/*-watch/* = file:/WEAR_OWNERS
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 9b997bf..0b9386c3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gebruik skermslot"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Voer jou skermslot in om voort te gaan"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Druk ferm op die sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kon nie vingerafdruk verwerk nie. Probeer asseblief weer."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Kan nie vingerafdruk herken nie. Probeer weer."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Maak vingerafdruksensor skoon en probeer weer"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Maak sensor skoon en probeer weer"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Druk ferm op sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vinger is te stadig beweer. Probeer asseblief weer."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probeer \'n ander vingerafdruk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Te helder"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Druk van aan/af-skakelaar bespeur"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probeer om dit te verstel"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Verander elke keer die posisie van jou vinger so effens"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gesig is gestaaf; druk asseblief bevestig"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Vingerafdrukhardeware is nie beskikbaar nie."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Kan nie vingerafdruk opstel nie"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Vingerafdrukuittelling is bereik. Probeer weer."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vingerafdrukopstelling het uitgetel. Probeer weer."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Vingerafdrukhandeling is gekanselleer."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Vingerafdrukhandeling is deur gebruiker gekanselleer."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Te veel pogings. Probeer later weer."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Te veel pogings. Gebruik eerder skermslot."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Te veel pogings. Gebruik eerder skermslot."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Probeer weer."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Kan nie vingerafdruk verwerk nie. Probeer weer."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukke is geregistreer nie."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Besoek \'n verskaffer wat herstelwerk doen."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Kan nie jou gesigmodel skep nie. Probeer weer."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Te helder. Probeer sagter beligting."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nie genoeg lig nie"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Beweeg foon verder weg"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Beweeg foon nader"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Beweeg foon hoër op"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Begin programme."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Voltooi herlaai."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Jy het die aan/af-skakelaar gedruk – dit skakel gewoonlik die skerm af.\n\nProbeer liggies tik terwyl jy jou vingerafdruk opstel."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tik om skerm af te skakel"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Skakel skerm af"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Skakel skerm af om opstelling te stop"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Skakel af"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Gaan voort met vingerafdrukverifiëring?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Jy het die aan/af-skakelaar gedruk – dit skakel gewoonlik die skerm af.\n\nProbeer liggies tik om jou vingerafdruk te verifieer."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Skakel skerm af"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Foon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dokluidsprekers"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Eksterne toestel"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Oorfone"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Stelsel"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 698bce4..1e8d681 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"የማያ ገጽ መቆለፊን ይጠቀሙ"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ለመቀጠል የማያ ገጽ ቁልፍዎን ያስገቡ"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ዳሳሹን በደንብ ይጫኑት"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ጣት አሻራን መስራት አልተቻለም። እባክዎ እንደገና ይሞክሩ።"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"የጣት አሻራን መለየት አልተቻለም። እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"የጣት አሻራ ዳሳሽን ያጽዱ እና እንደገና ይሞክሩ"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ዳሳሹን ያጽዱ እና እንደገና ይሞክሩ"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ዳሳሹን ጠበቅ አድርገው ይጫኑት"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ጣት ከልክ በላይ ተንቀራፎ ተንቀሳቅሷል። እባክዎ እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ሌላ የጣት አሻራ ይሞክሩ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"በጣም ብርሃናማ"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"በኃይል መጫን እንዳለ ታውቋል"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ለማስተካከል ይሞክሩ"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"በእያንዳንዱ ጊዜ የጣትዎን ቦታ በትንሹ ይለዋውጡ"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ፊት ተረጋግጧል፣ እባክዎ አረጋግጥን ይጫኑ"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"የጣት አሻራ ሃርድዌር አይገኝም።"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"የጣት አሻራን ማዋቀር አልተቻለም"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"የጣት አሻራ ማብቂያ ጊዜ ደርሷል። እንደገና ይሞክሩ።"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"የጣት አሻራ ውቅረት ጊዜው አብቅቷል። እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"የጣት አሻራ ስርዓተ ክወና ተትቷል።"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"የጣት አሻራ ክወና በተጠቃሚ ተሰርዟል።"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ከልክ በላይ ብዙ ሙከራዎች። በኋላ ላይ እንደገና ይሞክሩ።"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገጽ መቆለፊያን ይጠቀሙ።"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገጽ መቆለፊያን ይጠቀሙ።"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"እንደገና ይሞክሩ።"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"የጣት አሻራን ማሰናዳት አልተቻለም። እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ምንም የጣት አሻራዎች አልተመዘገቡም።"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"የጥገና አገልግሎት ሰጪን ይጎብኙ።"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"የመልክዎን ሞዴል መፍጠር አልተቻለም። እንደገና ይሞክሩ።"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ከልክ በላይ ፈካ ያለ። ይበልጥ ረጋ ያለ ብርሃን አጠቃቀምን ይሞክሩ።"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"በቂ ብርሃን የለም"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ስልኩን ያርቁት"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ስልኩን ያቅርቡት"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ስልኩን ከፍ ወዳለ ቦታ ይውሰዱት"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"መተግበሪያዎችን በማስጀመር ላይ፡፡"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"አጨራረስ ማስነሻ፡፡"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"የማብሪያ/ማጥፊያ ቁልፉን ተጭነዋል — ይህ ብዙውን ጊዜ ማያ ገጹን ያጠፋል።\n\nየጣት አሻራዎን በሚያዋቅሩበት ጊዜ በትንሹ መታ ለማድረግ ይሞክሩ።"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"ማያ ገጽን ለማጥፋት መታ ያድርጉ"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"ማያ ገጽን አጥፋ"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"ውቅረትን ለመጨረስ ማያ ገጽን ያጥፉ"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"አጥፋ"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"የጣት አሻራዎን ማረጋገጥ ይቀጥሉ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"የማብሪያ/ማጥፊያ ቁልፉን ተጭነዋል - ይህ ብዙውን ጊዜ ማያ ገጹን ያጠፋል። \n\n የጣት አሻራዎን ለማረጋገጥ በትንሹ መታ ለማድረግ ይሞክሩ።"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"ማያ ገጽን አጥፋ"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ቴሌቪዥን"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ስልክ"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"የትከል ድምፅ ማጉያዎች"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"ኤችዲኤምአይ"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"የውጪ መሣሪያ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"የጆሮ ማዳመጫዎች"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"ዩ ኤስ ቢ"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"ስርዓት"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 82fc943..1529b0d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -587,13 +587,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"استخدام قفل الشاشة"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"أدخِل قفل الشاشة للمتابعة"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"اضغط بقوة على المستشعر"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"تعذرت معالجة بصمة الإصبع. يُرجى إعادة المحاولة."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"يتعذّر التعرّف على بصمة الإصبع. يُرجى إعادة المحاولة."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"يُرجى تنظيف مستشعر بصمات الإصبع ثم إعادة المحاولة."</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"تنظيف المستشعر ثم إعادة المحاولة"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"اضغط بقوة على المستشعر"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"تم تحريك الإصبع ببطء شديد. يُرجى إعادة المحاولة."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"يمكنك تجربة بصمة إصبع أخرى."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"الصورة ساطعة للغاية."</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"تم رصد الضغط على زر التشغيل."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"حاوِل تعديل بصمة الإصبع."</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"غيِّر موضع إصبعك قليلاً في كل مرة."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -605,12 +606,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"تمّت مصادقة الوجه، يُرجى الضغط على \"تأكيد\"."</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"جهاز بصمة الإصبع غير متاح."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"يتعذّر إعداد بصمة الإصبع."</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"تم بلوغ مهلة إدخال بصمة الإصبع. أعد المحاولة."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"انتهت مهلة إعداد بصمة الإصبع. يُرجى إعادة المحاولة."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"تم إلغاء تشغيل بصمة الإصبع."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"تم إلغاء تشغيل بصمة الإصبع بواسطة المستخدم."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"تم إجراء عدد كبير من المحاولات. أعد المحاولة لاحقًا."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"تم إجراء عدد كبير جدًا من المحاولات. عليك استخدام قفل الشاشة بدلاً من ذلك."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"تم إجراء عدد كبير جدًا من المحاولات. عليك استخدام قفل الشاشة بدلاً من ذلك."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"أعد المحاولة."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"تتعذّر معالجة بصمة الإصبع. يُرجى إعادة المحاولة."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ليست هناك بصمات إصبع مسجَّلة."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
@@ -638,8 +639,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"يُرجى التواصل مع مقدِّم خدمات إصلاح."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"يتعذّر إنشاء نموذج الوجه. يُرجى إعادة المحاولة."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ساطع للغاية. تجربة مستوى سطوع أقلّ."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"الإضاءة غير كافية."</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"يُرجى إبعاد الهاتف عنك."</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"يُرجى تقريب الهاتف منك."</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"يُرجى رفع الهاتف للأعلى."</string>
@@ -1253,8 +1253,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"بدء التطبيقات."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"جارٍ إعادة التشغيل."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"ضغطت على زر التشغيل، يؤدي هذا عادةً إلى إيقاف الشاشة.\n\nجرِّب النقر بخفة أثناء إعداد بصمتك."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"النقر لإيقاف الشاشة"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"إيقاف الشاشة"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"لإنهاء عملية الإعداد، أوقِف الشاشة."</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"إيقاف"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"هل تريد مواصلة تأكيد بصمة إصبعك؟"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"ضغطت على زر التشغيل، يؤدي هذا عادةً إلى إيقاف الشاشة.\n\nجرِّب النقر بخفة لتأكيد بصمة إصبعك."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"إيقاف الشاشة"</string>
@@ -1615,7 +1615,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"التلفزيون"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"الهاتف"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"مكبرات صوت للإرساء"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"جهاز خارجي"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"سماعات رأس"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"النظام"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 93957e5..a854ea6 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্ৰীন ল\'ক ব্যৱহাৰ কৰক"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"অব্যাহত ৰাখিবলৈ আপোনাৰ স্ক্ৰীন লক দিয়ক"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ছেন্সৰটোত ভালকৈ টিপক"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ফিগাৰপ্ৰিণ্টৰ প্ৰক্ৰিয়া সম্পাদন কৰিবপৰা নগ\'ল। অনুগ্ৰহ কৰি আকৌ চেষ্টা কৰক৷"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ফিংগাৰপ্ৰিণ্ট চিনাক্ত কৰিব পৰা নাই। পুনৰ চেষ্টা কৰক।"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো মচি পুনৰ চেষ্টা কৰক"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ছেন্সৰটো মচি পুনৰ চেষ্টা কৰক"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ছেন্সৰটোত ভালকৈ টিপক"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"আঙুলিৰ গতি অতি মন্থৰ আছিল। অনুগ্ৰহ কৰি আকৌ চেষ্টা কৰক৷"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"অন্য এটা ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰি চাওক"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"অতি উজ্জ্বল"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"পাৱাৰ বুটাম টিপাটো চিনাক্ত কৰা হৈছে"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"মিলাই চাওক"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"প্ৰতিবাৰতে আপোনাৰ আঙুলিটোৰ স্থান সামান্য সলনি কৰক"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল, অনুগ্ৰহ কৰি ‘নিশ্চিত কৰক’ বুটামটো টিপক"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ নাই।"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ফিংগাৰপ্ৰিণ্ট ছেট আপ কৰিব নোৱাৰি"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ফিংগাৰপ্ৰিণ্ট গ্ৰহণৰ সময়সীমা উকলি গৈছে। আকৌ চেষ্টা কৰক।"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ফিংগাৰপ্ৰিণ্ট ছেটআপ কৰাৰ সময় উকলি গৈছে। পুনৰ চেষ্টা কৰক।"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ফিংগাৰপ্ৰিণ্ট কাৰ্য বাতিল কৰা হ’ল।"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ব্যৱহাৰকাৰীয়ে ফিংগাৰপ্ৰিণ্ট ক্ৰিয়া বাতিল কৰিছে।"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"অত্যধিক ভুল প্ৰয়াস। কিছুসময়ৰ পাছত আকৌ চেষ্টা কৰক।"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"অতি বেছিসংখ্যক প্ৰয়াস। ইয়াৰ সলনি স্ক্ৰীন লক ব্যৱহাৰ কৰক।"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"অতি বেছিসংখ্যক প্ৰয়াস। ইয়াৰ সলনি স্ক্ৰীন লক ব্যৱহাৰ কৰক।"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"আকৌ চেষ্টা কৰক।"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ফিংগাৰপ্ৰিণ্ট চিনাক্তকৰণ প্ৰক্ৰিয়া কৰিব পৰা নাই। পুনৰ চেষ্টা কৰক।"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"মেৰামতি সেৱা প্ৰদানকাৰী কোনো প্ৰতিষ্ঠানলৈ যাওক।"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"মুখাৱয়বৰ মডেল সৃষ্টি কৰিব নোৱাৰি। পুনৰ চেষ্টা কৰক।"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"অতি উজ্জ্বল। ইয়াতকৈ কম পোহৰৰ উৎস ব্যৱহাৰ কৰক।"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"পৰ্যাপ্ত পোহৰ নাই"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ফ’নটো আৰু আঁতৰলৈ নিয়ক"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ফ’নটো ওচৰলৈ আনক"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ফ’নটো ওপৰলৈ নিয়ক"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"আৰম্ভ হৈ থকা এপসমূহ।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"বুট কাৰ্য সমাপ্ত কৰিছে।"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"আপুনি পাৱাৰ বুটামটো টিপিছে — এইটোৱে সাধাৰণতে স্ক্ৰীনখন অফ কৰে।\n\nআপোনাৰ ফিংগাৰপ্ৰিণ্টটো ছেট আপ কৰাৰ সময়ত লাহেকৈ টিপি চাওক।"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"স্ক্ৰীন অফ কৰিবলৈ টিপক"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"স্ক্ৰীন অফ কৰক"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"ছেটআপ সমাপ্ত কৰিবলৈ স্ক্ৰীন অফ কৰক"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"অফ কৰক"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"ফিংগাৰপ্ৰিণ্ট সত্যাপন কৰা জাৰি ৰাখিবনে?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"আপুনি পাৱাৰ বুটামটো টিপিছে — এইটোৱে সাধাৰণতে স্ক্ৰীনখন অফ কৰে।\n\nআপোনাৰ ফিংগাৰপ্ৰিণ্টটো সত্যাপন কৰিবলৈ লাহেকৈ টিপি চাওক।"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"স্ক্ৰীন অফ কৰক"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"টিভি"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ফ\'ন"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ড\'ক স্পীকাৰসমূহ"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"বাহ্যিক ডিভাইচ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"হেডফ\'নবোৰ"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"ইউএছবি"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"ছিষ্টেম"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index c4f3d75..1449500 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran kilidindən istifadə edin"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Davam etmək üçün ekran kilidinizi daxil edin"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Sensora basıb saxlayın"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmaq izi tanınmadı. Lütfən, yenidən cəhd edin."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Barmaq izini tanımaq olmur. Yenidən cəhd edin."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Barmaq izi sensorunu silib yenidən cəhd edin"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensoru silib yenidən cəhd edin"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Sensora basıb saxlayın"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Barmağınızı çox yavaş hərəkət etdirdiniz. Lütfən, yenidən cəhd edin."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Başqa bir barmaq izini sınayın"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Çox işıqlıdır"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Qidalanma düyməsi basılıb"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Tənzimləməyə çalışın"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Hər dəfə barmağınızın yerini bir az dəyişdirin"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Üz təsdiq edildi, təsdiq düyməsinə basın"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Barmaq izi üçün avadanlıq yoxdur."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Barmaq izini ayarlamaq mümkün deyil"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Barmaq izinin vaxtı başa çatdı. Yenidən cəhd edin."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Barmaq izi ayarlama vaxtı bitib. Yenidən cəhd edin."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Barmaq izi əməliyyatı ləğv edildi."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Barmaq izi əməliyyatı istifadəçi tərəfindən ləğv edildi."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Cəhdlər çox oldu. Sonraya saxlayın."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Həddindən çox cəhd edilib. Əvəzində ekran kilidindən istifadə edin."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Həddindən çox cəhd edilib. Əvəzində ekran kilidindən istifadə edin."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Yenidən cəhd edin."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Barmaq izini emal etmək mümkün deyil. Yenidən cəhd edin."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Barmaq izi qeydə alınmayıb."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Təmir provayderini ziyarət edin."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Üz modelinizi yaratmaq olmur. Yenə cəhd edin."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Çox işıqlıdır. Daha az işıqlı şəkli sınayın."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Kifayət qədər İşıq yoxdur"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Telefonu uzaq tutun"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Telefonu yaxına tutun"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Telefonu yuxarı tutun"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Tətbiqlər başladılır."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Yükləmə başa çatır."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Qidalanma düyməsini basdınız — adətən bu, ekranı söndürür.\n\nBarmaq izini ayarlayarkən yüngülcə toxunmağa çalışın."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Ekranı söndürmək üçün toxunun"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Ekranı söndürün"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Ayarlamanı bitirmək üçün ekranı söndürün"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Söndürün"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Barmaq izini doğrulamağa davam edilsin?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Qidalanma düyməsini basdınız — adətən bu, ekranı söndürür.\n\nBarmaq izini doğrulamaq üçün yüngülcə toxunmağa çalışın."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Ekranı söndürün"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dok spikerlər"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Xarici Cihaz"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Qulaqlıq"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index bf9c57b..bcaea5d 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristite zaključavanje ekrana"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrebite zaključavanje ekrana da biste nastavili"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Jako pritisnite senzor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nije uspela obrada otiska prsta. Probajte ponovo."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Prepoznavanje otiska prsta nije uspelo. Probajte ponovo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Obrišite senzor za otisak prsta i probajte ponovo"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Obrišite senzor i probajte ponovo"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Jako pritisnite senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Previše sporo ste pomerili prst. Probajte ponovo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probajte sa drugim otiskom prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Previše je svetlo"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Otkriven je pritisak dugmeta za uključivanje"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probajte da prilagodite"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put pomalo promenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je potvrđeno. Pritisnite Potvrdi"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardver za otiske prstiju nije dostupan."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Podešavanje otiska prsta nije uspelo"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Vremensko ograničenje za otisak prsta je isteklo. Probajte ponovo."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vreme za podešavanje otiska prsta je isteklo. Probajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Radnja sa otiskom prsta je otkazana."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Korisnik je otkazao radnju sa otiskom prsta."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Previše pokušaja. Probajte ponovo kasnije."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Probajte ponovo."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Obrađivanje otiska prsta nije uspelo. Probajte ponovo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registrovan nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Posetite dobavljača za popravke."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Pravljenje modela lica nije uspelo. Probajte ponovo."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Previše je svetlo. Probajte sa slabijim osvetljenjem."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nema dovoljno svetla"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Udaljite telefon"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Približite telefon"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Pomerite telefon nagore"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Završavanje pokretanja."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Pritisnuli ste dugme za uključivanje – time obično isključujete ekran.\n\nProbajte lagano da dodirnete dok podešavate otisak prsta."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Dodirnite da biste isključili ekran"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Isključi ekran"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Završite podešavanje isključivanjem ekrana"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Isključi"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Nastavljate verifikaciju otiska prsta?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Pritisnuli ste dugme za uključivanje – time obično isključujete ekran.\n\nProbajte lagano da dodirnete da biste verifikovali otisak prsta."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Isključi ekran"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Zvučnici bazne stanice"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Spoljni uređaj"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Slušalice"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 1af3c7d..48dd891 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ужываць блакіроўку экрана"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Каб працягнуць, скарыстайце свой сродак блакіроўкі экрана"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Моцна націсніце на сканер"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не атрымалася апрацаваць адбітак пальца. Паспрабуйце яшчэ раз."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Не ўдалося распазнаць адбітак пальца. Паўтарыце спробу."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Ачысціце сканер адбіткаў пальцаў і паўтарыце спробу"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Ачысціце сканер і паўтарыце спробу"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Моцна націсніце на сканер"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Палец рухаўся занадта павольна. Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Паспрабуйце іншы адбітак пальца"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Занадта светла"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Выяўлена моцнае націсканне"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Паспрабуйце наладзіць"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Кожны раз крыху мяняйце пазіцыю пальца"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Твар распазнаны. Націсніце, каб пацвердзіць"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Апаратныя сродкі адбіткаў пальцаў недаступныя."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не ўдалося захаваць адбітак пальца"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Час чакання выйшаў. Паспрабуйце яшчэ раз."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Наладжванне адбітка пальца не завершана. Паўтарыце спробу."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Аперацыя з адбіткамі пальцаў скасавана."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Аўтэнтыфікацыя па адбітках пальцаў скасавана карыстальнікам."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Занадта шмат спроб. Паспрабуйце яшчэ раз пазней."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Занадта шмат спроб. Скарыстайце блакіроўку экрана."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Занадта шмат спроб. Скарыстайце блакіроўку экрана."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Паўтарыце спробу."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Не ўдалося апрацаваць адбітак пальца. Паўтарыце спробу."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Адбіткі пальцаў не зарэгістраваны."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Звярніцеся ў сэрвісны цэнтр."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Не ўдалося стварыць мадэль твару. Паўтарыце."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Занадта светла. Прыглушыце асвятленне."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Недастаткова святла"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Перамясціце тэлефон далей"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Перамясціце тэлефон бліжэй"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Перамясціце тэлефон вышэй"</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Запуск прыкладанняў."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Завяршэнне загрузкі."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Вы націснулі кнопку сілкавання. Звычайна ў выніку гэтага дзеяння выключаецца экран.\n\nПадчас наладжвання адбітка пальца злёгку дакраніцеся да кнопкі."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Націсніце, каб выключыць экран"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Выключыць экран"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Каб завяршыць наладку, выключыце экран"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Выключыць"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Працягнуць спраўджанне адбітка пальца?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Вы націснулі кнопку сілкавання. Звычайна ў выніку гэтага дзеяння выключаецца экран.\n\nКаб спраўдзіць адбітак пальца, злёгку дакраніцеся да кнопкі."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Выключыць экран"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ТБ"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Тэлефон"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Дынамікі станцыi"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Знешняя прылада"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Навушнікі"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Сістэма"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 4ae1f21..9304969 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ползване на заключв. на екрана"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Въведете опцията си за заключване на екрана, за да продължите"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Натиснете добре върху сензора"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатъкът не бе обработен. Моля, опитайте отново."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Отпечатъкът не може да бъде разпознат. Опитайте отново."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Почистете сензора за отпечатъци и опитайте отново"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Почистете сензора и опитайте отново"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Натиснете добре върху сензора"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Преместихте пръста си твърде бавно. Моля, опитайте отново."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Опитайте с друг отпечатък"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Твърде светло е"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Установено е натискане на бутона за захранване"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Опитайте да коригирате"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Всеки път променяйте леко позицията на пръста си"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицето е удостоверено. Моля, натиснете „Потвърждаване“"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хардуерът за отпечатъци не е налице."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не може да се настрои отпечатък"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Времето за изчакване за отпечатък изтече. Опитайте отново."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Настройването на отпечатък не завърши навреме. Опитайте отново."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Операцията за отпечатък е анулирана."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Операцията за удостоверяване чрез отпечатък бе анулирана от потребителя."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Твърде много опити. Пробвайте отново по-късно."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Твърде много опити. Вместо това използвайте опция за заключване на екрана."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Твърде много опити. Вместо това използвайте опция за заключване на екрана."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Опитайте отново."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Отпечатъкът не може да бъде обработен. Опитайте отново."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Няма регистрирани отпечатъци."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Посетете оторизиран сервиз."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Моделът на лицето ви не бе създаден. Опитайте пак."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Твърде светло е. Опитайте при по-слабо осветление."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Няма достатъчно светлина"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Отдалечете телефона"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Доближете телефона"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Преместете телефона по-високо"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Приложенията се стартират."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Зареждането завършва."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Натиснахте бутона за включване/изключване – това обикновено изключва екрана.\n\nОпитайте да докоснете леко, докато настройвате отпечатъка си."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Докоснете за изключване на екрана"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Изключване на екрана"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Изключете екрана за изход от настройката"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Изключване"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Напред с потвърждаването на отпечатъка?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Натиснахте бутона за включване/изключване – това обикновено изключва екрана.\n\nОпитайте да докоснете леко, за да потвърдите отпечатъка си."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Изключване на екрана"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Телевизор"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Докинг станц.: Високогов."</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Външно устройство"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Слушалки"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Система"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 2aac0c9..09033e9 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্রিন লক ব্যবহার করুন"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"চালিয়ে যেতে আপনার স্ক্রিন লক ব্যবহার করুন"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"সেন্সর জোরে প্রেস করুন"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"আঙ্গুলের ছাপ প্রক্রিয়া করা যায়নি৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ফিঙ্গারপ্রিন্ট শনাক্ত করা যায়নি। আবার চেষ্টা করুন।"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"আঙ্গুলের ছাপের সেন্সর পরিষ্কার করে আবার চেষ্টা করুন"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"সেন্সর পরিষ্কার করে আবার চেষ্টা করুন"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"সেন্সর জোরে প্রেস করুন"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"আঙ্গুল খুব ধীরে সরানো হয়েছে৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"অন্য আঙ্গুলের ছাপ দিয়ে চেষ্টা করুন"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"অত্যন্ত উজ্জ্বল"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"পাওয়ার বোতাম প্রেস করার বিষয়টি শনাক্ত করা হয়েছে"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"অ্যাডজাস্ট করার চেষ্টা করুন"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"প্রতিবার আঙ্গুলের ছাপ সেটআপ করার সময় আপনার আঙ্গুলের অবস্থান সামান্য পরিবর্তন করুন"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ফেস যাচাই করা হয়েছে, \'কনফার্ম করুন\' বোতাম প্রেস করুন"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"আঙ্গুলের ছাপ নেওয়ার হার্ডওয়্যার অনুপলব্ধ৷"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"আঙ্গুলের ছাপ সেট-আপ করতে পারছি না"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"আঙ্গুলের ছাপ নেওয়ার সময়সীমা শেষ হযেছে৷ আবার চেষ্টা করুন৷"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ফিঙ্গারপ্রিন্ট সেট-আপ করার সময় সীমা পেরিয়ে গেছে। আবার চেষ্টা করুন।"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"আঙ্গুলের ছাপ অপারেশন বাতিল করা হয়েছে৷"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ব্যবহারকারী আঙ্গুলের ছাপের অপারেশনটি বাতিল করেছেন।"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"অনেকবার প্রচেষ্টা করা হয়েছে৷ পরে আবার চেষ্টা করুন৷"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"অনেকবার চেষ্টা করেছেন। পরিবর্তে স্ক্রিন লক ব্যবহার করুন।"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"অনেকবার চেষ্টা করেছেন। পরিবর্তে স্ক্রিন লক ব্যবহার করুন।"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"আবার চেষ্টা করুন৷"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ফিঙ্গারপ্রিন্ট প্রসেস করা যায়নি। আবার চেষ্টা করুন।"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনও আঙ্গুলের ছাপ নথিভুক্ত করা হয়নি।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"একজন মেরামতি মিস্ত্রির কাছে যান।"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"ফেস মডেল তৈরি করা যাচ্ছে না। আবার চেষ্টা করুন।"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"খুব উজ্জ্বল। আলো কমিয়ে চেষ্টা করে দেখুন।"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"পর্যাপ্ত আলো নেই"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ফোন আরও দূরে নিয়ে যান"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ফোন আরও কাছে নিয়ে আসুন"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ফোন আরও উঁচুতে তুলুন"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"অ্যাপ্লিকেশানগুলি শুরু করা হচ্ছে৷"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"চালু করা সম্পূর্ণ হচ্ছে৷"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"আপনি \'পাওয়ার\' বোতাম প্রেস করেছেন — এর ফলে সাধারণত স্ক্রিন বন্ধ হয়ে যায়।\n\nআঙ্গুলের ছাপ সেট-আপ করার সময় হালকাভাবে ট্যাপ করে দেখুন।"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"স্ক্রিন বন্ধ করতে ট্যাপ করুন"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"স্ক্রিন বন্ধ করুন"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"সেট-আপ সম্পূর্ণ করতে, স্ক্রিন বন্ধ করুন"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"বন্ধ করুন"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"আঙ্গুলের ছাপ যাচাই করা চালিয়ে যাবেন?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"আপনি \'পাওয়ার\' বোতাম প্রেস করেছেন — এর ফলে সাধারণত স্ক্রিন বন্ধ হয়ে যায়।\n\nআঙ্গুলের ছাপ যাচাই করতে হালকাভাবে ট্যাপ করে দেখুন।"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"স্ক্রিন বন্ধ করুন"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"টিভি"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ফোন"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ডক স্পিকার"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"এক্সটার্নাল ডিভাইস"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"হেডফোন"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"সিস্টেম"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 3c87b0d..d741095 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristi zaključavanje ekrana"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Unesite zaključavanje ekrana da nastavite"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Čvrsto pritisnite senzor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Nije moguće prepoznati otisak prsta. Pokušajte ponovo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Očistite senzor za otisak prsta i pokušajte ponovo"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Očistite senzor i pokušajte ponovo"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Čvrsto pritisnite senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Presporo ste pomjerili prst. Pokušajte ponovo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Pokušajte s drugim otiskom prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvijetlo"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Otkriveno je pritiskanje dugmeta za uključivanje"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pokušajte podesiti"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put pomalo promijenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je provjereno, pritisnite dugme za potvrdu"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardver za otisak prsta nije dostupan."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nije moguće postaviti otisak prsta"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Vrijeme za prepoznavanje otiska prsta je isteklo. Pokušajte ponovo."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vrijeme za postavljanje otiska prsta je isteklo. Pokušajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Radnja s otiskom prsta je otkazana."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Korisnik je otkazao radnju s otiskom prsta."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Umjesto toga koristite zaključavanje ekrana."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Umjesto toga koristite zaključavanje ekrana."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Pokušajte ponovo."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nije moguće obraditi otisak prsta. Pokušajte ponovo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije prijavljen nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Posjetite pružaoca usluga za popravke."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Nije moguće kreirati model lica. Pokušajte ponovo."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Previše svijetlo. Probajte s blažim osvjetljenjem."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nema dovoljno svjetlosti"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Odmaknite telefon"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Primaknite telefon"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Pomjerite telefon naviše"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Pokretanje pri kraju."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Pritisnuli ste dugme za uključivanje. Tako se obično isključuje ekran.\n\nPokušajte ga lagano dodirnuti dok postavljate otisak prsta."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Dodirnite da isključite ekran"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Isključi ekran"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Da završite postavljanje, isključite ekran"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Isključi"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Nastaviti s potvrđivanjem otiska prsta?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Pritisnuli ste dugme za uključivanje. Tako se obično isključuje ekran.\n\nPokušajte ga lagano dodirnuti da potvrdite otisak prsta."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Isključi ekran"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Zvučnici priključne stanice"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Vanjski uređaj"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Slušalice"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 317c004..a334461 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utilitza el bloqueig de pantalla"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introdueix el teu bloqueig de pantalla per continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Prem el sensor de manera ferma"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No s\'ha pogut processar l\'empremta digital. Torna-ho a provar."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"No es pot reconèixer l\'empremta digital. Torna-ho a provar."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Neteja el sensor d\'empremtes digitals i torna-ho a provar"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Neteja el sensor i torna-ho a provar"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Prem el sensor de manera ferma"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"El dit s\'ha mogut massa lentament. Torna-ho a provar."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prova una altra empremta digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Hi ha massa llum"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"S\'ha premut el botó d\'engegada"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prova d\'ajustar l\'empremta digital"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Canvia lleugerament la posició del dit en cada intent"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Cara autenticada; prem el botó per confirmar"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El maquinari d\'empremtes digitals no està disponible."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"No es pot configurar l\'empremta digital"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"S\'ha esgotat el temps d\'espera per a l\'empremta digital. Torna-ho a provar."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Temps d\'espera esgotat per configurar l\'empremta digital. Torna-ho a provar."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"S\'ha cancel·lat l\'operació d\'empremta digital."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"L\'usuari ha cancel·lat l\'operació d\'empremta digital."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"S\'han produït massa intents. Torna-ho a provar més tard."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Massa intents. Utilitza el bloqueig de pantalla."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Massa intents. Utilitza el bloqueig de pantalla."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Torna-ho a provar."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"No es pot processar l\'empremta digital. Torna-ho a provar."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No s\'ha registrat cap empremta digital."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes digitals."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visita un proveïdor de reparacions."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"No es pot crear el model facial. Torna-ho a provar."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Massa brillant Prova una il·luminació més suau."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"No hi ha prou llum"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Allunya\'t del telèfon"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Apropa el telèfon"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Mou el telèfon més amunt"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"S\'estan iniciant les aplicacions."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"S\'està finalitzant l\'actualització."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Has premut el botó d\'engegada, fet que sol apagar la pantalla.\n\nProva de tocar-lo lleugerament en configurar l\'empremta digital."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Toca per apagar la pantalla"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Apaga la pantalla"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Per finalitzar, apaga la pantalla"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Desactiva"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Vols continuar verificant l\'empremta?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Has premut el botó d\'engegada, fet que sol apagar la pantalla.\n\nProva de tocar-lo lleugerament per verificar l\'empremta digital."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Apaga la pantalla"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Televisor"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telèfon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Altaveus de la base"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispositiu extern"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Auriculars"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index cbd2df6..831ccab 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použít zámek obrazovky"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Pokračujte zadáním zámku obrazovky"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pevně zatlačte na senzor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Zpracování otisku prstu se nezdařilo. Zkuste to znovu."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Otisk prstu se nepodařilo rozpoznat. Zkuste to znovu."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistěte snímač otisků prstů a zkuste to znovu"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistěte senzor a zkuste to znovu"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Zatlačte silně na senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pohyb prstem byl příliš pomalý. Zkuste to znovu."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zkuste jiný otisk prstu"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Je příliš světlo"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Bylo zjištěno stisknutí vypínače"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Zkuste provést úpravu"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Pokaždé lehce změňte polohu prstu"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Obličej byl ověřen, stiskněte tlačítko pro potvrzení"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Není k dispozici hardware ke snímání otisků prstů."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Otisk prstu se nepodařilo nastavit"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Časový limit sejmutí otisku prstu vypršel. Zkuste to znovu."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Časový limit nastavení otisku prstu vypršel. Zkuste to znovu."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operace otisku prstu byla zrušena."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Uživatel operaci s otiskem prstu zrušil."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Příliš mnoho pokusů. Zkuste to později."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Příliš mnoho pokusů. Použijte zámek obrazovky."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Příliš mnoho pokusů. Použijte zámek obrazovky."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Zkuste to znovu."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Otisk prstu nelze zpracovat. Zkuste to znovu."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nejsou zaregistrovány žádné otisky prstů."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Navštivte servis"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Model se nepodařilo vytvořit. Zkuste to znovu."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Je příliš světlo. Zmírněte osvětlení."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nedostatečné osvětlení"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Umístěte telefon dál"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Umístěte telefon blíž"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Umístěte telefon výš"</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Spouštění aplikací."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Dokončování inicializace."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Stiskli jste vypínač – tím se obvykle vypíná obrazovka.\n\nPři nastavování otisku prstu je třeba klepat lehce."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Klepnutím vypnete obrazovku"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Vypnout obrazovku"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"K dokončení nastavení je nutné vypnout obrazovku"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Vypnout"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Pokračovat v ověřování otisku prstu?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Stiskli jste vypínač – tím se obvykle vypíná obrazovka.\n\nZkuste lehkým klepnutím ověřit svůj otisk prstu."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Vypnout obrazovku"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Televize"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Reproduktory doku"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Externí zařízení"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Sluchátka"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Systém"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 083c42c..b35719d 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Brug skærmlås"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Angiv din skærmlås for at fortsætte"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Hold fingeren nede på læseren"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingeraftrykket kunne ikke behandles. Prøv igen."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Fingeraftrykket kan ikke genkendes. Prøv igen."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengør fingeraftrykslæseren, og prøv igen"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengør læseren, og prøv igen"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Hold fingeren nede på læseren"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du bevægede fingeren for langsomt. Prøv igen."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv med et andet fingeraftryk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Der er for lyst"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Et tryk på afbryderknappen er blevet registreret"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prøv at justere den"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Flyt fingeren en smule hver gang"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansigtet er godkendt. Tryk på Bekræft."</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardwaren til fingeraftryk er ikke tilgængelig."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Fingeraftrykket kan ikke gemmes"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Registrering af fingeraftryk fik timeout. Prøv igen."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Konfigurationen af fingeraftryk fik timeout. Prøv igen."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingeraftrykshandlingen blev annulleret."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeraftrykshandlingen blev annulleret af brugeren."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Du har prøvet for mange gange. Prøv igen senere."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Du har brugt for mange forsøg. Brug skærmlåsen i stedet."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Du har brugt for mange forsøg. Brug skærmlåsen i stedet."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Prøv igen."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Fingeraftrykket kan ikke behandles. Prøv igen."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Der er ikke registreret nogen fingeraftryk."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Få den repareret."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Din ansigtsmodel kan ikke oprettes. Prøv igen."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Der er for lyst. Prøv en mere dæmpet belysning."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Der er ikke nok lys"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Flyt telefonen længere væk"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Flyt telefonen tættere på"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Løft telefonen højere op"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Åbner dine apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Gennemfører start."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Du har trykket på afbryderknappen, hvilket som regel slukker skærmen.\n\nPrøv at trykke let på knappen, mens du konfigurerer dit fingeraftryk."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tryk for at slukke skærmen"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Sluk skærm"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Sluk skærmen for at afslutte konfigurationen"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Deaktiver"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Vil du bekræfte dit fingeraftryk?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Du har trykket på afbryderknappen, hvilket som regel slukker skærmen.\n\nPrøv at trykke let på knappen for at bekræfte dit fingeraftryk."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Sluk skærm"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Tv"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dockstationens højttalere"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Ekstern enhed"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Hovedtelefoner"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index fc8eadaf..2d151d9 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Displaysperre verwenden"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Displaysperre eingeben, um fortzufahren"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Drücke fest auf den Sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingerabdruck konnte nicht verarbeitet werden. Bitte versuche es noch einmal."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Fingerabdruck wurde nicht erkannt. Versuch es noch einmal."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Reinige den Fingerabdrucksensor und versuch es noch einmal"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Reinige den Sensor und versuche es noch einmal"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Drücke fest auf den Sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger zu langsam bewegt. Bitte versuche es noch einmal."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Anderen Fingerabdruck verwenden"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zu hell"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Drücken der Ein-/Aus-Taste erkannt"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Versuche, den Finger anders aufzulegen"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ändere jedes Mal leicht die Position deines Fingers"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gesicht authentifiziert, bitte bestätigen"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerabdruckhardware nicht verfügbar"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Fingerabdruck konnte nicht eingerichtet werden"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Zeitüberschreitung bei Fingerabdruck. Bitte versuche es noch einmal."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Zeitüberschreitung bei Fingerabdruckeinrichtung. Versuch es noch einmal."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerabdruckvorgang abgebrochen"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Vorgang der Fingerabdruckauthentifizierung vom Nutzer abgebrochen."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Zu viele Versuche, bitte später noch einmal versuchen"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Zu viele Versuche. Verwende stattdessen die Displaysperre."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Zu viele Versuche. Verwende stattdessen die Displaysperre."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Bitte versuche es noch einmal."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Fingerabdruck kann nicht verarbeitet werden. Versuch es noch einmal."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Keine Fingerabdrücke erfasst."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Suche einen Reparaturdienstleister auf."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Kein Gesichtsmodell möglich. Versuche es erneut."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Zu hell. Schwächere Beleuchtung ausprobieren."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nicht genug Licht"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Bewege das Smartphone weiter weg"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Bewege das Smartphone näher heran"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Bewege das Smartphone nach oben"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Apps werden gestartet..."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Start wird abgeschlossen..."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Du hast die Ein-/Aus-Taste gedrückt — damit wird der Bildschirm ausgeschaltet.\n\nTippe die Taste leicht an, um deinen Fingerabdruck einzurichten."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tippen, um Display auszuschalten"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Display ausschalten"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Zum Beenden der Einrichtung Bildschirm deaktivieren"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Deaktivieren"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Mit der Fingerabdruckprüfung fortfahren?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Du hast die Ein-/Aus-Taste gedrückt — damit wird der Bildschirm ausgeschaltet.\n\nTippe die Taste leicht an, um mit deinem Fingerabdruck deine Identität zu bestätigen."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Ausschalten"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dock-Lautsprecher"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Externes Gerät"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Kopfhörer"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index c76b2b0..d3a9c17 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Χρήση κλειδώματος οθόνης"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Χρησιμοποιήστε το κλείδωμα οθόνης για να συνεχίσετε"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Πιέστε σταθερά τον αισθητήρα"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Δεν ήταν δυνατή η επεξεργασία του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Δεν είναι δυνατή η αναγνώριση του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Καθαρίστε τον αισθητήρα δακτυλικών αποτυπωμάτων και δοκιμάστε ξανά"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Καθαρίστε τον αισθητήρα και δοκιμάστε ξανά"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Πιέστε σταθερά τον αισθητήρα"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Πολύ αργή κίνηση δαχτύλου. Δοκιμάστε ξανά."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Δοκιμάστε άλλο δακτυλικό αποτύπωμα"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Υπερβολικά έντονος φωτισμός"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Εντοπίστηκε πάτημα του κουμπιού λειτουργίας"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Δοκιμάστε να το προσαρμόσετε"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Αλλάζετε ελαφρώς τη θέση του δακτύλου σας κάθε φορά."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Έγινε έλεγχος ταυτότητας προσώπου, πατήστε \"Επιβεβαίωση\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Ο εξοπλισμός δακτυλικού αποτυπώματος δεν είναι διαθέσιμος."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Δεν είναι δυνατή η ρύθμιση του δακτυλικού αποτυπώματος"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Λήξη χρονικού ορίου δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Λήξη χρονικού ορίου ρύθμισης δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Η λειτουργία δακτυλικού αποτυπώματος ακυρώθηκε."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Η λειτουργία δακτυλικού αποτυπώματος ακυρώθηκε από τον χρήστη."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Πάρα πολλές προσπάθειες. Δοκιμάστε ξανά αργότερα."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Υπερβολικά πολλές προσπάθειες. Χρησιμοποιήστε εναλλακτικά το κλείδωμα οθόνης."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Υπερβολικά πολλές προσπάθειες. Χρησιμοποιήστε εναλλακτικά το κλείδωμα οθόνης."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Δοκιμάστε ξανά."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Δεν είναι δυνατή η επεξεργασία του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Δεν έχουν καταχωριστεί δακτυλικά αποτυπώματα."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Επισκεφτείτε έναν πάροχο υπηρεσιών επισκευής."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Αδύν. η δημιουρ. του μοντ. προσώπ. Δοκιμάστε ξανά."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Υπερβολικά έντονος φωτισμός. Δοκιμάστε πιο ήπιο."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Δεν υπάρχει αρκετό φως"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Απομακρύνετε περισσότερο το τηλέφωνο"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Φέρτε πιο κοντά το τηλέφωνό σας"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Μετακινήστε το τηλέφωνο πιο ψηλά"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Έναρξη εφαρμογών."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Ολοκλήρωση εκκίνησης."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Πατήσατε το κουμπί λειτουργίας. Αυτό συνήθως απενεργοποιεί την οθόνη.\n\nΔοκιμάστε να πατήσετε απαλά κατά τη ρύθμιση του δακτυλικού σας αποτυπώματος."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Πατήστε για απενεργοποίηση οθόνης"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Απενεργοπ. οθόνης"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Απενεργ. την οθόνη για ολοκλήρ. ρύθμισης"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Απενεργοποίηση"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Συνέχιση επαλήθευσης δακτ. αποτυπώματος;"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Πατήσατε το κουμπί λειτουργίας. Αυτό συνήθως απενεργοποιεί την οθόνη.\n\nΔοκιμάστε να πατήστε απαλά για να επαληθεύσετε το δακτυλικό σας αποτύπωμα."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Απενεργοπ. οθόνης"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Τηλεόραση"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Τηλέφωνο"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Ηχεία βάσης σύνδεσης"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Εξωτερική συσκευή"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Ακουστικά"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Σύστημα"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 8591467..fcc6cdd 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Can’t recognise fingerprint. Try again."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Press firmly on the sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger moved too slow. Please try again."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Power press detected"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Fingerprint timeout reached. Try again."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Too many attempts. Try again later."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Try again."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Can’t create your face model. Try again."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Not enough light"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Move phone further away"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Move phone closer"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Move phone higher"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finishing boot."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"You pressed the power button – this usually turns off the screen.\n\nTry tapping lightly while setting up your fingerprint."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tap to turn off screen"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Turn off screen"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"To end setup, turn off screen"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Turn off"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continue verifying your fingerprint?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"You pressed the power button – this usually turns off the screen.\n\nTry tapping lightly to verify your fingerprint."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Turn off screen"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Phone"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dock speakers"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"External device"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Headphones"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 08097a5..de1516c 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Can’t recognise fingerprint. Try again."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Press firmly on the sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger moved too slow. Please try again."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Power press detected"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Fingerprint timeout reached. Try again."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Too many attempts. Try again later."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Try again."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Can’t create your face model. Try again."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Not enough light"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Move phone further away"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Move phone closer"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Move phone higher"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finishing boot."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"You pressed the power button – this usually turns off the screen.\n\nTry tapping lightly while setting up your fingerprint."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tap to turn off screen"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Turn off screen"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"To end setup, turn off screen"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Turn off"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continue verifying your fingerprint?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"You pressed the power button – this usually turns off the screen.\n\nTry tapping lightly to verify your fingerprint."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Turn off screen"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Phone"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dock speakers"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"External device"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Headphones"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bf82587..ef91ac2 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Can’t recognise fingerprint. Try again."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Press firmly on the sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger moved too slow. Please try again."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Power press detected"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Fingerprint timeout reached. Try again."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Too many attempts. Try again later."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Try again."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Can’t create your face model. Try again."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Not enough light"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Move phone further away"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Move phone closer"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Move phone higher"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finishing boot."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"You pressed the power button – this usually turns off the screen.\n\nTry tapping lightly while setting up your fingerprint."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tap to turn off screen"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Turn off screen"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"To end setup, turn off screen"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Turn off"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continue verifying your fingerprint?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"You pressed the power button – this usually turns off the screen.\n\nTry tapping lightly to verify your fingerprint."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Turn off screen"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Phone"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dock speakers"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"External device"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Headphones"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 110e68f..6d7f422 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Can’t recognise fingerprint. Try again."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Press firmly on the sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger moved too slow. Please try again."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Power press detected"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingerprint hardware not available."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Can’t set up fingerprint"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Fingerprint timeout reached. Try again."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingerprint setup timed out. Try again."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingerprint operation cancelled."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingerprint operation cancelled by user."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Too many attempts. Try again later."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Too many attempts. Use screen lock instead."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Too many attempts. Use screen lock instead."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Try again."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Can’t process fingerprint. Try again."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Can’t create your face model. Try again."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Not enough light"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Move phone further away"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Move phone closer"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Move phone higher"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finishing boot."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"You pressed the power button – this usually turns off the screen.\n\nTry tapping lightly while setting up your fingerprint."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tap to turn off screen"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Turn off screen"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"To end setup, turn off screen"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Turn off"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continue verifying your fingerprint?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"You pressed the power button – this usually turns off the screen.\n\nTry tapping lightly to verify your fingerprint."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Turn off screen"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Phone"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dock speakers"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"External device"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Headphones"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index ddb93a8..4fee71d 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎Use screen lock‎‏‎‎‏‎"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎Enter your screen lock to continue‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‎‎Press firmly on the sensor‎‏‎‎‏‎"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎Couldn\'t process fingerprint. Please try again.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎Can’t recognize fingerprint. Try again.‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎Clean fingerprint sensor and try again‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎Clean sensor and try again‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‎Press firmly on the sensor‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎Finger moved too slow. Please try again.‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎Try another fingerprint‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‎Too bright‎‏‎‎‏‎"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‎Power press detected‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‏‎‎‎Try adjusting‎‏‎‎‏‎"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎Change the position of your finger slightly each time‎‏‎‎‏‎"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎Face authenticated, please press confirm‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎Fingerprint hardware not available.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‎‎‎Can’t set up fingerprint‎‏‎‎‏‎"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎Fingerprint time out reached. Try again.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‎Fingerprint setup timed out. Try again.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‎Fingerprint operation canceled.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎Fingerprint operation canceled by user.‎‏‎‎‏‎"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎Too many attempts. Try again later.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎Too many attempts. Use screen lock instead.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎Too many attempts. Use screen lock instead.‎‏‎‎‏‎"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎Try again.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎Can’t process fingerprint. Try again.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‏‎No fingerprints enrolled.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎This device does not have a fingerprint sensor.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎Sensor temporarily disabled.‎‏‎‎‏‎"</string>
@@ -1248,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎Starting apps.‎‏‎‎‏‎"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎Finishing boot.‎‏‎‎‏‎"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‎You pressed the power button — this usually turns off the screen.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Try tapping lightly while setting up your fingerprint.‎‏‎‎‏‎"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎Tap to turn off screen‎‏‎‎‏‎"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎Turn off screen‎‏‎‎‏‎"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎To end setup, turn off screen‎‏‎‎‏‎"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‎‎‎‎Turn off‎‏‎‎‏‎"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎Continue verifying your fingerprint?‎‏‎‎‏‎"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎You pressed the power button — this usually turns off the screen.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Try tapping lightly to verify your fingerprint.‎‏‎‎‏‎"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎Turn off screen‎‏‎‎‏‎"</string>
@@ -1610,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎TV‎‏‎‎‏‎"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎Phone‎‏‎‎‏‎"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎Dock speakers‎‏‎‎‏‎"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎HDMI‎‏‎‎‏‎"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎External Device‎‏‎‎‏‎"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎Headphones‎‏‎‎‏‎"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎USB‎‏‎‎‏‎"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎System‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 933ccfb..efaaa97 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ingresa tu bloqueo de pantalla para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Presiona con firmeza el sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se pudo procesar la huella dactilar. Vuelve a intentarlo."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"No se reconoce la huella dactilar. Vuelve a intentarlo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpia el sensor de huellas dactilares y vuelve a intentarlo"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpia el sensor y vuelve a intentarlo"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Presiona con firmeza el sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Moviste el dedo muy lento. Vuelve a intentarlo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella dactilar"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Se detectó una presión del botón de encendido"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prueba ajustarla"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia un poco la posición del dedo cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se autenticó el rostro; presiona Confirmar"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El hardware para detectar huellas dactilares no está disponible."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"No se puede configurar la huella dactilar"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Finalizó el tiempo de espera para la huella dactilar. Vuelve a intentarlo."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Se agotó el tiempo de espera para configurar la huella dactilar. Vuelve a intentarlo."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Se canceló la operación de huella dactilar."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"El usuario canceló la operación de huella dactilar."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Demasiados intentos. Vuelve a intentarlo más tarde."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Demasiados intentos. Utiliza el bloqueo de pantalla en su lugar."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Demasiados intentos. Utiliza el bloqueo de pantalla en su lugar."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Vuelve a intentarlo."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"No se puede procesar la huella dactilar. Vuelve a intentarlo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se registraron huellas digitales."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas dactilares."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Consulta a un proveedor de reparaciones."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"No se puede crear modelo de rostro. Reinténtalo."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Demasiado brillante. Prueba con menos iluminación."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"No hay suficiente luz"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Aleja el teléfono un poco más"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Acerca el teléfono"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Mueve el teléfono hacia arriba"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicaciones"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalizando el inicio"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Presionaste el botón de encendido. Por lo general, esta acción apaga la pantalla.\n\nPresiona suavemente mientras configuras tu huella dactilar."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Presiona para apagar la pantalla"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Apagar pantalla"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Para finalizar, apaga la pantalla"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Apagar"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"¿Verificar huella dactilar?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Presionaste el botón de encendido. Por lo general, esta acción apaga la pantalla.\n\nPresiona suavemente para verificar tu huella dactilar."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Apagar pantalla"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Dispositivo"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Altavoces del conector"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispositivo externo"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Auriculares"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 9795e23..e6c088f 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introduce tu bloqueo de pantalla para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Mantén pulsado firmemente el sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se ha podido procesar la huella digital. Vuelve a intentarlo."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"No se puede reconocer la huella digital. Inténtalo de nuevo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpia el sensor de huellas digitales e inténtalo de nuevo"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpia el sensor e inténtalo de nuevo"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Mantén pulsado firmemente el sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Has movido el dedo demasiado despacio. Vuelve a intentarlo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Se ha pulsado el botón de encendido"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prueba a mover el dedo"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia ligeramente el dedo de posición cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se ha autenticado la cara, pulsa para confirmar"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El hardware de huella digital no está disponible."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"No se puede configurar la huella digital"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Se ha alcanzado el tiempo de espera de la huella digital. Vuelve a intentarlo."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tiempo de espera para configurar la huella digital agotado. Inténtalo de nuevo."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Se ha cancelado la operación de huella digital."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"El usuario ha cancelado la operación de huella digital."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Demasiados intentos. Vuelve a intentarlo más tarde."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Demasiados intentos. Usa el bloqueo de pantalla."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Demasiados intentos. Usa el bloqueo de pantalla."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Vuelve a intentarlo."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"No se puede procesar la huella digital. Inténtalo de nuevo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se ha registrado ninguna huella digital."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visita un proveedor de reparaciones."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"No se puede crear tu modelo. Inténtalo de nuevo."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Hay demasiada luz. Busca un sitio menos iluminado."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"No hay suficiente luz"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Aleja el teléfono"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Acerca el teléfono"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Sube el teléfono"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicaciones"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalizando inicio..."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Has pulsado el botón de encendido, lo que suele apagar la pantalla.\n\nPrueba a apoyar el dedo ligeramente para verificar tu huella digital."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Toca para apagar la pantalla"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Apagar pantalla"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Apaga la pantalla para finalizar"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Apagar"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"¿Seguir verificando tu huella digital?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Has pulsado el botón de encendido, lo que suele apagar la pantalla.\n\nPrueba a apoyar el dedo ligeramente para verificar tu huella digital."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Apagar pantalla"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Teléfono"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Altavoces de la base"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispositivo externo"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Auriculares"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index fe7549e..7f761c4 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekraaniluku kasutamine"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jätkamiseks sisestage oma ekraanilukk"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Vajutage tugevalt andurile"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sõrmejälge ei õnnestunud töödelda. Proovige uuesti."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Sõrmejälge ei õnnestu tuvastada. Proovige uuesti."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Puhastage sõrmejäljeandur ja proovige uuesti"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Puhastage andur ja proovige uuesti"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Vajutage tugevalt andurile"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Sõrm liikus liiga aeglaselt. Proovige uuesti."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proovige teist sõrmejälge"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liiga ere"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Tuvastati toitenupu vajutamine"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Proovige kohandada"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Muutke iga kord pisut oma sõrme asendit"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Nägu on autenditud, vajutage käsku Kinnita"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Sõrmejälje riistvara pole saadaval."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Sõrmejälge ei saa seadistada"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Sõrmejälje riistvara taimeri ajalõpp. Proovige uuesti."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Sõrmejälje seadistamine aegus. Proovige uuesti."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Sõrmejälje toiming tühistati."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Kasutaja tühistas sõrmejälje kasutamise."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Liiga palju katseid. Proovige hiljem uuesti."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Liiga palju katseid. Kasutage selle asemel ekraanilukku."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Liiga palju katseid. Kasutage selle asemel ekraanilukku."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Proovige uuesti."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Sõrmejälge ei õnnestu töödelda. Proovige uuesti."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ühtegi sõrmejälge pole registreeritud."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Külastage remonditeenuse pakkujat."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Teie näomudelit ei saa luua. Proovige uuesti."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Liiga ere. Proovige hämaramat valgust."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Pole piisavalt valgust"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Liigutage telefoni kaugemale"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Liigutage telefoni lähemale"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Liigutage telefoni kõrgemale"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Rakenduste käivitamine."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Käivitamise lõpuleviimine."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Vajutasite toitenuppu – tavaliselt lülitab see ekraani välja.\n\nPuudutage õrnalt ja seadistage oma sõrmejälg."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Puudutage ekraani väljalülitamiseks"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Lülita ekraan välja"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Seadistuse lõpet. lülitage ekraan välja"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Lülita välja"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Kas jätkata sõrmejälje kinnitamist?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Vajutasite toitenuppu – tavaliselt lülitab see ekraani välja.\n\nPuudutage õrnalt, et oma sõrmejälg kinnitada."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Lülita ekraan välja"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Teler"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Doki kõlarid"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Väline seade"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Kõrvaklapid"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Süsteem"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 7f424eb..ee07ce1 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Erabili pantailaren blokeoa"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Aurrera egiteko, desblokeatu pantailaren blokeoa"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Sakatu irmo sentsorea"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ezin izan da prozesatu hatz-marka. Saiatu berriro."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Ezin da hauteman hatz-marka. Saiatu berriro."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Garbitu hatz-marken sentsorea eta saiatu berriro"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Garbitu sentsorea eta saiatu berriro"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Sakatu irmo sentsorea"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Mantsoegi mugitu duzu hatza. Saiatu berriro."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Erabili beste hatz-marka bat"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Argi gehiegi dago"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Hauteman egin da etengailua sakatu dela"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Saiatu doituta"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Aldi bakoitzean, aldatu hatzaren posizioa apur bat"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autentifikatu da aurpegia; sakatu Berretsi"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hatz-marken hardwarea ez dago erabilgarri."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Ezin da konfiguratu hatz-marka"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Hatz-markak prozesatzeko denbora-muga gainditu da. Saiatu berriro."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Gainditu egin da hatz-marka konfiguratzeko denbora-muga. Saiatu berriro."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Hatz-markaren eragiketa bertan behera utzi da."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Erabiltzaileak bertan behera utzi du hatz-marka bidezko eragiketa."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Saiakera gehiegi egin dituzu. Saiatu berriro geroago."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Saiakera gehiegi egin dira. Erabili pantailaren blokeoa."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Saiakera gehiegi egin dira. Erabili pantailaren blokeoa."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Saiatu berriro."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Ezin da prozesatu hatz-marka. Saiatu berriro."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ez da erregistratu hatz-markarik."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Jarri harremanetan konponketak egiten dituen hornitzaile batekin."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Ezin da sortu aurpegi-eredua. Saiatu berriro."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Argi gehiegi dago. Joan toki ilunago batera."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Ilunegi dago"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Urrundu telefonoa"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Hurbildu telefonoa"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Igo telefonoa"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Aplikazioak abiarazten."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Bertsio-berritzea amaitzen."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Etengailua sakatu duzu; pantaila itzaltzeko balio du horrek.\n\nUki ezazu arin, hatz-marka konfiguratu bitartean."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Pantaila itzaltzeko, sakatu hau"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Itzali pantaila"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Konfiguratzen amaitzeko, itzali pantaila"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Itzali"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Hatz-marka egiaztatzen jarraitu nahi duzu?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Etengailua sakatu duzu; pantaila itzaltzeko balio du horrek.\n\nUki ezazu arin, hatz-marka egiaztatzeko."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Itzali pantaila"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Telebista"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefonoa"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Konektatu bozgorailuak oinarrira"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Kanpoko gailua"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Entzungailuak"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 83821a3..82c716f 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"از قفل صفحه استفاده کنید"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"برای ادامه، قفل صفحه‌تان را وارد کنید"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"محکم روی حسگر فشار دهید"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"اثرانگشت پردازش نشد. لطفاً دوباره امتحان کنید."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"اثر انگشت شناسایی نشد. دوباره امتحان کنید."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"حسگر اثر انگشت را تمیز و دوباره امتحان کنید"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"حسگر را تمیز و دوباره امتحان کنید"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"محکم روی حسگر فشار دهید"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"حرکت انگشت خیلی آهسته بود. لطفاً دوباره امتحان کنید."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"اثر انگشت دیگری را امتحان کنید"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"خیلی روشن است"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"فشردن دکمه روشن/ خاموش شناسایی شد"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"اثر انگشت را تنظیم کنید"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"هربار موقعیت انگشتتان را کمی تغییر دهید"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چهره اصالت‌سنجی شد، لطفاً تأیید را فشار دهید"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"سخت‌افزار اثرانگشت در دسترس نیست."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"اثر انگشت راه‌اندازی نشد"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"مهلت ثبت اثر انگشت به‌پایان رسید. دوباره امتحان کنید."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"مهلت راه‌اندازی اثر انگشت به‌پایان رسید. دوباره امتحان کنید."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"عملکرد اثر انگشت لغو شد."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"کاربر عملیات اثر انگشت را لغو کرد"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"تلاش‌های زیادی انجام شده است. بعداً دوباره امتحان کنید."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"تلاش‌ها از حد مجاز بیشتر شده است. به‌جای آن از قفل صفحه استفاده کنید."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"تلاش‌های بیش‌ازحد. حالا از قفل صفحه استفاده کنید."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"دوباره امتحان کنید."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"اثر انگشت پردازش نشد. دوباره امتحان کنید."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"اثر انگشتی ثبت نشده است."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر به‌طور موقت غیرفعال است."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"به ارائه‌دهنده خدمات تعمیر مراجعه کنید."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"مدل چهره ایجاد نشد. دوباره امتحان کنید."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"خیلی روشن است. روشنایی‌اش را ملایم‌تر کنید."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"نور کافی نیست"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"تلفن را دورتر ببرید"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"تلفن را نزدیک‌تر بیاورید"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"تلفن را بالاتر ببرید"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"درحال آغاز کردن برنامه‌ها."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"درحال اتمام راه‌اندازی."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"دکمه روشن/ خاموش را فشار دادید — این کار معمولاً صفحه‌نمایش را خاموش می‌کند.\n\nهنگام راه‌اندازی اثر انگشت، آرام ضربه بزنید."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"برای خاموش کردن صفحه‌نمایش، ضربه بزنید"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"خاموش کردن صفحه"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"برای اتمام راه‌اندازی، صفحه را خاموش کنید"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"خاموش کردن"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"تأیید اثر انگشت را ادامه می‌دهید؟"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"دکمه روشن/ خاموش را فشار دادید — این کار معمولاً صفحه‌نمایش را خاموش می‌کند.\n\nبرای تأیید اثر انگشتتان، آرام ضربه بزنید."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"خاموش کردن صفحه"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"تلویزیون"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"تلفن"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"بلندگوهای جایگاه"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"دستگاه خارجی"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"هدفون‌ها"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"سیستم"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8798ffc..5988783 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Käytä näytön lukitusta"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jatka lisäämällä näytön lukituksen avaustapa"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Paina anturia voimakkaasti"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sormenjäljen prosessointi epäonnistui. Yritä uudelleen."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Sormenjälkeä ei voi tunnistaa. Yritä uudelleen."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Puhdista sormenjälkitunnistin ja yritä uudelleen"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Puhdista anturi ja yritä uudelleen"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Paina anturia voimakkaasti"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Liikutit sormea liian hitaasti. Yritä uudelleen."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Kokeile toista sormenjälkeä"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liian kirkas"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Virtapainikkeen painaminen havaittu"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Kokeile muuttaa asentoa"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Liikuta sormeasi hieman joka kerralla"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Kasvot tunnistettu, valitse Vahvista"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Sormenjälkilaitteisto ei ole käytettävissä."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Sormenjälkeä ei voi ottaa käyttöön"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Sormenjälkitunnistimen toiminta aikakatkaistiin. Yritä uudelleen."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Sormenjäljen käyttöönotto aikakatkaistu. Yritä uudelleen."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Sormenjälkitoiminto peruutettiin."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Käyttäjä peruutti sormenjälkitoiminnon."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Liian monta yritystä. Yritä myöhemmin uudelleen."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Liian monta yritystä. Käytä näytön lukituksen avaustapaa."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Liian monta yritystä. Käytä näytön lukituksen avaustapaa."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Yritä uudelleen."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Sormenjälkeä ei voida käsitellä. Yritä uudelleen."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Sormenjälkiä ei ole otettu käyttöön."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Ota yhteys korjauspalveluun."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Kasvomallia ei voi luoda. Yritä uudelleen."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Liian kirkasta. Kokeile pehmeämpää valaistusta."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Ei tarpeeksi valoa"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Vie puhelin kauemmas"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Tuo puhelin lähemmäs"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Siirrä puhelinta ylemmäs"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Käynnistetään sovelluksia."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Viimeistellään päivitystä."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Painoit virtapainiketta, mikä yleensä sammuttaa näytön.\n\nKosketa painiketta kevyesti tallentaessasi sormenjälkeä."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Sammuta näyttö napauttamalla"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Sammuta näyttö"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Lopeta käyttöönotto sammuttamalla näyttö"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Laita pois päältä"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Jatketaanko sormenjäljen vahvistamista?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Painoit virtapainiketta, mikä yleensä sammuttaa näytön.\n\nVahvista sormenjälki koskettamalla painiketta kevyesti."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Sammuta näyttö"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Puhelin"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Telineen kaiuttimet"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Ulkoinen laite"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Kuulokkeet"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Järjestelmä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 87861ae..75ec39a 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser le verrouillage de l\'écran"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Entrez votre verrouillage d\'écran pour continuer"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Appuyez fermement sur le capteur"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Empreinte digitale non reconnue. Réessayez."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nettoyez le capteur d\'empreintes digitales et réessayez"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nettoyez le capteur et réessayez"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Appuyez fermement sur le capteur"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte digitale"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop lumineux"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Forte pression détectée"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Essayez de l\'ajuster"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Modifiez légèrement la position de votre doigt chaque fois"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Visage authentifié, veuillez appuyer sur le bouton Confirmer"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Lecteur d\'empreintes digitales indisponible."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Impossible de configurer l\'empreinte digitale"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Le temps attribué pour lire l\'empreinte digitale est écoulé. Veuillez réessayer."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Délai dépassé pour configurer l\'empreinte digitale. Réessayez."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Opération d\'empreinte digitale numérique annulée."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"L\'opération d\'empreinte digitale a été annulée par l\'utilisateur."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Trop de tentatives. Veuillez réessayer plus tard."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Trop de tentatives. Utilisez plutôt le verrouillage de l\'écran."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Trop de tentatives. Utilisez plutôt le verrouillage de l\'écran."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Réessayer."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Empreinte digitale non traitable. Réessayez."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Le capteur a été désactivé temporairement."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Consultez un fournisseur de services de réparation."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Impossible de créer votre modèle facial. Réessayez."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Trop lumineux. Essayez un éclairage plus faible."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Éclairage insuffisant"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Éloignez le téléphone"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Rapprochez le téléphone"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Tenez le téléphone plus haut"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applications…"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalisation de la mise à jour."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Vous avez appuyé sur le l\'interrupteur – cette action éteint habituellement l\'écran.\n\nEssayez de toucher légèrement pendant la configuration de votre empreinte digitale."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Toucher pour éteindre l\'écran"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Éteindre l\'écran"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Pour terminer, éteignez l\'écran"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Désactiver"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Poursuivre vérifica. empreinte digitale?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Vous avez appuyé sur le l\'interrupteur – cette action éteint habituellement l\'écran.\n\nEssayez de toucher légèrement pour vérifier votre empreinte digitale."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Éteindre l\'écran"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Télévision"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Téléphone"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Haut-parleurs de la station d\'accueil"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Appareil externe"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Oreillettes"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Système"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a9dccbc..427ae2d 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser verrouillage écran"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Utilisez le verrouillage de l\'écran pour continuer"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Appuyez bien sur le lecteur"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Impossible de reconnaître l\'empreinte digitale. Réessayez."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nettoyez le lecteur d\'empreinte digitale et réessayez"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nettoyez le lecteur et réessayez"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Appuyez bien sur le lecteur"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop de lumière"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Utilisation du bouton Marche/Arrêt détectée"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Essayez de repositionner le doigt"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Changez légèrement de position à chaque fois"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Visage authentifié, veuillez appuyer sur \"Confirmer\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Matériel d\'empreinte digitale indisponible."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Impossible de configurer l\'empreinte"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Délai de détection de l\'empreinte digitale expiré. Veuillez réessayer."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Délai de configuration de l\'empreinte dépassé. Réessayez."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Opération d\'empreinte digitale annulée."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Opération d\'authentification par empreinte digitale annulée par l\'utilisateur."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Trop de tentatives. Veuillez réessayer plus tard."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Trop de tentatives. Utilisez plutôt le verrouillage de l\'écran."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Trop de tentatives. Utilisez plutôt le verrouillage de l\'écran."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Veuillez réessayer."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Impossible de reconnaître l\'empreinte digitale. Réessayez."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Contactez un réparateur."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Impossible de créer l\'empreinte faciale. Réessayez."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Trop lumineux. Essayez de baisser la lumière."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Lumière insuffisante"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Éloignez le téléphone."</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Rapprochez le téléphone"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Déplacez le téléphone vers le haut"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applications…"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalisation de la mise à jour."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Vous avez appuyé sur le bouton Marche/Arrêt, ce qui éteint généralement l\'écran.\n\nEssayez d\'appuyer doucement pendant la configuration de votre empreinte digitale."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Appuyer pour éteindre l\'écran"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Éteindre l\'écran"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Éteindre l\'écran pour achever la config."</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Éteindre"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continuer de valider votre empreinte ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Vous avez appuyé sur le bouton Marche/Arrêt, ce qui éteint généralement l\'écran.\n\nPour valider votre empreinte digitale, appuyez plus doucement."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Éteindre l\'écran"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Téléviseur"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Téléphone"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Haut-parleurs de la station d\'accueil"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Appareil externe"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Écouteurs"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Système"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index ae29e50..f99b755b 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar credencial do dispositivo"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Desbloquea a pantalla para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Preme o sensor con firmeza"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Non se puido procesar a impresión dixital. Téntao de novo."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Non se puido recoñecer a impresión dixital. Téntao de novo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpa o sensor de impresión dixital e téntao de novo"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpa o sensor e téntao de novo"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Preme o sensor con firmeza"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"O dedo moveuse demasiado lento. Téntao de novo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proba con outra impresión dixital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Hai demasiada luz"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Premeuse o botón de acendido"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Proba a axustar a impresión dixital"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia lixeiramente a posición do dedo en cada intento"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autenticouse a cara, preme Confirmar"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impresión dixital non dispoñible."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Non se puido configurar a impresión dixital"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Esgotouse o tempo de espera da impresión dixital. Téntao de novo."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Esgotouse o tempo para configurar a impresión dixital Téntao de novo."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Cancelouse a operación da impresión dixital."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"O usuario cancelou a operación da impresión dixital."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Demasiados intentos. Téntao de novo máis tarde."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Houbo demasiados intentos. Mellor usa o bloqueo de pantalla."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Demasiados intentos. Mellor usa o bloqueo de pantalla."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Téntao de novo."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Non se pode procesar a impresión dixital Téntao de novo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Non se rexistraron impresións dixitais."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visita un provedor de reparacións."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Non se puido crear o modelo facial. Téntao de novo."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Hai demasiada iluminación. Proba cunha máis suave."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Non hai luz suficiente"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Afasta o teléfono"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Achega o teléfono"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Sube o teléfono"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicacións."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Está finalizando o arranque"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Premiches o botón de acendido, o que adoita facer que se apague a pantalla.\n\nProba a dar un toque suave namentres configuras a impresión dixital."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Toca para desactivar a pantalla"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Desactivar pantalla"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Apaga a pantalla e acaba a configuración"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Desactivar"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Queres seguir verificando a impresión?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Premiches o botón de acendido, o que adoita facer que se apague a pantalla.\n\nProba a dar un toque suave para verificar a impresión dixital."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Desactivar pantalla"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Televisión"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Teléfono"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Conectar altofalantes á base"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispositivo externo"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Auriculares"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 36812e8..96b9e0f 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"આગળ વધવા માટે તમારું સ્ક્રીન લૉક દાખલ કરો"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"સેન્સર પર જોરથી દબાવો"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ફિંગરપ્રિન્ટ પ્રક્રિયા કરી શકાઈ નથી. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ફિંગરપ્રિન્ટ ઓળખી શકતા નથી. ફરી પ્રયાસ કરો."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ફિંગરપ્રિન્ટ સેન્સર સાફ કરો અને ફરી પ્રયાસ કરો"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"સેન્સર સાફ કરો અને ફરી પ્રયાસ કરો"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"સેન્સર પર જોરથી દબાવો"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"આંગળી બહુ જ ધીમેથી ખસેડી. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"અન્ય ફિંગરપ્રિન્ટ અજમાવી જુઓ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"અતિશય પ્રકાશિત"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"પાવર બટન દબાવ્યું હોવાની જાણ થઈ છે"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ગોઠવણી કરી જુઓ"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"દરેક વખતે સ્કૅનર પર તમારી આંગળીની સ્થિતિ સહેજ બદલતા રહો"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ચહેરા પ્રમાણિત, કૃપા કરીને કન્ફર્મ કરો"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ફિંગરપ્રિન્ટ હાર્ડવેર ઉપલબ્ધ નથી."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ફિંગરપ્રિન્ટનું સેટઅપ કરી શકતા નથી"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ફિંગરપ્રિન્ટનો સમય બાહ્ય થયો. ફરી પ્રયાસ કરો."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ફિંગરપ્રિન્ટનું સેટઅપ કરવાનો સમય સમાપ્ત થઈ ગયો. ફરી પ્રયાસ કરો."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ફિંગરપ્રિન્ટ ઓપરેશન રદ કર્યું."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ફિંગરપ્રિન્ટ ચકાસવાની પ્રક્રિયા વપરાશકર્તાએ રદ કરી."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ઘણા બધા પ્રયત્નો. પછીથી ફરી પ્રયાસ કરો."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ઘણા બધા પ્રયાસો. તેને બદલે સ્ક્રીન લૉકનો ઉપયોગ કરો."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ઘણા બધા પ્રયાસો. વિકલ્પ તરીકે સ્ક્રીન લૉકનો ઉપયોગ કરો."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ફરી પ્રયાસ કરો."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ફિંગરપ્રિન્ટની પ્રક્રિયા કરી શકતા નથી. ફરી પ્રયાસ કરો."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"કોઈ ફિંગરપ્રિન્ટની નોંધણી કરવામાં આવી નથી."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"રિપેર કરવાની સેવા આપતા પ્રદાતાની મુલાકાત લો."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"તમારા ચહેરાનું મૉડલ ન બનાવી શકાય. ફરી પ્રયાસ કરો."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"અતિશય પ્રકાશિત. થોડો હળવો પ્રકાશ અજમાવી જુઓ."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"પૂરતો પ્રકાશ નથી"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ફોનને વધુ દૂર લઈ જાઓ"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ફોનને વધુ નજીક લાવો"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ફોનને વધુ ઊંચે લઈ જાઓ"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ઍપ્લિકેશનો શરૂ કરી રહ્યાં છે."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"બૂટ સમાપ્ત કરી રહ્યાં છે."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"તમે પાવર બટન દબાવ્યું છે — જેનાથી સામાન્ય રીતે સ્ક્રીન બંધ થઈ જાય છે.\n\nતમારી ફિંગરપ્રિન્ટનું સેટઅપ કરતી વખતે હળવેથી ટૅપ કરવાનો પ્રયાસ કરો."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"સ્ક્રીન બંધ કરવા માટે ટૅપ કરો"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"સ્ક્રીન બંધ કરો"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"સેટઅપ સમાપ્ત કરવા માટે, સ્ક્રીન બંધ કરો"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"બંધ કરો"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"શું તમારી ફિંગરપ્રિન્ટની ચકાસણી કરીએ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"તમે પાવર બટન દબાવ્યું છે — જેનાથી સામાન્ય રીતે સ્ક્રીન બંધ થઈ જાય છે.\n\nતમારી ફિંગરપ્રિન્ટની ચકાસણી કરવા માટે, તેને હળવેથી ટૅપ કરવાનો પ્રયાસ કરો."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"સ્ક્રીન બંધ કરો"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ફોન"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"સ્પીકર્સ ડૉક કરો"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"બહારનું ડિવાઇસ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"હેડફોન"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"સિસ્ટમ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2a9a44a..4e05cd4 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"जारी रखने के लिए, अपने स्क्रीन लॉक की पुष्टि करें"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"सेंसर को उंगली से ज़ोर से दबाएं"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फ़िंगरप्रिंट प्रोसेस नहीं हो सका. कृपया दोबारा कोशिश करें."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"फ़िंगरप्रिंट की पहचान नहीं की जा सकी. फिर से कोशिश करें."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"फ़िंगरप्रिंट सेंसर को साफ़ करके फिर से कोशिश करें"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"फ़िंगरप्रिंट सेंसर को साफ़ करके फिर से कोशिश करें"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"सेंसर को उंगली से ज़ोर से दबाएं"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"उंगली बहुत धीरे चलाई गई. कृपया फिर से कोशिश करें."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"किसी दूसरे फ़िंगरप्रिंट से कोशिश करें"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"बहुत रोशनी है"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"पावर बटन दबाया गया"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"सेंसर पर सही तरीके से उंगली लगाने की कोशिश करें"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"फ़िंगरप्रिंट सेट अप करते समय, अपनी उंगली को हर बार थोड़ी अलग स्थिति में रखें"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"चेहरे की पहचान की गई, कृपया पुष्टि बटन दबाएं"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"फ़िंगरप्रिंट हार्डवेयर उपलब्ध नहीं है."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"फ़िंगरप्रिंट सेट अप नहीं किया जा सका"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"फ़िंगरप्रिंट का समय खत्म हो गया. फिर से कोशिश करें."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"फ़िंगरप्रिंट सेटअप करने का समय खत्म हो गया. फिर से कोशिश करें."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"फ़िंगरप्रिंट ऑपरेशन रोक दिया गया."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"उपयोगकर्ता ने फिंगरप्रिंट की पुष्टि की कार्रवाई रद्द कर दी है."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"बहुत ज़्यादा प्रयास कर लिए गए हैं. बाद में फिर से प्रयास करें."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"कई बार कोशिश की जा चुकी है. इसके बजाय, स्क्रीन लॉक का इस्तेमाल करें."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"इससे ज़्यादा बार कोशिश नहीं की जा सकती. इसके बजाय, स्क्रीन लॉक का इस्तेमाल करें."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"फिर से कोशिश करें."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"फ़िंगरप्रिंट की पहचान नहीं की जा सकी. फिर से कोशिश करें."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोई फ़िंगरप्रिंट रजिस्टर नहीं किया गया है."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"फ़िंगरप्रिंट सेंसर को रिपेयर करने की सेवा देने वाली कंपनी से संपर्क करें."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"चेहरे का माॅडल नहीं बन सका. फिर से कोशिश करें."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"बहुत रोशनी है. हल्की रोशनी आज़माएं."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"ज़रूरत के मुताबिक रोशनी नहीं है"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"फ़ोन को दूर ले जाएं"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"फ़ोन को नज़दीक लाएं"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"फ़ोन को थोड़ा और ऊपर ले जाएं"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ऐप्स  प्रारंभ होने वाले हैं"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"बूट खत्म हो रहा है."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"आपने पावर बटन दबाया - आम तौर पर, इससे स्क्रीन बंद हो जाती है.\n\nअपना फ़िंगरप्रिंट सेट अप करते समय, बटन को हल्के से टैप करके देखें."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"स्क्रीन बंद करने के लिए टैप करें"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"स्क्रीन बंद करें"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"सेटअप पूरा होने पर, स्क्रीन बंद करें"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"बंद करें"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"फ़िंगरप्रिंट की पुष्टि करना जारी रखना है?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"आपने पावर बटन दबाया - आम तौर पर, इससे स्क्रीन बंद हो जाती है.\n\nअपने फ़िंगरप्रिंट की पुष्टि करने के लिए, बटन पर हल्के से टैप करके देखें."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"स्क्रीन बंद करें"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"टीवी"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"फ़ोन"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"डॉक स्‍पीकर"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"बाहरी डिवाइस"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"हेडफ़ोन"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"यूएसबी"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"सिस्‍टम"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0a2702a..0a557d6 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Upotreba zaključavanja zaslona"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrijebite zaključavanje zaslona da biste nastavili"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Čvrsto pritisnite senzor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Prepoznavanje otiska prsta nije uspjelo. Pokušajte ponovo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Očistite senzor otiska prsta i pokušajte ponovno"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Očistite senzor i pokušajte ponovno"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Čvrsto pritisnite senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Presporo pomicanje prsta. Pokušajte ponovo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Isprobajte drugi otisak prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvijetlo"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Detektiran je pritisak na tipku za uključivanje"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pokušajte ga prilagoditi"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promijenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je autentificirano, pritisnite Potvrdi"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardver za otisak prsta nije dostupan."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Postavljanje otiska prsta nije uspjelo"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Isteklo je vrijeme čekanja za otisak prsta. Pokušajte ponovo."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vrijeme za postavljanje otiska prsta je isteklo. Pokušajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Radnja otiska prsta otkazana je."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Radnju s otiskom prsta otkazao je korisnik."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Umjesto toga upotrijebite zaključavanje zaslona."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Umjesto toga upotrijebite zaključavanje zaslona."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Pokušajte ponovo."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registriran nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Posjetite davatelja usluga popravaka."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Izrada modela lica nije uspjela. Pokušajte ponovo."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Presvijetlo je. Pokušajte sa slabijim svjetlom."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nema dovoljno svjetla"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Udaljite telefon"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Približite telefon"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Pomaknite telefon prema gore"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Završetak inicijalizacije."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Pritisnuli ste tipku za uključivanje/isključivanje, čime se obično isključuje zaslon.\n\nPokušajte lagano dodirnuti dok postavljate svoj otisak prsta."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Dodirnite da biste isključili zaslon"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Isključi zaslon"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Za prekid postavljanja isključite zaslon"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Isključi"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Nastaviti s potvrđivanjem otiska prsta?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Pritisnuli ste tipku za uključivanje/isključivanje, čime se obično isključuje zaslon.\n\nPokušajte lagano dodirnuti da biste potvrdili svoj otisak prsta."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Isključi zaslon"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Televizor"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Zvučnici postolja"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Vanjski uređaj"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Slušalice"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sustav"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 01b6f90..f1388f6 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Képernyőzár használata"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"A folytatáshoz adja meg a képernyőzár hitelesítési adatait"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Nyomja meg határozottan az érzékelőt"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nem sikerült feldolgozni az ujjlenyomatot. Próbálkozzon újra."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Az ujjlenyomat nem ismerhető fel. Próbálkozzon újra."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Tisztítsa meg az ujjlenyomat-érzékelőt, majd próbálja újra"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Tisztítsa meg az érzékelőt, majd próbálja újra"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Nyomja meg határozottan az érzékelőt"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Túl lassan húzta az ujját. Próbálkozzon újra."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Próbálkozzon másik ujjlenyomattal"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Túl világos"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Bekapcsológomb lenyomása észlelve"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Próbálja beállítani"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Módosítsa minden alkalommal kis mértékben ujja helyzetét."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Arc hitelesítve; nyomja meg a Megerősítés lehetőséget"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Az ujjlenyomathoz szükséges hardver nem érhető el."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nem sikerült beállítani az ujjlenyomatot"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Az ujjlenyomat-beolvasási műveletkor időtúllépés történt. Próbálkozzon újra."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Lejárt az ujjlenyomat-beállítás időkorlátja. Próbálkozzon újra."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Ujjlenyomattal kapcsolatos művelet megszakítva"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Az ujjlenyomattal kapcsolatos műveletet a felhasználó megszakította."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Túl sok próbálkozás. Próbálja újra később."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Túl sokszor próbálkozott. Használja inkább a képernyőzárat."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Túl sok próbálkozás. Használja inkább a képernyőzárat."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Próbálkozzon újra."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nem sikerült feldolgozni az ujjlenyomatot. Próbálkozzon újra."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nincsenek regisztrált ujjlenyomatok."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Keresse fel a szervizt."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Nem lehet létrehozni az arcmodellt. Próbálja újra."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Túl világos. Próbálja kevésbé erős világítással."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nincs elég fény"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Tartsa távolabb a telefont"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Tartsa közelebb a telefont"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Emelje magasabbra a telefont"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Kezdő alkalmazások."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Rendszerindítás befejezése."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Megnyomta a bekapcsológombot — ezzel általában kikapcsol a képernyő.\n\nPróbáljon finoman rákoppintani az ujjlenyomat beállítása közben."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Koppintson a képernyő kikapcsolásához"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Képernyő kikapcsolása"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"A képernyő kikapcsolása befejezi a beállítást"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Kikapcsolás"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Folytatja az ujjlenyomat ellenőrzését?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Megnyomta a bekapcsológombot — ezzel általában kikapcsol a képernyő.\n\nPróbáljon finoman rákoppintani az ujjlenyomat ellenőrzéséhez."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Kikapcsolom"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dokkolóegység hangszórója"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Külső eszköz"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Fejhallgató"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Rendszer"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 86560be..14fb55c 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Էկրանի կողպում"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Շարունակելու համար ապակողպեք էկրանը"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Մատը ուժեղ սեղմեք սկաների վրա"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Չհաջողվեց մշակել մատնահետքը: Նորից փորձեք:"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Մատնահետքը չի հաջողվում ճանաչել։ Նորից փորձեք։"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Մաքրեք մատնահետքերի սկաները և նորից փորձեք"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Մաքրեք սկաները և նորից փորձեք"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Մատը ուժեղ սեղմեք սկաների վրա"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Շատ դանդաղ անցկացրիք մատը: Փորձեք նորից:"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Փորձեք մեկ այլ մատնահետք"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Շատ լուսավոր է"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Հայտնաբերվել է սնուցման կոճակի սեղմում"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Փորձեք փոխել մատի դիրքը"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ամեն անգամ թեթևակի փոխեք մատի դիրքը"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Դեմքը ճանաչվեց: Սեղմեք «Հաստատել»:"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Մատնահետքի սարքն անհասանելի է:"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Հնարավոր չէ կարգավորել մատնահետքը"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Մատնահետքի գրանցման ժամանակը սպառվել է: Փորձեք նորից:"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Մատնահետքի կարգավորման ժամանակը սպառվել է։ Նորից փորձեք։"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Իսկորոշումը մատնահետքի միջոցով չեղարկվեց:"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Մատնահետքով նույնականացման գործողությունը չեղարկվել է օգտատիրոջ կողմից:"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Չափից շատ փորձ եք կատարել: Փորձեք նորից քիչ հետո:"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Չափազանց շատ փորձեր են արվել։ Օգտագործեք էկրանի կողպումը։"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Չափազանց շատ փորձեր են արվել։ Օգտագործեք էկրանի կողպումը։"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Փորձեք նորից:"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Չի հաջողվում մշակել մատնահետքը։ Նորից փորձեք։"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Գրանցված մատնահետք չկա:"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Այցելեք սպասարկման կենտրոն։"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Չհաջողվեց ստեղծել ձեր դեմքի մոդելը։ Նորից փորձեք։"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Շատ լուսավոր է։ Փորձեք ավելի թեթև լուսավորություն։"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Թույլ լուսավորություն"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Փոքր-ինչ հեռու պահեք հեռախոսը"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Մոտեցրեք հեռախոսը"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Բարձրացրեք հեռախոսը"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Հավելվածները մեկնարկում են:"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Բեռնումն ավարտվում է:"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Դուք սեղմել եք սնուցման կոճակը։ Սովորաբար դրա արդյունքում էկրանն անջատվում է։\n\nՄատնահետքը ավելացնելու համար թեթևակի հպեք կոճակին։"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Հպեք՝ էկրանն անջատելու համար"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Անջատել էկրանը"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Ավարտեք կարգավորումը՝ անջատելով էկրանը"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Անջատել"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Շարունակե՞լ մատնահետքի սկանավորումը"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Դուք սեղմել եք սնուցման կոճակը։ Սովորաբար դրա արդյունքում էկրանն անջատվում է։\n\nՄատնահետքը սկանավորելու համար թեթևակի հպեք կոճակին։"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Անջատել էկրանը"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Հեռուստացույց"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Հեռախոս"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Դոկ-կայանի բարձրախոսներ"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Արտաքին սարք"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Ականջակալներ"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Համակարգ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index b145e20..58d91c8 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci layar"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Masukkan kunci layar untuk melanjutkan"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tekan sensor dengan kuat"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses sidik jari. Coba lagi."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Tidak dapat mengenali sidik jari. Coba lagi."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Bersihkan sensor sidik jari lalu coba lagi"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Bersihkan sensor lalu coba lagi"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tekan sensor dengan kuat"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Jari digerakkan terlalu lambat. Coba lagi."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Coba sidik jari lain"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Penekanan tombol daya terdeteksi"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Coba sesuaikan"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ubah sedikit posisi jari di setiap percobaan"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Wajah diautentikasi, silakan tekan konfirmasi"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware sidik jari tidak tersedia."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Tidak dapat menyiapkan sidik jari"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Waktu sidik jari habis. Coba lagi."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Waktu penyiapan sidik jari habis. Coba lagi."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operasi sidik jari dibatalkan."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operasi sidik jari dibatalkan oleh pengguna."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Terlalu banyak upaya. Coba lagi nanti."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Terlalu banyak upaya gagal. Gunakan kunci layar."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Terlalu banyak upaya gagal. Gunakan kunci layar."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Coba lagi."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Tidak dapat memproses sidik jari. Coba lagi."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tidak ada sidik jari yang terdaftar."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Kunjungi penyedia reparasi."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Tidak dapat membuat model wajah Anda. Coba lagi."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Terlalu terang. Coba cahaya yang lebih lembut."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Cahaya tidak cukup"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Jauhkan ponsel"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Dekatkan ponsel"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Gerakkan ponsel ke atas"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Memulai aplikasi."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Menyelesaikan boot."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Anda menekan tombol daya; tindakan ini biasanya akan menonaktifkan layar.\n\nCoba ketuk lembut saat menyiapkan sidik jari Anda."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Ketuk untuk menonaktifkan layar"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Nonaktifkan layar"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Untuk mengakhiri penyiapan, nonaktifkan layar"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Nonaktifkan"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Lanjutkan verifikasi sidik jari?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Anda menekan tombol daya; tindakan ini biasanya akan menonaktifkan layar.\n\nCoba ketuk lembut untuk memverifikasi sidik jari Anda."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Nonaktifkan layar"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Ponsel"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Pengeras suara dok"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Perangkat Eksternal"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Headphone"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 6f48de2..7466295 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Nota skjálás"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Sláðu inn skjálásinn þinn til að halda áfram"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Ýttu ákveðið á lesarann"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ekki var hægt að vinna úr fingrafarinu. Reyndu aftur."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Fingrafar þekkist ekki. Reyndu aftur."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hreinsaðu fingrafaralesarann og reyndu aftur"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Hreinsaðu lesarann og reyndu aftur"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Ýttu ákveðið á lesarann"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Fingurinn hreyfðist of hægt. Reyndu aftur."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prófaðu annað fingrafar"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Of bjart"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Þrýstingur á aflrofa greindist"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prófaðu að breyta stöðu fingursins"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Breyttu stöðu fingursins örlítið í hvert skipti"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Andlit staðfest, ýttu til að staðfesta"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Fingrafarsvélbúnaður ekki til staðar."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Ekki er hægt að setja upp fingrafar"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Tímamörk runnu út fyrir fingrafar. Reyndu aftur."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingrafarsuppsetning rann út á tíma. Reyndu aftur."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Hætt við fingrafarsaðgerð."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Notandi hætti við að nota fingrafar."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Of margar tilraunir. Reyndu aftur síðar."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Of margar tilraunir. Notaðu skjálás í staðinn."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Of margar tilraunir. Notaðu skjálás í staðinn."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Reyndu aftur."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Ekki tekst að vinna úr fingrafari. Reyndu aftur."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Engin fingraför hafa verið skráð."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Þú verður að fara á verkstæði."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Ekki tekst að búa til andlitslíkan. Reyndu aftur."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Of bjart. Prófaðu mýkri lýsingu."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Of lítið ljós"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Færðu símann lengra frá"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Færðu símann nær"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Færðu símann hærra"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Ræsir forrit."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Lýkur ræsingu."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Þú ýttir á aflrofann. Yfirleitt slekkur það á skjánum.\n\nPrófaðu að ýta laust þegar þú setur upp fingrafarið."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Ýttu til að slökkva á skjá"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Slökkva á skjá"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Slökktu á skjá til að ljúka uppsetningu"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Slökkva"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Halda áfram að staðfesta fingrafarið?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Þú ýttir á aflrofann. Yfirleitt slekkur það á skjánum.\n\nPrófaðu að ýta laust til að staðfesta fingrafarið þitt."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Slökkva á skjá"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Sjónvarp"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Sími"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dokkuhátalarar"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Ytra tæki"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Heyrnartól"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Kerfi"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index fb7763a..3484165 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usa il blocco schermo"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Inserisci il blocco schermo per continuare"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Premi con decisione sul sensore"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossibile elaborare l\'impronta. Riprova."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Impossibile riconoscere l\'impronta. Riprova."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Pulisci il sensore di impronte digitali e riprova"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Pulisci il sensore e riprova"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Premi con decisione sul sensore"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Movimento del dito troppo lento. Riprova."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prova con un\'altra impronta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Troppa luce"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Rilevata pressione tasto di accensione"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prova a regolare"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia leggermente la posizione del dito ogni volta"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Volto autenticato, premi Conferma"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware per l\'impronta non disponibile."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Impossibile configurare l\'impronta"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Timeout impronta. Riprova."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Timeout configurazione impronta. Riprova."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operazione associata all\'impronta annullata."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operazione di autenticazione dell\'impronta annullata dall\'utente."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Troppi tentativi. Riprova più tardi."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Troppi tentativi. Usa il blocco schermo."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Troppi tentativi. Usa il blocco schermo."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Riprova."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Impossibile elaborare l\'impronta. Riprova."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nessuna impronta digitale registrata."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Contatta un fornitore di servizi di riparazione."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Impossibile creare il modello del volto. Riprova."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Troppa luce. Prova con una luce più soft."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Luce insufficiente"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Allontana il telefono"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Avvicina il telefono"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Sposta il telefono più in alto"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Avvio app."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Conclusione dell\'avvio."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Hai premuto il tasto di accensione; in genere questa azione disattiva lo schermo.\n\nProva a toccare leggermente il tasto di accensione durante la configurazione della tua impronta."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tocca per disattivare lo schermo"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Disattiva lo schermo"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Per terminare, disattiva lo schermo"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Disattiva"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Vuoi continuare a verificare l\'impronta?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Hai premuto il tasto di accensione; in genere questa azione disattiva lo schermo.\n\nProva a toccare leggermente il tasto di accensione per verificare la tua impronta."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Disattiva lo schermo"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefono"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Altoparlanti dock"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispositivo esterno"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Cuffie audio"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 7a460a3..0c62ea2 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"שימוש בנעילת מסך"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"יש לבטל את נעילת המסך כדי להמשיך"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"לוחצים לחיצה חזקה על החיישן"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"לא ניתן היה לעבד את טביעת האצבע. אפשר לנסות שוב."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"לא ניתן לזהות את טביעת האצבע. יש לנסות שוב."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"עליך לנקות את חיישן טביעות האצבע ולנסות שוב"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"עליך לנקות את החיישן ולנסות שוב"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"לוחצים לחיצה חזקה על החיישן"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"הזזת את האצבע לאט מדי. יש לנסות שוב."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"יש להשתמש בטביעת אצבע אחרת"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"בהיר מדי"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"זוהתה לחיצה על לחצן ההפעלה"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"יש לנסות ולשנות את תנוחת האצבע"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"צריך לשנות מעט את תנוחת האצבע בכל פעם"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"זיהוי הפנים בוצע. יש ללחוץ על אישור"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"החומרה לזיהוי טביעות אצבעות אינה זמינה."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"לא ניתן להגדיר טביעת אצבע"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"נגמר הזמן הקצוב לטביעת אצבע. אפשר לנסות שוב."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"הזמן שהוקצב להגדרה של טביעת האצבע פג. יש לנסות שוב."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"פעולת טביעת האצבע בוטלה."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"פעולת טביעת האצבע בוטלה על ידי המשתמש."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"יותר מדי ניסיונות. יש לנסות שוב מאוחר יותר."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"בוצעו יותר מדי ניסיונות. יש להשתמש בנעילת המסך במקום זאת."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"בוצעו יותר מדי ניסיונות. יש להשתמש בנעילת המסך במקום זאת."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"כדאי לנסות שוב."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"לא ניתן לעבד את טביעת האצבע. יש לנסות שוב."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נסרקו טביעות אצבע."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"צריך ליצור קשר עם ספק תיקונים."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"לא ניתן ליצור את התבנית לזיהוי הפנים. יש לנסות שוב."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"בהירה מדי. צריך תאורה עדינה יותר."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"אין מספיק אור"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"צריך להרחיק את הטלפון"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"צריך לקרב את הטלפון"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"צריך להגביה את הטלפון"</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"מתבצעת הפעלה של אפליקציות."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"תהליך האתחול בשלבי סיום."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"לחצת על לחצן ההפעלה – בדרך כלל הפעולה הזו מכבה את המסך.\n\nעליך לנסות להקיש בעדינות במהלך ההגדרה של טביעת האצבע שלך."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"יש להקיש כדי לכבות את המסך"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"כיבוי המסך"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"כדי לסיים את ההגדרה צריך לכבות את המסך"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"השבתה"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"להמשיך לאמת את טביעת האצבע שלך?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"לחצת על לחצן ההפעלה – בדרך כלל הפעולה הזו מכבה את המסך.\n\nעליך לנסות להקיש בעדינות כדי לאמת את טביעת האצבע שלך."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"כיבוי המסך"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"טלוויזיה"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"טלפון"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"רמקולים של מעגן"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"מכשיר חיצוני"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"אוזניות"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"מערכת"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index cf8521f..94c6bb0 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"画面ロックの使用"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"続行するには画面ロックを入力してください"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"センサーにしっかりと押し当ててください"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"指紋を処理できませんでした。もう一度お試しください。"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"指紋を認識できません。もう一度お試しください。"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"指紋認証センサーの汚れを取り除いて、もう一度お試しください"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"センサーの汚れを取り除いて、もう一度お試しください"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"センサーにしっかりと押し当ててください"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"指の動きが遅すぎました。もう一度お試しください。"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"別の指紋をお試しください"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"明るすぎます"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"電源ボタンが押されました"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"調整してみてください"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"毎回、指を置く位置を少し変えてください"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"顔を認証しました。[確認] を押してください"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指紋認証ハードウェアは使用できません。"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"指紋を設定できません"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"指紋の読み取りがタイムアウトになりました。もう一度お試しください。"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指紋の設定がタイムアウトしました。もう一度お試しください。"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋の操作をキャンセルしました。"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"指紋の操作がユーザーによりキャンセルされました。"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"所定の回数以上間違えました。しばらくしてからもう一度お試しください。"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"試行回数が上限を超えました。代わりに画面ロックを使用してください。"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"試行回数が上限を超えました。代わりに画面ロックを使用してください。"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"もう一度お試しください。"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"指紋を処理できません。もう一度お試しください。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"指紋が登録されていません。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string>
@@ -1248,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"アプリを起動しています。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ブートを終了しています。"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"電源ボタンを押しました。通常、この操作で画面が OFF になります。\n\n指紋を設定する場合は電源ボタンに軽く触れてみましょう。"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"タップして画面を OFF にする"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"画面を OFF にする"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"設定を終了するには画面を OFF にします"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"OFF にする"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"指紋の確認を続行しますか?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"電源ボタンを押しました。通常、この操作で画面が OFF になります。\n\n指紋を確認するには、電源ボタンに軽く触れてみましょう。"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"画面を OFF にする"</string>
@@ -1610,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"テレビ"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"モバイル デバイス"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ホルダーのスピーカー"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"外部デバイス"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ヘッドホン"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"システム"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index ae14cc9..576c61e 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"გამოიყენეთ ეკრანის დაბლოკვა"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"გასაგრძელებლად შედით ეკრანის დაბლოკვაში"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"მაგრად დააჭირეთ სენსორს"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"თითის ანაბეჭდის დამუშავება ვერ მოხერხდა. გთხოვთ, ცადოთ ხელახლა."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"თითის ანაბეჭდის ამოცნობა ვერ ხერხდება. ცადეთ ხელახლა."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"გაწმინდეთ თითის ანაბეჭდის სენსორი და ხელახლა ცადეთ"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"გაწმინდეთ სენსორი და ხელახლა ცადეთ"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"მაგრად დააჭირეთ სენსორს"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"თითის აღება მეტისმეტად ნელა მოხდა. გთხოვთ, სცადოთ ხელახლა."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ცადეთ სხვა თითის ანაბეჭდი"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ზედმეტად ნათელია"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"აღმოჩენილია Ძლიერი დაჭერა"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ცადეთ დარეგულირება"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ოდნავ შეცვალეთ თითის დაჭერის ადგილი ყოველ ჯერზე"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"სახე ავტორიზებულია, დააჭირეთ დადასტურებას"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"თითის ანაბეჭდის აპარატურა არ არის ხელმისაწვდომი."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"თითის ანაბეჭდის დაყენება ვერ ხერხდება"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"თითის ანაბეჭდის ლოდინის დრო ამოიწურა. სცადეთ ხელახლა."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"თითის ანაბეჭდის დაყენების დრო ამოიწურა. ცადეთ ხელახლა."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"თითის ანაბეჭდის აღების ოპერაცია გაუქმდა."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"თითის ანაბეჭდის ოპერაცია გააუქმა მომხმარებელმა."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ძალიან ბევრი მცდელობა იყო. სცადეთ მოგვიანებით."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"მეტისმეტად ბევრი მცდელობა იყო. სანაცვლოდ გამოიყენეთ ეკრანის დაბლოკვა."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"მეტისმეტად ბევრი მცდელობა იყო. სანაცვლოდ გამოიყენეთ ეკრანის დაბლოკვა."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ხელახლა სცადეთ"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"თითის ანაბეჭდის დამუშავება შეუძლებელია. ცადეთ ხელახლა."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"თითის ანაბეჭდები რეგისტრირებული არ არის."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ეწვიეთ შეკეთების სერვისის პროვაიდერს."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"თქვენი სახის მოდელი ვერ იქმნება. ცადეთ ხელახლა."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"მეტისმეტად ნათელია. ცადეთ უფრო სუსტი განათება."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"განათება არასაკმარისია"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"გაწიეთ ტელეფონი უფრო შორს"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"მიიტანეთ ტელეფონი უფრო ახლოს"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"აწიეთ ტელეფონი ზემოთ"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"აპების ჩართვა"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ჩატვირთვის დასასრული."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"თქვენ დააჭირეთ ჩართვის ღილაკს — ჩვეულებრივ, ის ეკრანს გამორთავს.\n\nთქვენი თითის ანაბეჭდის დაყენებისას ცადეთ მსუბუქად შეხება."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"შეეხეთ ეკრანის გამოსართავად"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"ეკრანის გამორთვა"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"დაყენების დასასრულებლად გამორთეთ ეკრანი"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"გამორთვა"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"გსურთ ანაბეჭდის დადასტურების გაგრძელება?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"თქვენ დააჭირეთ ჩართვის ღილაკს — ჩვეულებრივ, ის ეკრანს გამორთავს.\n\nთქვენი თითის ანაბეჭდის დასადასტურებლად ცადეთ მსუბუქად შეხება."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"ეკრანის გამორთვა"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ტელევიზია"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ტელეფონი"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"სპიკერების მიმაგრება"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"გარე მოწყობილობა"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ყურსასმენები"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"სისტემა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 54edba3..535996f 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Экран құлпын пайдалану"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Жалғастыру үшін экран құлпын енгізіңіз."</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Сканерді қатты басыңыз."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Саусақ ізін өңдеу мүмкін емес. Әрекетті қайталаңыз."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Саусақ ізін тану мүмкін емес. Қайталап көріңіз."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Саусақ ізін оқу сканерін тазалап, әрекетті қайталаңыз."</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Сканерді тазалап, әрекетті қайталаңыз."</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Сканерді қатты басыңыз."</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Саусағыңызды тым баяу қозғалттыңыз. Әрекетті қайталап көріңіз."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Басқа саусақ ізін байқап көріңіз."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Тым жарық."</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Қуат түймесін басу әрекеті анықталды."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Дұрыстап қойып көріңіз."</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Саусағыңыздың қалпын аздап өзгертіп тұрыңыз."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,13 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Бет танылды, \"Растау\" түймесін басыңыз"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Саусақ ізі жабдығы қолжетімді емес."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Саусақ ізін орнату мүмкін емес."</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Саусақ ізін күту уақыты бітті. Әрекетті қайталаңыз."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Саусақ ізін реттеу уақыты өтіп кетті. Қайталап көріңіз."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Саусақ ізі операциясынан бас тартылған."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Пайдаланушы саусақ ізі операциясынан бас тартты."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Талпыныстар тым көп. Кейінірек қайталап көріңіз."</string>
-    <!-- no translation found for fingerprint_error_lockout_permanent (9060651300306264843) -->
-    <skip />
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Әрекетті қайталаңыз."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Тым көп әрекет жасалды. Орнына экран құлпын пайдаланыңыз."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Тым көп әрекет жасалды. Орнына экран құлпын пайдаланыңыз."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Саусақ ізін өңдеу мүмкін емес. Қайталап көріңіз."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Саусақ іздері тіркелмеген."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
@@ -635,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Жөндеу қызметіне барыңыз."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Бет үлгісі жасалмады. Қайталап көріңіз."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Тым ашық. Күңгірттеу жарық керек."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Жарық жеткіліксіз"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Телефонды алшақ ұстаңыз."</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Телефонды жақынырақ ұстаңыз."</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Телефонды жоғарырақ ұстаңыз."</string>
@@ -1250,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Қолданбалар іске қосылуда."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Қосуды аяқтауда."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Қуат түймесін бастыңыз. Бұл әдетте экранды өшіреді.\n\nСаусақ ізін реттеу үшін, оны жайлап түртіп көріңіз."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Экранды өшіру үшін түртіңіз"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Экранды өшіру"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Реттеуді аяқтау үшін экранды өшіріңіз"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Өшіру"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Саусақ ізін растауды жалғастырасыз ба?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Қуат түймесін бастыңыз. Бұл әдетте экранды өшіреді.\n\nСаусақ ізін растау үшін, оны жайлап түртіп көріңіз."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Экранды өшіру"</string>
@@ -1612,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ТД"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Үндеткіштерді қондыру"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Сыртқы құрылғы"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Құлақаспаптар"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Жүйе"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 0d3d07d..09c4478 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ប្រើ​ការ​ចាក់​សោ​អេក្រង់"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"បញ្ចូលការចាក់សោអេក្រង់របស់អ្នក ដើម្បីបន្ត"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"សង្កត់លើ​ឧបករណ៍​ចាប់សញ្ញា​ឱ្យណែន"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"មិនអាចដំណើរការស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្តងទៀត។"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"មិនអាចសម្គាល់​ស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"សម្អាត​ឧបករណ៍​ចាប់ស្នាមម្រាមដៃ រួចព្យាយាម​ម្ដងទៀត"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"សម្អាត​ឧបករណ៍​ចាប់សញ្ញា រួចព្យាយាម​ម្ដងទៀត"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"សង្កត់លើ​ឧបករណ៍​ចាប់សញ្ញា​ឱ្យណែន"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ចលនាម្រាមដៃយឺតពេកហើយ។ សូមព្យាយាមម្តងទៀត។"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"សាកល្បងប្រើ​ស្នាមម្រាមដៃផ្សេងទៀត"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ភ្លឺពេក"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ចាប់ដឹងថាចុចប៊ូតុងថាមពល"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"សាកល្បង​កែតម្រូវ"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ប្ដូរទីតាំងម្រាមដៃ​របស់អ្នកតិចៗ​គ្រប់ពេល"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"បានផ្ទៀងផ្ទាត់​មុខ សូម​ចុច​បញ្ជាក់"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ផ្នែករឹងស្នាមម្រាមដៃមិនមានទេ។"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"មិនអាចរៀបចំ​ស្នាមម្រាមដៃបានទេ"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ស្នាមម្រាមដៃបានអស់ម៉ោង។ សូមព្យាយាមម្តងទៀត។"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"កា​ររៀបចំ​ស្នាមម្រាមដៃបានអស់ម៉ោង។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"បានបោះបង់ប្រតិបត្តិការស្នាមម្រាមដៃ។"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ប្រតិបត្តិការ​ស្នាម​ម្រាម​ដៃ​ត្រូវ​បាន​បោះ​បង់​ដោយ​អ្នក​ប្រើប្រាស់។"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ព្យាយាមចូលច្រើនពេកហើយ។ សូមព្យាយាមម្តងទៀតពេលក្រោយ។"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ព្យាយាម​ច្រើនដងពេក។ សូមប្រើការចាក់សោ​អេក្រង់ជំនួសវិញ។"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ព្យាយាម​ច្រើនដងពេក។ សូមប្រើការចាក់សោ​អេក្រង់ជំនួសវិញ។"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ព្យាយាមម្ដងទៀត។"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"មិនអាចដំណើរការស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"មិន​មាន​ការ​ចុះឈ្មោះស្នាម​ម្រាមដៃទេ។"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះ​មិនមាន​ឧបករណ៍ចាប់​ស្នាមម្រាមដៃទេ។"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ទាក់ទងក្រុមហ៊ុន​ផ្ដល់ការជួសជុល។"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"មិនអាចបង្កើតគំរូមុខរបស់អ្នកបានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ភ្លឺពេក។ សូមសាកល្បង​ប្រើ​ពន្លឺស្រាលជាងនេះ។"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"មិនមាន​ពន្លឺគ្រប់គ្រាន់"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ដាក់​ទូរសព្ទឱ្យឆ្ងាយ​ជាងមុន"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ដាក់​ទូរសព្ទ​ឱ្យជិត​ជាងមុន"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ដាក់​ទូរសព្ទ​ឱ្យខ្ពស់​ជាងមុន"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ចាប់ផ្ដើម​កម្មវិធី។"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"បញ្ចប់​ការ​ចាប់ផ្ដើម។"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"អ្នកបានចុចប៊ូតុងថាមពល — ជាធម្មតាការធ្វើបែបនេះនឹងបិទអេក្រង់។\n\nសាកល្បងចុចថ្នមៗ ខណៈពេលកំពុងរៀបចំស្នាមម្រាមដៃរបស់អ្នក។"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"ចុច ដើម្បីបិទអេក្រង់"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"បិទ​អេក្រង់"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"ដើម្បីបញ្ចប់ការរៀបចំ សូមបិទអេក្រង់"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"បិទ"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"បន្តផ្ទៀងផ្ទាត់ស្នាមម្រាមដៃរបស់អ្នកឬ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"អ្នកបានចុចប៊ូតុងថាមពល — ជាធម្មតាការធ្វើបែបនេះនឹងបិទអេក្រង់។\n\nសាកល្បងចុចថ្នមៗ ដើម្បីផ្ទៀងផ្ទាត់ស្នាមម្រាមដៃរបស់អ្នក។"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"បិទ​អេក្រង់"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ទូរទស្សន៍"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ទូរសព្ទ"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ភ្ជាប់​អូប៉ាល័រ"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"ឧបករណ៍ខាងក្រៅ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"កាស"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"ប្រព័ន្ធ"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 9925a26..7fd8aef 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ಮುಂದುವರಿಯಲು ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ ಅನ್ನು ನಮೂದಿಸಿ"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ಸೆನ್ಸರ್ ಮೇಲೆ ದೃಢವಾಗಿ ಒತ್ತಿರಿ"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಸ್ವಚ್ಛಗೊಳಿಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ಸೆನ್ಸರ್‌‌ ಸ್ವಚ್ಛಗೊಳಿಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ಸೆನ್ಸರ್ ಮೇಲೆ ದೃಢವಾಗಿ ಒತ್ತಿರಿ"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ಬೆರಳನ್ನು ತುಂಬಾ ನಿಧಾನವಾಗಿ ಸರಿಸಲಾಗಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ಮತ್ತೊಂದು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ಪವರ್ ಬಟನ್ ಒತ್ತುವುದು ಪತ್ತೆಯಾಗಿದೆ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ಪ್ರತಿ ಬಾರಿಯೂ ನಿಮ್ಮ ಬೆರಳಿನ ಸ್ಥಾನವನ್ನು ಸ್ವಲ್ಪ ಮಟ್ಟಿಗೆ ಬದಲಾಯಿಸಿ"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ, ದೃಢೀಕರಣವನ್ನು ಒತ್ತಿ"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಹಾರ್ಡ್‌ವೇರ್‌ ಲಭ್ಯವಿಲ್ಲ."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅವಧಿ ಮೀರಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಸೆಟಪ್ ಮಾಡುವ ಅವಧಿ ಮುಗಿದಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ಬಳಕೆದಾರರು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ರದ್ದುಪಡಿಸಿದ್ದಾರೆ."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ಹಲವಾರು ಪ್ರಯತ್ನಗಳು. ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಬದಲಾಗಿ ಸ್ಕ್ರೀನ್‌ಲಾಕ್ ಬಳಸಿ."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಬದಲಾಗಿ ಪರದೆಲಾಕ್ ಬಳಸಿ."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ಯಾವುದೇ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‌ ಅನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ರಿಪೇರಿ ಮಾಡುವವರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"ಫೇಸ್ ಮಾಡೆಲ್ ರಚಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ ಮಂದ ಪ್ರಕಾಶಮಾನವಿರುವ ಲೈಟ್ ಬಳಸಿ"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"ಸಾಕಷ್ಟು ಬೆಳಕು ಇಲ್ಲ"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ಫೋನ್ ಅನ್ನು ದೂರಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ಫೋನ್ ಅನ್ನು ಸಮೀಪಕ್ಕೆ ತನ್ನಿ"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ಫೋನ್ ಅನ್ನು ಮೇಲಕ್ಕೆ ಎತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ಬೂಟ್ ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"ನೀವು ಪವರ್ ಬಟನ್ ಒತ್ತಿದ್ದೀರಿ — ಇದು ಸಾಮಾನ್ಯವಾಗಿ ಸ್ಕ್ರೀನ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ.\n\nನಿಮ್ಮ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಹೊಂದಿಸುವಾಗ ಲಘುವಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"ಸ್ಕ್ರೀನ್ ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"ಸ್ಕ್ರೀನ್ ಆಫ್ ಮಾಡಿ"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"ಸೆಟಪ್ ಪೂರ್ಣಗೊಳಿಸಲು, ಸ್ಕ್ರೀನ್‌ ಆಫ್ ಮಾಡಿ"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ಆಫ್ ಮಾಡಿ"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಪರಿಶೀಲನೆ ಮುಂದುವರಿಸುವುದೇ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"ನೀವು ಪವರ್ ಬಟನ್ ಒತ್ತಿದ್ದೀರಿ — ಇದು ಸಾಮಾನ್ಯವಾಗಿ ಸ್ಕ್ರೀನ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ.\n\nನಿಮ್ಮ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಪರಿಶೀಲಿಸಲು ಲಘುವಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"ಸ್ಕ್ರೀನ್ ಆಫ್ ಮಾಡಿ"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ಟಿವಿ"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ಫೋನ್"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ಡಾಕ್ ಸ್ಪೀಕರ್‍‌ಗಳು"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"ಬಾಹ್ಯ ಸಾಧನ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ಹೆಡ್‌ಫೋನ್‌ಗಳು"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"ಸಿಸ್ಟಂ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 40c545f..35e9e85 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"화면 잠금 사용"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"계속하려면 화면 잠금용 사용자 인증 정보를 입력하세요"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"센서 위에 손가락을 좀 더 오래 올려놓으세요."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"지문 센서를 닦은 후 다시 시도해 보세요."</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"센서를 닦은 후 다시 시도해 보세요."</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"센서 위에 손가락을 좀 더 오래 올려놓으세요."</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"손가락을 너무 느리게 움직였습니다. 다시 시도해 주세요."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"다른 지문으로 시도"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"너무 밝음"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"전원 누름이 감지되었습니다."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"조정 시도"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"지문을 등록할 때마다 손가락을 조금씩 이동하세요"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"얼굴이 인증되었습니다. 확인을 누르세요"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"지문 인식 하드웨어를 사용할 수 없습니다."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"지문을 설정할 수 없음"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"지문 인식 시간이 초과되었습니다. 다시 시도하세요."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"지문 설정 시간이 초과되었습니다. 다시 시도해 주세요."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"지문 인식 작업이 취소되었습니다."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"사용자가 지문 인식 작업을 취소했습니다."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"시도 횟수가 너무 많습니다. 나중에 다시 시도하세요."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"시도 횟수가 너무 많습니다. 화면 잠금을 대신 사용하세요."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"시도 횟수가 너무 많습니다. 화면 잠금을 대신 사용하세요."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"다시 시도해 보세요."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"지문을 처리할 수 없습니다. 다시 시도해 주세요."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"등록된 지문이 없습니다."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"수리업체에 방문하세요."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"얼굴 모델을 만들 수 없습니다. 다시 시도해 주세요."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"너무 밝습니다. 조명 밝기를 조금 낮춰보세요."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"조명이 부족합니다."</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"휴대전화를 얼굴에서 더 멀리 떨어뜨려 주세요."</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"휴대전화를 얼굴에 더 가까이 가져와 주세요."</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"휴대전화를 위로 이동하세요"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"앱을 시작하는 중입니다."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"부팅 완료"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"전원 버튼을 눌렀습니다. 이러면 보통 화면이 꺼집니다.\n\n지문 설정 중에 가볍게 탭하세요."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"탭하여 화면 끄기"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"화면 끄기"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"설정을 완료하려면 화면을 끄세요"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"사용 중지"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"지문 인증을 계속할까요?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"전원 버튼을 눌렀습니다. 이러면 보통 화면이 꺼집니다.\n\n지문을 인식하려면 화면을 가볍게 탭하세요."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"화면 끄기"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"휴대전화"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"도크 스피커"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"외부 기기"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"헤드폰"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"시스템"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index f27b0d6..176a49d 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Экран кулпусун колдонуу"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Улантуу үчүн экрандын кулпусун киргизиңиз"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Сенсорду катуу басыңыз"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Манжа изи иштелбей койду. Кайталап көрүңүз."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Манжа изи таанылбай жатат. Кайра аракет кылыңыз."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Манжа изинин сенсорун тазалап, кайра аракет кылыңыз"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Сенсорду тазалап, кайра аракет кылыңыз"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Сенсорду катуу басыңыз"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Манжа өтө жай жылды. Кайталап көрүңүз."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Башка манжа изин байкап көрүңүз"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Өтө жарык"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Кубат баскычы басылганы аныкталды"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Тууралап көрүңүз"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Манжаңыздын абалын ар жолкусунда бир аз өзгөртүп туруңуз"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Жүздүн аныктыгы текшерилди, эми \"Ырастоону\" басыңыз"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Манжа изинин аппараттык камсыздоосу жеткиликтүү эмес."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Манжа изи жөндөлбөй жатат"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Манжа изин күтүү мөөнөтү бүттү. Кайталап көрүңүз."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Манжа изин тууралоо убакыты бүтүп калды. Кайра аракет кылыңыз."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Манжа изи иш-аракети жокко чыгарылды."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Манжа изи операциясын колдонуучу жокко чыгарды."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Аракеттер өтө көп болду. Бир аздан кийин кайталап көрүңүз."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Өтө көп жолу аракет кылдыңыз. Экранды кулпулоо функциясын колдонуңуз."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Өтө көп жолу аракет кылдыңыз. Экранды кулпулоо функциясын колдонуңуз."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Кайра бир аракеттениңиз."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Манжа изи иштетилген жок. Кайра аракет кылыңыз."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бир да манжа изи катталган эмес."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Тейлөө кызматына кайрылыңыз."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Жүзүңүздүн үлгүсү түзүлгөн жок. Кайталаңыз."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Өтө жарык. Жарыктыкты азайтып көрүңүз."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Жарык жетишсиз"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Телефонду алыстатыңыз"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Телефонду жакындатыңыз"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Телефонду жогору жылдырыңыз"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Колдонмолорду иштетип баштоо"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Жүктөлүүдө"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Кубат баскычын бастыңыз — адатта, бул экранды өчүрөт.\n\nМанжаңыздын изин жөндөп жатканда аны акырын басып көрүңүз."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Экранды өчүрүү үчүн таптаңыз"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Экранды өчүрүү"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Тууралап бүтүрүү үчүн экранды өчүрүңүз"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Өчүрүү"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Манжаңыздын изин ырастоону улантасызбы?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Кубат баскычын бастыңыз — адатта, бул экранды өчүрөт.\n\nМанжаңыздын изин ырастоо үчүн аны акырын басып көрүңүз."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Экранды өчүрүү"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Сыналгы"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Аудио док бекет"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Тышкы түзмөк"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Кулакчын"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Тутум"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 7c9f815..7ca4b56 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ໃຊ້ການລັອກໜ້າຈໍ"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ໃສ່ການລັອກໜ້າຈໍຂອງທ່ານເພື່ອສືບຕໍ່"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ກົດຢູ່ເຊັນເຊີໃຫ້ແໜ້ນ"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ບໍ່​ສາ​ມາດ​ດຳ​ເນີນ​ການ​ລາຍ​ນີ້ວ​ມື​ໄດ້. ກະ​ລຸ​ນາ​ລອງ​ໃໝ່​ອີກ."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ບໍ່ສາມາດຈຳແນກລາຍນິ້ວມືໄດ້. ກະລຸນາລອງໃໝ່."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ໃຫ້ອະນາໄມເຊັນ​ເຊີລາຍນິ້ວ​ມືແລ້ວລອງໃໝ່"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ໃຫ້ອະນາໄມເຊັນ​ເຊີແລ້ວລອງໃໝ່"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ກົດຢູ່ເຊັນເຊີໃຫ້ແໜ້ນ"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ຍ້າຍ​ນີ້ວ​ມື​ໄປຊ້າ​ເກີນ​ໄປ. ກະ​ລຸ​ນາ​ລອງ​ໃໝ່​ອີກ."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ລອງໃຊ້ລາຍນິ້ວມືອື່ນ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ແຈ້ງເກີນໄປ"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ກວດພົບແຮງກົດ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ກະລຸນາລອງປັບແກ້"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ປ່ຽນຕຳແໜ່ງຂອງນິ້ວມືຂອງທ່ານເລັກນ້ອຍໃນແຕ່ລະເທື່ອ"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ, ກະລຸນາກົດຢືນຢັນ"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ບໍ່​ມີ​ຮາດ​ແວລາຍ​ນີ້ວ​ມື​ໃຫ້​ຢູ່."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ບໍ່ສາມາດຕັ້ງຄ່າລາຍນິ້ວມືໄດ້"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ເວ​ລາ​ລາຍ​ນີ້ວ​ມື​ບໍ່​ເຂົ້າ​ເຖິງ​ໄດ້. ລອງ​ໃໝ່​ອີກ."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ໝົດເວລາຕັ້ງຄ່າລາຍນິ້ວມື. ກະລຸນາລອງໃໝ່."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ຍົກ​ເລີກ​ການ​ດຳ​ເນີນ​ການ​ລາຍ​ນີ້ວ​ມື​ແລ້ວ."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ຜູ້ໃຊ້ໄດ້ຍົກເລີກຄຳສັ່ງລາຍນິ້ວມືແລ້ວ."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ມີ​ຄວາມ​ພະ​ຍາ​ຍາມ​ຫຼາຍ​ຄັ້ງ​ເກີນ​ໄປ. ລອງ​ໃໝ່​ພາຍ​ຫຼັງ."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ພະຍາຍາມຫຼາຍເທື່ອເກີນໄປ. ກະລຸນາໃຊ້ການລອກໜ້າຈໍແທນ."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ພະຍາຍາມຫຼາຍເທື່ອເກີນໄປ. ກະລຸນາໃຊ້ການລອກໜ້າຈໍແທນ."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ລອງໃໝ່ອີກຄັ້ງ."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ບໍ່ສາມາດປະມວນຜົນລາຍນິ້ວມືໄດ້. ກະລຸນາລອງໃໝ່."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ບໍ່ມີການລົງທະບຽນລາຍນິ້ວມື."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ກະລຸນາໄປຫາຜູ້ໃຫ້ບໍລິການສ້ອມແປງ."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"ບໍ່ສາມາດສ້າງຮູບແບບໃບໜ້າຂອງທ່ານໄດ້. ກະລຸນາລອງໃໝ່."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ແຈ້ງເກີນໄປ. ລອງຄ່ອຍແສງໄຟລົງ."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"ແສງບໍ່ພໍ"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ເລື່ອນໂທລະສັບອອກໄປໄກຂຶ້ນ"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ເລື່ອນໂທລະສັບເຂົ້າໄປໃກ້ຂຶ້ນ"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ຍົກໂທລະສັບໃຫ້ສູງຂຶ້ນ"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ກຳລັງເປີດແອັບຯ."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ກຳລັງສຳເລັດການເປີດລະບົບ."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"ທ່ານກົດປຸ່ມເປີດປິດ, ປົກກະຕິນີ້ຈະປິດໜ້າຈໍ.\n\nລອງແຕະຄ່ອຍໆໃນລະຫວ່າງຕັ້ງຄ່າລາຍນິ້ວມືຂອງທ່ານ."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"ແຕະເພື່ອປິດໜ້າຈໍ"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"ປິດໜ້າຈໍ"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"ເພື່ອສິ້ນສຸດການຕັ້ງຄ່າ, ໃຫ້ປິດໜ້າຈໍ"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ປິດໄວ້"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"ສືບຕໍ່ການຢັ້ງຢືນລາຍນິ້ວມືຂອງທ່ານບໍ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"ທ່ານກົດປຸ່ມເປີດປິດ, ປົກກະຕິນີ້ຈະເປັນການປິດໜ້າຈໍ.\n\nໃຫ້ລອງແຕະຄ່ອຍໆເພື່ອຢັ້ງຢືນລາຍນິ້ວມືຂອງທ່ານ."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"ປິດໜ້າຈໍ"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ໂທລະພາບ"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ໂທລະສັບ"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ບ່ອນຕັ້ງລຳໂພງ"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"ອຸປະກອນພາຍນອກ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ຫູຟັງ"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"ລະບົບ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 2954f9c..9f646f0 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Naudoti ekrano užraktą"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jei norite tęsti, įveskite ekrano užraktą"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tvirtai paspauskite jutiklį"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nepavyko apdoroti piršto antspaudo. Bandykite dar kartą."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Nepavyko atpažinti kontrolinio kodo. Bandykite dar kartą."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nuvalykite kontrolinio kodo jutiklį ir bandykite dar kartą"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nuvalykite jutiklį ir bandykite dar kartą"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tvirtai paspauskite jutiklį"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Per lėtai judinate pirštą. Bandykite dar kartą."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Pabandykite kitą kontrolinį kodą"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Per šviesu"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Aptiktas maitinimo mygtuko paspaudimas"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pabandykite koreguoti"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Kaskart šiek tiek pakeiskite piršto poziciją"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Veidas autentifikuotas, paspauskite patvirtinimo mygtuką"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Piršto antspaudo aparatinė įranga nepasiekiama."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nepavyko nustatyti kontrolinio kodo"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Baigėsi piršto antspaudo nustatymo skirtasis laikas. Bandykite dar kartą."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Baigėsi kontrolinio kodo sąrankos skirtasis laikas. Bandykite dar kartą."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Piršto antspaudo operacija atšaukta."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Piršto antspaudo operaciją atšaukė naudotojas."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Per daug bandymų. Vėliau bandykite dar kartą."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Per daug bandymų. Naudokite ekrano užraktą."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Per daug bandymų. Naudokite ekrano užraktą."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Bandykite dar kartą."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nepavyko apdoroti kontrolinio kodo. Bandykite dar kartą."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neužregistruota jokių kontrolinių kodų."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Apsilankykite pas taisymo paslaugos teikėją."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Nepavyko sukurti veido modelio. Band. dar kartą."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Per šviesu. Išbandykite mažesnį apšvietimą."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nepakanka apšvietimo"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Laikykite telefoną toliau"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Laikykite telefoną arčiau"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Laikykite telefoną aukščiau"</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Paleidžiamos programos."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Užbaigiamas paleidimas."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Paspaudėte maitinimo mygtuką, taip paprastai išjungiamas ekranas.\n\nNustatydami kontrolinį kodą, pabandykite jį švelniai paliesti."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Palieskite, kad išjungtumėte ekraną"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Išjungti ekraną"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Sąrankos užbaigimas išjungus ekraną"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Išjungti"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Tęsti kontrolinio kodo patvirtinimą?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Paspaudėte maitinimo mygtuką, taip paprastai išjungiamas ekranas.\n\nNorėdami patvirtinti kontrolinį kodą, pabandykite jį švelniai paliesti."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Išjungti ekraną"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefonas"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Doko garsiakalbiai"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Išorinis įrenginys"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Ausinės"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 853a490..3a078db 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekrāna bloķēšanas metodes izmantošana"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Lai turpinātu, ievadiet ekrāna bloķēšanas informāciju"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Stingri spiediet pirkstu pie sensora"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nevarēja apstrādāt pirksta nospiedumu. Lūdzu, mēģiniet vēlreiz."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Nevar atpazīt pirksta nospiedumu. Mēģiniet vēlreiz."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Notīriet pirkstu nospiedumu sensoru un mēģiniet vēlreiz"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Notīriet sensoru un mēģiniet vēlreiz"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Stingri spiediet pirkstu pie sensora"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pārāk lēna pirksta kustība. Lūdzu, mēģiniet vēlreiz."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Izmēģiniet citu pirksta nospiedumu"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Pārāk spilgts"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Konstatēta barošanas pogas nospiešana"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Mēģiniet mainīt pozīciju"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Katru reizi mazliet mainiet pirksta pozīciju."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Seja ir autentificēta. Nospiediet pogu Apstiprināt."</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Nospieduma aparatūra nav pieejama."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nevar iestatīt pirksta nospiedumu"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Pirkstu nospiedumu nolasīšanas aparatūras noildze. Mēģiniet vēlreiz."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Iestatot pirksta nospiedumu, iestājās noildze. Mēģiniet vēlreiz."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Nospieduma darbība neizdevās."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Lietotājs atcēla pirksta nospieduma darbību."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Pārāk daudz mēģinājumu. Vēlāk mēģiniet vēlreiz."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Pārāk daudz mēģinājumu. Izmantojiet ekrāna bloķēšanu."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Pārāk daudz mēģinājumu. Izmantojiet ekrāna bloķēšanu."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Mēģiniet vēlreiz."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nevar apstrādāt pirksta nospiedumu. Mēģiniet vēlreiz."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nav reģistrēts neviens pirksta nospiedums."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Sazinieties ar remonta pakalpojumu sniedzēju."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Nevar izveidot sejas modeli. Mēģiniet vēlreiz."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Pārāk spilgts. Izmēģiniet maigāku apgaismojumu."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nepietiekams apgaismojums"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Pārvietojiet tālruni tālāk."</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Pārvietojiet tālruni tuvāk."</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Paceliet tālruni augstāk."</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Notiek lietotņu palaišana."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Tiek pabeigta sāknēšana."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Jūs nospiedāt barošanas pogu — tādējādi parasti tiek izslēgts ekrāns.\n\nMēģiniet viegli pieskarties, iestatot pirksta nospiedumu."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Pieskarieties, lai izslēgtu ekrānu"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Izslēgt ekrānu"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Lai beigtu iestatīt, izslēdziet ekrānu"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Izslēgt"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Vai apstiprināt pirksta nospiedumu?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Jūs nospiedāt barošanas pogu — tādējādi parasti tiek izslēgts ekrāns.\n\nMēģiniet viegli pieskarties, lai apstiprinātu pirksta nospiedumu."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Izslēgt ekrānu"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Tālrunis"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Doka skaļruņi"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Ārēja ierīce"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Austiņas"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistēma"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 9ce43d1..c67819e 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користи заклучување екран"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Внесете го заклучувањето на екранот за да продолжите"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Цврсто притиснете на сензорот"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не може да се обработи. Обидете се повторно."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Не се препознава отпечатокот. Обидете се повторно."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Исчистете го сензорот за отпечатоци и обидете се повторно"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Исчистете го сензорот и обидете се повторно"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Цврсто притиснете на сензорот"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Прстот се движеше премногу бавно. Обидете се повторно."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте со друг отпечаток"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Премногу светло"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Откриено е притискање на копчето за вклучување"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да го приспособите прстот"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Менувајте ја положбата на прстот по малку секој пат"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицето е проверено, притиснете го копчето „Потврди“"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хардверот за отпечатоци не е достапен."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не може да се постави отпечаток"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Се достигна времето на истекување на отпечатокот. Обидете се повторно."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Времето за поставување отпечаток истече. Обидете се повторно."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Операцијата со отпечаток се откажа."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Корисникот ја откажа потврдата со отпечаток."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Премногу обиди. Обидете се повторно подоцна."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Премногу обиди. Користете заклучување екран."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Премногу обиди. Користете заклучување екран."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Обидете се повторно."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Не може да се обработи отпечатокот од прст. Обидете се повторно."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Не се запишани отпечатоци."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Однесете го на поправка."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Не може да создаде модел на лик. Обидете се пак."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Премногу светла. Пробајте со послабо осветлување."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Нема доволно светлина"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Оддалечете го телефонот"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Доближете го телефонот"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Кренете го телефонот погоре"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Се стартуваат апликациите."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Подигањето завршува."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Го притиснавте копчето за вклучување — така обично се исклучува екранот.\n\nДопрете лесно додека го поставувате отпечатокот."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Допрете за да го исклучите екранот"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Исклучи го екранот"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"За да завршите со поставувањето, исклучете го екранот."</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Исклучи"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Да продолжи потврдувањето на отпечаток?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Го притиснавте копчето за вклучување — така обично се исклучува екранот.\n\nДопрете лесно за да го потврдите отпечатокот."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Исклучи го екранот"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Телевизор"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Приклучи звучници"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Надворешен уред"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Слушалки"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Систем"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index c71047d..63a5e0d 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"തുടരാൻ നിങ്ങളുടെ സ്‌ക്രീൻ ലോക്ക് നൽകുക"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"സെൻസറിന് മുകളിൽ ശക്തിയായി അമർത്തുക"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ഫിംഗർപ്രിന്റ് പ്രോസസ് ചെയ്യാനായില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ഫിംഗർപ്രിന്റ് തിരിച്ചറിയാനാകുന്നില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ഫിംഗർപ്രിന്റ് സെൻസർ വൃത്തിയാക്കിയ ശേഷം വീണ്ടും ശ്രമിക്കുക"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"സെൻസർ വൃത്തിയാക്കിയ ശേഷം വീണ്ടും ശ്രമിക്കുക"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"സെൻസറിന് മുകളിൽ ശക്തിയായി അമർത്തുക"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"വിരൽ വളരെ പതുക്കെ നീക്കി. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"മറ്റൊരു ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് നോക്കുക"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"തെളിച്ചം വളരെയധികമാണ്"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"പവർ ബട്ടൺ അമർത്തിയത് തിരിച്ചറിഞ്ഞു"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"അൽപ്പം നീക്കി നോക്കൂ"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ഓരോ തവണയും നിങ്ങളുടെ വിരലിന്റെ സ്ഥാനം ചെറുതായി മാറ്റുക"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു, സ്ഥിരീകരിക്കുക അമർത്തുക"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ഫിംഗർപ്രിന്റ് ഹാർഡ്‌വെയർ ലഭ്യമല്ല."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ഫിംഗർപ്രിന്റ് സജ്ജീകരിക്കാനാകില്ല"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ഫിംഗർപ്രിന്റ് നൽകേണ്ട സമയം കഴിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ഫിംഗർപ്രിന്റ് സജ്ജീകരണം ടൈംഔട്ടായി. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ഫിംഗർപ്രിന്റ് പ്രവർത്തനം റദ്ദാക്കി."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ഉപയോക്താവ് റദ്ദാക്കിയ ഫിംഗർപ്രിന്‍റ് പ്രവർത്തനം."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"നിരവധി തവണ ശ്രമിച്ചു. പിന്നീട് വീണ്ടും ശ്രമിക്കുക."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"നിരവധി ശ്രമങ്ങൾ. പകരം സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"നിരവധി ശ്രമങ്ങൾ. പകരം സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"വീണ്ടും ശ്രമിക്കൂ."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ഫിംഗർപ്രിന്റ് പ്രോസസ് ചെയ്യാനാകില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"വിരലടയാളങ്ങൾ എൻറോൾ ചെയ്തിട്ടില്ല."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"റിപ്പയർ കേന്ദ്രം സന്ദർശിക്കുക."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"മുഖ മോഡൽ സൃഷ്ടിക്കാനാകുന്നില്ല. വീണ്ടും ശ്രമിക്കൂ."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"വളരെയധികം തെളിച്ചം. സൗമ്യതയേറിയ പ്രകാശം ശ്രമിക്കൂ."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"വേണ്ടത്ര പ്രകാശമില്ല"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ഫോൺ കൂടുതൽ ദൂരേയ്ക്ക് നീക്കുക"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ഫോൺ അടുത്തേക്ക് നീക്കുക"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ഫോൺ മുകളിലേക്ക് ഉയർത്തുക"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"അപ്ലിക്കേഷനുകൾ ആരംഭിക്കുന്നു."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ബൂട്ട് ചെയ്യൽ പൂർത്തിയാകുന്നു."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"നിങ്ങൾ പവർ ബട്ടൺ അമർത്തി — സാധാരണയായി ഇത് സ്ക്രീൻ ഓഫാകുന്നതിന് കാരണമാകും.\n\nനിങ്ങളുടെ ഫിംഗർപ്രിന്റ് സജ്ജീകരിക്കുമ്പോൾ മൃദുവായി ടാപ്പ് ചെയ്ത് നോക്കുക."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"സ്ക്രീൻ ഓഫാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"സ്ക്രീൻ ഓഫാക്കുക"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"സജ്ജീകരണം നിർത്താൻ, സ്ക്രീൻ ഓഫാക്കുക"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ഓഫാക്കുക"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"ഫിംഗർപ്രിന്റ് പരിശോധിച്ചുറപ്പിക്കൽ തുടരണോ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"നിങ്ങൾ പവർ ബട്ടൺ അമർത്തി — സാധാരണയായി ഇത് സ്ക്രീൻ ഓഫാകുന്നതിന് കാരണമാകും.\n\nനിങ്ങളുടെ ഫിംഗർപ്രിന്റ് പരിശോധിച്ചുറപ്പിക്കാൻ മൃദുവായി ടാപ്പ് ചെയ്ത് നോക്കുക."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"സ്ക്രീൻ ഓഫാക്കുക"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ടിവി"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ഫോണ്‍"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ഡോക്ക് സ്‌പീക്കറുകൾ"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"ബാഹ്യ ഉപകരണം"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ഹെഡ്‌ഫോണുകൾ"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"സിസ്റ്റം"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 417500d..9be2b2c 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Дэлгэцийн түгжээг ашиглах"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Үргэлжлүүлэхийн тулд дэлгэцийн түгжээгээ оруулна уу"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Мэдрэгч дээр чанга дарна уу"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Хурууны хээ боловсруулж чадахгүй байна. Дахин оролдоно уу."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Хурууны хээг таних боломжгүй. Дахин оролдоно уу."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Хурууны хээ мэдрэгчийг цэвэрлээд, дахин оролдоно уу"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Мэдрэгчийг цэвэрлээд, дахин оролдоно уу"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Мэдрэгч дээр чанга дарна уу"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Хуруу хэт удаан хөдөлгөсөн байна. Дахин оролдоно уу."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Өөр хурууны хээ туршина уу"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Хэт гэрэлтэй байна"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Цахилгаан даралтыг илрүүлсэн"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Тохируулж үзнэ үү"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Хурууныхаа байрлалыг тухай бүрд бага зэрэг өөрчилнө үү"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Царайг баталгаажууллаа. Баталгаажуулах товчлуурыг дарна уу"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хурууны хээний төхөөрөмж бэлэн бус байна."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Хурууны хээ тохируулах боломжгүй"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Хурууны хээ оруулах хугацаа өнгөрсөн байна. Дахин оруулна уу."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Хурууны хээний тохируулга завсарласан. Дахин оролдоно уу."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Хурууны хээний бүртгэл амжилтгүй боллоо."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Хэрэглэгч хурууны хээний баталгаажуулалтыг цуцалсан байна."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Хэтэрхий олон оролдлоо.  Түр хүлээгээд дахин оролдоно уу."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Хэт олон удаа оролдлоо. Оронд нь дэлгэцийн түгжээ ашиглана уу."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Хэт олон удаа оролдлоо. Оронд нь дэлгэцийн түгжээ ашиглана уу."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Дахин оролдно уу."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Хурууны хээг боловсруулах боломжгүй. Дахин оролдоно уу."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бүртгүүлсэн хурууны хээ алга."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Засварын үйлчилгээ үзүүлэгчид зочилно уу."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Нүүрний загвар үүсгэж чадсангүй. Дахин оролдоно уу."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Хэт цайвар байна. Гэрэл багатай газар оролдоно уу."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Гэрэл хангалтгүй байна"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Утсаа холдуулна уу"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Утсаа ойртуулна уу"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Утсаа дээшлүүлнэ үү"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Апп-г эхлүүлж байна."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Эхлэлийг дуусгаж байна."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Та асаах/унтраах товчийг дарсан байна — энэ нь ихэвчлэн дэлгэцийг унтраадаг.\n\nХурууны хээгээ тохируулж байх үедээ зөөлөн товшиж үзнэ үү."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Дэлгэцийг унтраахын тулд товшино уу"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Дэлгэцийг унтраах"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Тохиргоог дуусгахын тулд дэлгэцийг унтраана уу"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Унтраах"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Хурууны хээгээ үргэлжлүүлэн баталгаажуулах уу?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Та асаах/унтраах товчийг дарсан байна — энэ нь ихэвчлэн дэлгэцийг унтраадаг.\n\nХурууны хээгээ баталгаажуулахын тулд зөөлөн товшиж үзнэ үү."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Дэлгэцийг унтраах"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Tелевиз"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Утас"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Чанга яригчийг суулгах"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Гадаад төхөөрөмж"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Чихэвч"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Систем"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index f91a18f..5729355b 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रीन लॉक वापरा"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"पुढे सुरू ठेवण्यासाठी तुमचे स्क्रीन लॉक एंटर करा"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"सेन्सरवर जोरात दाबा"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिंटवर प्रक्रिया करणे शक्य झाले नाही. कृपया पुन्हा प्रयत्न करा."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"फिंगरप्रिंट ओळखता आली नाही. पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"फिंगरप्रिंट सेन्सर स्वच्छ करा आणि पुन्हा प्रयत्न करा"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"सेन्सर स्वच्छ करा आणि पुन्हा प्रयत्न करा"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"सेन्सरवर जोरात दाबा"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"बोट खूप सावकाश हलविले. कृपया पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"दुसरी फिंगरप्रिंट वापरून पहा"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"खूप प्रखर"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"पॉवर बटण दाबले गेल्याचे डिटेक्ट केले"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"अ‍ॅडजस्ट करण्याचा प्रयत्न करा"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"तुमच्या बोटाची स्थिती प्रत्येक वेळी थोडीशी बदला"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"चेहरा ऑथेंटिकेशन केलेला आहे, कृपया कंफर्म दाबा"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"फिंगरप्रिंट हार्डवेअर उपलब्‍ध नाही."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"फिंगरप्रिंट सेट करता आली नाही"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"फिंगरप्रिंट टाइमआउट झाले. पुन्हा प्रयत्न करा."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"फिंगरप्रिट सेट करण्याची वेळ संपली आहे. पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"फिंगरप्रिंट ऑपरेशन रद्द झाले."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"वापरकर्त्याने फिंगरप्रिंट ऑपरेशन रद्द केले."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"खूप प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"खूप जास्त प्रयत्न. त्याऐवजी स्क्रीन लॉक वापरा."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"खूप जास्त प्रयत्न. त्याऐवजी स्क्रीन लॉक वापरा."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"पुन्हा प्रयत्न करा."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"फिंगरप्रिंटवर प्रक्रिया करू शकत नाही. पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोणत्याही फिंगरप्रिंटची नोंद झाली नाही"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"दुरुस्तीच्या सेवा पुरवठादाराला भेट द्या."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"फेस मॉडेल तयार करू शकत नाही. पुन्हा प्रयत्न करा."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"खूप प्रखर. आणखी सौम्य प्रकाश वापरून पहा."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"पुरेसा प्रकाश नाही"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"फोन आणखी दूर हलवा"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"फोन आणखी जवळ हलवा"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"फोन आणखी वर हलवा"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"अ‍ॅप्स सुरू करत आहे."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"बूट समाप्त होत आहे."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"तुम्ही पॉवर बटण दाबले — हे सहसा स्क्रीन बंद करते.\n\nतुमचे फिंगरप्रिंट सेट करताना हलके टॅप करून पहा."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"स्क्रीन बंद करण्यासाठी टॅप करा"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"स्क्रीन बंद करा"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"सेटअप संपवण्यासाठी, स्क्रीन बंद करा"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"बंद करा"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"फिंगरप्रिंट पडताळणी सुरू ठेवायची का?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"तुम्ही पॉवर बटण दाबले — हे सहसा स्क्रीन बंद करते.\n\nतुमच्या फिंगरप्रिंटची पडताळणी करण्यासाठी हलके टॅप करून पहा."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"स्क्रीन बंद करा"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"टीव्ही"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"फोन"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"स्पीकर डॉक करा"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"बाह्य डिव्हाइस"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"हेडफोन"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"सिस्टम"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 9b76a16..3595acc 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci skrin"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Masukkan kunci skrin untuk teruskan"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tekan dengan kuat pada penderia"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses cap jari. Sila cuba lagi."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Tidak dapat mengecam cap jari. Cuba lagi."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Bersihkan penderia cap jari dan cuba lagi"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Bersihkan penderia dan cuba lagi"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tekan dengan kuat pada penderia"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Jari digerakkan terlalu perlahan. Sila cuba lagi."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Cuba cap jari lain"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Penekanan Kuasa dikesan"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Cuba selaraskan"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Tukar sedikit kedudukan jari anda setiap kali pergerakan dilakukan"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Wajah disahkan, sila tekan sahkan"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Perkakasan cap jari tidak tersedia."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Tidak dapat menyediakan cap jari"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Sudah tamat masa untuk cap jari. Cuba lagi"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Persediaan cap jari telah tamat masa. Cuba lagi."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Pengendalian cap jari dibatalkan."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Pengendalian cap jari dibatalkan oleh pengguna."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Terlalu banyak percubaan. Cuba sebentar lagi."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Terlalu banyak percubaan. Gunakan kunci skrin."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Terlalu banyak percubaan. Gunakan kunci skrin."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Cuba lagi."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Tidak dapat memproses cap jari. Cuba lagi."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tiada cap jari didaftarkan."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Lawati penyedia pembaikan."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Tidak dapat membuat model wajah anda. Cuba lagi."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Terlalu terang. Cuba pencahayaan yang lebih lembut."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Cahaya tidak mencukupi"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Jauhkan telefon"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Dekatkan telefon"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Tinggikan lagi telefon"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Memulakan apl."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"But akhir."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Anda menekan butang kuasa — tindakan ini biasanya mematikan skrin.\n\nCuba ketik dengan perlahan semasa menetapkan cap jari anda."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Ketik untuk mematikan skrin"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Matikan skrin"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Untuk tamatkan persediaan, matikan skrin"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Matikan"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Terus mengesahkan cap jari anda?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Anda menekan butang kuasa — tindakan ini biasanya mematikan skrin.\n\nCuba ketik dengan perlahan untuk mengesahkan cap jari anda."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Matikan skrin"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Pembesar suara dok"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Peranti Luar"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Fon kepala"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 87916c4..da34c95 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ရှေ့ဆက်ရန် သင်၏ဖန်သားပြင် လော့ခ်ချခြင်းကို ထည့်ပါ"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"အာရုံခံကိရိယာပေါ်တွင် သေချာဖိပါ"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"လက်ဗွေယူ၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"လက်ဗွေကို မမှတ်မိပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"လက်ဗွေ အာရုံခံကိရိယာကို သန့်ရှင်းပြီး ထပ်စမ်းကြည့်ပါ"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"အာရုံခံကိရိယာကို သန့်ရှင်းပြီး ထပ်စမ်းကြည့်ပါ"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"အာရုံခံကိရိယာပေါ်တွင် သေချာဖိပါ"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"လက်ညှိုးအလွန်နှေးကွေးစွာ ရွေ့ခဲ့သည်။ ကျေးဇူးပြု၍ ထပ်မံကြိုးစားပါ။"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"အခြားလက်ဗွေဖြင့် စမ်းကြည့်ပါ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"အလွန် လင်းသည်"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ဖွင့်ပိတ်ခလုတ် နှိပ်လိုက်သည်"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ပြင်ဆင်ကြည့်ပါ"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"အကြိမ်တိုင်း သင့်လက်ချောင်း၏ အနေအထားကို အနည်းငယ်ပြောင်းပါ"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ၊ အတည်ပြုရန်ကို နှိပ်ပါ"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"လက်ဗွေ စက်ပစ္စည်းမရနိုင်ပါ။"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"လက်ဗွေကို စနစ်ထည့်သွင်း၍ မရပါ"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"လက်ဗွေယူချိန်ကုန် သွားပါသည်။ ထပ်စမ်းကြည့်ပါ။"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"လက်ဗွေစနစ်ထည့်သွင်းချိန် ကုန်သွားပါပြီ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"လက်ဗွေယူခြင်း ပယ်ဖျက်လိုက်သည်။"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"လက်ဗွေဖြင့် အထောက်အထားစိစစ်ခြင်းကို အသုံးပြုသူက ပယ်ဖျက်ထားသည်။"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ကြိုးစာမှု အကြိမ်များနေ၏။ နောက်မှ ထပ်မံကြိုးစားပါ။"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ကြိုးပမ်းမှုအကြိမ်ရေ များလွန်းသည်။ ဖန်သားပြင်လော့ခ်ချခြင်းကို အစားထိုးသုံးပါ။"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ကြိုးပမ်းမှုအကြိမ်ရေ များလွန်းသည်။ ဖန်သားပြင်လော့ခ်ချခြင်းကို အစားထိုးသုံးပါ။"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ပြန်ကြိုးစားပါ"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"လက်ဗွေကို လုပ်ဆောင်နိုင်ခြင်းမရှိပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"မည်သည့် လက်ဗွေကိုမျှ ထည့်သွင်းမထားပါ။"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ပြုပြင်ရေး ဝန်ဆောင်မှုပေးသူထံသို့ သွားပါ။"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"သင့်မျက်နှာနမူနာ ပြုလုပ်၍မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"အလွန် လင်းသည်။ အလင်းလျှော့ကြည့်ပါ။"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"အလင်းရောင် အားနည်းသည်"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ဖုန်းကို အဝေးသို့ခွာပါ"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ဖုန်းကို အနားသို့ပိုတိုးပါ"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ဖုန်းကို ပိုမြှင့်လိုက်ပါ"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"အက်ပ်များကို စတင်နေ"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"လုပ်ငန်းစနစ်ထည့်သွင်း၍ ပြန်လည်စတင်ရန် ပြီးပါပြီ"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"ဖွင့်ပိတ်ခလုတ်ကို သင်နှိပ်ခဲ့သည် — ၎င်းက ပုံမှန်အားဖြင့် စခရင်ကို ပိတ်စေသည်။\n\nသင့်လက်ဗွေကို ထည့်သွင်းသောအခါ ဖွဖွတို့ကြည့်ပါ။"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"ဖန်သားပြင်ပိတ်ရန် တို့ပါ"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"ဖန်သားပြင် ပိတ်ရန်"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"စနစ်ထည့်သွင်းမှုရပ်ရန် ဖန်သားပြင်ပိတ်ပါ"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ပိတ်ရန်"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"သင့်လက်ဗွေကို ဆက်၍ အတည်ပြုမလား။"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"ဖွင့်ပိတ်ခလုတ်ကို သင်နှိပ်ခဲ့သည် — ၎င်းက ပုံမှန်အားဖြင့် စခရင်ကို ပိတ်စေသည်။\n\nသင့်လက်ဗွေကို အတည်ပြုရန် ဖွဖွတို့ကြည့်ပါ။"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"စခရင် ပိတ်ရန်"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ဖုန်း"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"အထိုင်ရှိသော စပီကာများ"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"ပြင်ပစက်"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"နားကြပ်"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"စနစ်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index e101548..87e206d 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Bruk skjermlås"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Skriv inn skjermlåsen for å fortsette"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Trykk godt på sensoren"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kunne ikke registrere fingeravtrykket. Prøv på nytt."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Fingeravtrykket gjenkjennes ikke. Prøv på nytt."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengjør fingeravtrykkssensoren og prøv igjen"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengjør sensoren og prøv igjen"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Trykk godt på sensoren"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du flyttet fingeren for sakte. Prøv på nytt."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv et annet fingeravtrykk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"For lyst"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Trykk på av/på-knappen er registrert"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prøv å justere"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Endre posisjonen til fingeren litt hver gang"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet er autentisert. Trykk på Bekreft"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Maskinvare for fingeravtrykk er ikke tilgjengelig."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Kan ikke konfigurere fingeravtrykk"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Tidsavbrudd for fingeravtrykk er nådd. Prøv på nytt."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Konfigureringen av fingeravtrykk er tidsavbrutt. Prøv på nytt."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingeravtrykk-operasjonen ble avbrutt."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeravtrykk-operasjonen ble avbrutt av brukeren."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"For mange forsøk. Prøv på nytt senere."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"For mange forsøk. Bruk skjermlås i stedet."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"For mange forsøk. Bruk skjermlås i stedet."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Prøv på nytt."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Kan ikke behandle fingeravtrykket. Prøv på nytt."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ingen fingeravtrykk er registrert."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Gå til en reparasjonsleverandør."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Kan ikke lage ansiktsmodell. Prøv på nytt."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"For lyst. Prøv svakere belysning."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Ikke nok lys"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Flytt telefonen lengre unna"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Flytt telefonen nærmere"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Flytt telefonen høyere"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starter apper."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Ferdigstiller oppstart."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Du har trykket på av/på-knappen – dette slår vanligvis av skjermen.\n\nPrøv å trykke lett mens du konfigurerer fingeravtrykket ditt."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Trykk for å slå av skjermen"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Slå av skjermen"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Slå av skjerm for å stoppe konfigurering"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Slå av"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Fortsett bekreftelse av fingeravtrykket?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Du har trykket på av/på-knappen – dette slår vanligvis av skjermen.\n\nPrøv å trykke lett for å bekrefte fingeravtrykket ditt."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Slå av skjermen"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Google TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dokkhøyttalere"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Ekstern enhet"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Hodetelefoner"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index b2bf381..5df7009 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रिन लक प्रयोग गर्नुहोस्"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"जारी राख्न आफ्नो स्क्रिन लक हाल्नुहोस्"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"सेन्सरमा बेसरी थिच्नुहोस्"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिन्ट प्रशोधन गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"फिंगरप्रिन्ट पहिचान गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"फिंगरप्रिन्ट सेन्सर सफा गरेर फेरि प्रयास गर्नुहोस्"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"सेन्सर सफा गरेर फेरि प्रयास गर्नुहोस्"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"सेन्सरमा बेसरी थिच्नुहोस्"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"औंला निकै सुस्त सारियो। कृपया फेरि प्रयास गर्नुहोस्।"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"अर्को फिंगरप्रिन्ट प्रयोग गरी हेर्नुहोस्"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ज्यादै उज्यालो छ"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"पावर बटन प्रेस गरेको कुरा पत्ता लाग्यो"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"सेन्सरमा सही तरिकाले औँला राखेर हेर्नुहोस्"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"हरेक पटक आफ्नो औँला थोरै यताउता सार्नुहोस्"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"अनुहार प्रमाणीकरण गरियो, कृपया पुष्टि गर्नुहोस् थिच्नुहोस्"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"औँठाछाप हार्डवेयर उपलब्ध छैन।"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"फिंगरप्रिन्ट सेटअप गर्न सकिएन"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"फिंगरप्रिन्ट समय सकिएको छ। फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"फिंगरप्रिन्ट सेट अप गर्ने समय सकियो। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"फिंगरप्रिन्ट सञ्चालन रद्द गरियो।"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"प्रयोगकर्ताले फिंगरप्रिन्टसम्बन्धी कारबाही रद्द गर्नुभयो।"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"धेरै प्रयासहरू। केहि समय पछि पुन: प्रयास गर्नुहोला"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"निकै धेरै पटक प्रयास गरिसकिएको छ। बरु स्क्रिन लक प्रयोग गर्नुहोस्।"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"निकै धेरै पटक प्रयास गरिसकिएको छ। बरु स्क्रिन लक प्रयोग गर्नुहोस्।"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"पुन: प्रयास गर्नुहोला।"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"फिंगरप्रिन्ट पहिचान गर्ने प्रक्रिया अघि बढाउन सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कुनै पनि फिंगरप्रिन्ट दर्ता गरिएको छैन।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो डिभाइसमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"फिंगरप्रिन्ट सेन्सर मर्मत गर्ने सेवा प्रदायक कम्पनीमा सम्पर्क गर्नुहोस्।"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"तपाईंको फेस मोडेल सिर्जना गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ज्यादै चम्किलो। अझ मधुरो प्रकाश प्रयोग गरी हेर्नु…"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"पर्याप्त उज्यालो छैन"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"फोन अझै पर सार्नुहोस्"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"फोन अझै नजिक सार्नुहोस्"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"फोन अझ माथि उठाउनुहोस्"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"सुरुवात एपहरू।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"बुट पुरा हुँदै।"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"तपाईंले पावर बटन थिच्नुभयो — सामान्यतया स्क्रिन अफ गर्न यो बटन थिच्ने गरिन्छ।\n\nफिंगरप्रिन्ट सेटअप भइन्जेल हल्का तरिकाले यो बटन ट्याप गर्नुहोस्।"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"स्क्रिन अफ गर्न ट्याप गर्नुहोस्"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"स्क्रिन अफ गर्नुहोस्"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"सेट अप गरिसक्न स्क्रिन अफ गर्नुहोस्"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"अफ गर्नुहोस्"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"फिंगरप्रिन्ट पुष्टि गर्ने क्रम जारी राख्ने हो?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"तपाईंले पावर बटन थिच्नुभयो — सामान्यतया स्क्रिन अफ गर्न यो बटन थिच्ने गरिन्छ।\n\nतपाईं आफ्नो फिंगरप्रिन्ट पुष्टि गर्न चाहनुहुन्छ भने हल्का तरिकाले यो बटन ट्याप गरी हेर्नुहोस्।"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"स्क्रिन अफ गर्नुहोस्"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"टिभी"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"फोन"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"डक स्पिकरहरू"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"बााह्य डिभाइस"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"हेडफोनहरू"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"प्रणाली"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 9811e27..f89bc78 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Schermvergrendeling gebruiken"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Voer je schermvergrendeling in om door te gaan"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Druk stevig op de sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kan vingerafdruk niet verwerken. Probeer het opnieuw."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Vingerafdruk niet herkend. Probeer het opnieuw."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Reinig de vingerafdruksensor en probeer het opnieuw"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Reinig de sensor en probeer het opnieuw"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Druk stevig op de sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vinger te langzaam bewogen. Probeer het opnieuw."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probeer een andere vingerafdruk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Te veel licht"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Druk op aan/uit-knop waargenomen"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Verplaats je vinger"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Verander de positie van je vinger steeds een beetje"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gezicht geverifieerd. Druk op Bevestigen."</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware voor vingerafdruk niet beschikbaar."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Kan vingerafdruk niet instellen"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Time-out bereikt voor vingerafdruk. Probeer het opnieuw."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Time-out bij instellen van vingerafdruk. Probeer het opnieuw."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Vingerafdrukbewerking geannuleerd."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Vingerafdrukverificatie geannuleerd door gebruiker."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Te veel pogingen. Probeer het later opnieuw."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Te veel pogingen. Gebruik in plaats daarvan de schermvergrendeling."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Te veel pogingen. Gebruik in plaats daarvan de schermvergrendeling."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Probeer het opnieuw."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Kan vingerafdruk niet verwerken. Probeer het opnieuw."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukken geregistreerd."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor staat tijdelijk uit."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Ga naar een reparateur."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Kan gezichtsmodel niet maken. Probeer het opnieuw."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Overbelicht. Probeer een minder felle belichting."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Te weinig licht"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Houd de telefoon verder weg"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Houd de telefoon dichterbij"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Houd de telefoon hoger"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Apps starten."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Opstarten afronden."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Je hebt op de aan/uit-knop gedrukt. Zo zet je meestal het scherm uit.\n\nRaak de knop voorzichtig aan terwijl je je vingerafdruk instelt."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tik om het scherm uit te zetten"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Scherm uitzetten"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Zet het scherm uit om het instellen te beëindigen"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Uitzetten"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Doorgaan met verificatie van je vingerafdruk?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Je hebt op de aan/uit-knop gedrukt. Zo zet je meestal het scherm uit.\n\nRaak de knop voorzichtig aan om je vingerafdruk te verifiëren."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Scherm uitzetten"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Tv"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefoon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dockluidsprekers"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Extern apparaat"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Hoofdtelefoon"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Systeem"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index d3cbaec..9b38ea8 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ସ୍କ୍ରିନ୍ ଲକ୍ ଏଣ୍ଟର୍ କରନ୍ତୁ"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ସେନ୍ସର ଉପରେ ଦୃଢ଼ ଭାବେ ଦବାନ୍ତୁ"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ଟିପଚିହ୍ନ ପ୍ରୋସେସ୍‍ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ଟିପଚିହ୍ନକୁ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ପରିଷ୍କାର କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ସେନ୍ସରକୁ ପରିଷ୍କାର କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ସେନ୍ସର ଉପରେ ଦୃଢ଼ ଭାବେ ଦବାନ୍ତୁ"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ଆଙ୍ଗୁଠି ଖୁବ୍‍ ଧୀରେ ନିଆଗଲା। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ଅନ୍ୟ ଏକ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ବହୁତ ଉଜ୍ଜ୍ୱଳ"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ପାୱାର ବଟନ ଦବାଇବା ଚିହ୍ନଟ କରାଯାଇଛି"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ଆଡଜଷ୍ଟ କରି ଦେଖନ୍ତୁ"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ପ୍ରତି ଥର ଆପଣଙ୍କ ଆଙ୍ଗୁଠିର ସ୍ଥାନ ସାମାନ୍ୟ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ମୁହଁ ଚିହ୍ନଟ ହୋଇଛି, ଦୟାକରି ସୁନିଶ୍ଚିତ ଦବାନ୍ତୁ"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ଟିପଚିହ୍ନ ହାର୍ଡୱେର୍‍ ଉପଲବ୍ଧ ନାହିଁ।"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ଟିପଚିହ୍ନକୁ ସେଟ୍ ଅପ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ଟିପଚିହ୍ନର ସମୟ ଶେଷ ହେଲା । ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ସେଟଅପର ସମୟସୀମା ସମାପ୍ତ ହୋଇଯାଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ଟିପଚିହ୍ନ କାର୍ଯ୍ୟ ବାତିଲ୍ କରାଗଲା।"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ଉପଯୋଗକର୍ତ୍ତା ଟିପଚିହ୍ନ କାର୍ଯ୍ୟ ବାତିଲ୍ କରିଛନ୍ତି।"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ବହୁତ ପ୍ରୟାସ କରାଗଲା। ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ଅନେକଗୁଡ଼ିଏ ପ୍ରଚେଷ୍ଟା। ଏହା ପରିବର୍ତ୍ତେ ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ଅନେକଗୁଡ଼ିଏ ପ୍ରଚେଷ୍ଟା। ଏହା ପରିବର୍ତ୍ତେ ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ଟିପଚିହ୍ନକୁ ପ୍ରକ୍ରିୟାନ୍ୱିତ କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"କୌଣସି ଆଙ୍ଗୁଠି ଚିହ୍ନ ପଞ୍ଜୀକୃତ ହୋଇନାହିଁ।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍‌ରେ ଟିପଚିହ୍ନ ସେନ୍‍ସର୍ ନାହିଁ।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ଏକ ମରାମତି କେନ୍ଦ୍ରକୁ ଭିଜିଟ୍ କରନ୍ତୁ।"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"ଫେସର ମଡେଲ ତିଆରି କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କର।"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ଅତ୍ୟଧିକ ଉଜ୍ଵଳ। କମ୍ ଉଜ୍ବଳକରଣରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"ଯଥେଷ୍ଟ ଆଲୋକ ନାହିଁ"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ଫୋନକୁ ଟିକେ ଦୂରକୁ ନିଅନ୍ତୁ"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ଫୋନକୁ ପାଖକୁ ଆଣନ୍ତୁ"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ଫୋନକୁ ଉପରକୁ ମୁଭ କରନ୍ତୁ"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ଆପ୍‍ ଆରମ୍ଭ କରାଯାଉଛି।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ବୁଟ୍‍ ସମାପ୍ତ କରୁଛି।"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"ଆପଣ ପାୱାର ବଟନ ଦବାଇଛନ୍ତି — ଏହା ସାଧାରଣତଃ ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ ବନ୍ଦ କରିଥାଏ।\n\nଆପଣଙ୍କ ଟିପଚିହ୍ନ ସେଟ ଅପ କରିବା ସମୟରେ ଧୀରେ ଟାପ କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"ସ୍କ୍ରିନ ବନ୍ଦ କରିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"ସ୍କ୍ରିନ ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"ସେଟଅପ ସମାପ୍ତ କରିବାକୁ ସ୍କ୍ରିନ ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"ଆପଣଙ୍କ ଟିପଚିହ୍ନ ଯାଞ୍ଚ କରିବା ଜାରି ରଖିବେ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"ଆପଣ ପାୱାର ବଟନ ଦବାଇଛନ୍ତି — ଏହା ସାଧାରଣତଃ ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ ବନ୍ଦ କରିଥାଏ।\n\nଆପଣଙ୍କ ଟିପଚିହ୍ନ ଯାଞ୍ଚ କରିବା ପାଇଁ ଧୀରେ ଟାପ କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"ସ୍କ୍ରିନ ବନ୍ଦ କରନ୍ତୁ"</string>
@@ -1273,7 +1273,7 @@
     <string name="volume_ringtone" msgid="134784084629229029">"ରିଙ୍ଗର୍‌ ଭଲ୍ୟୁମ୍"</string>
     <string name="volume_music" msgid="7727274216734955095">"ମିଡିଆ ଭଲ୍ୟୁମ୍‌"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"ବ୍ଲୁଟୂଥ୍‍ ମାଧ୍ୟମରେ ଚାଲୁଛି"</string>
-    <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ରିଙ୍ଗଟୋନ୍‍‍କୁ ନିରବ ଭାବେ ସେଟ୍ କରାଯାଇଛି"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ସାଇଲେଣ୍ଟ ରିଂଟୋନ ସେଟ ହୋଇଛି"</string>
     <string name="volume_call" msgid="7625321655265747433">"ଇନ୍‍-କଲ୍‍ ଭଲ୍ୟୁମ୍‌"</string>
     <string name="volume_bluetooth_call" msgid="2930204618610115061">"ବ୍ଲୁଟୂଥ୍‍ ଇନ୍-କଲ୍ ଭଲ୍ୟୁମ୍‌"</string>
     <string name="volume_alarm" msgid="4486241060751798448">"ଆଲାରାମ୍ ଭଲ୍ୟୁମ୍‌"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ଫୋନ"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ଡକ୍‌ ସ୍ପିକର୍‌"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"ଏକ୍ସଟର୍ନଲ ଡିଭାଇସ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ହେଡଫୋନ୍‍"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"ସିଷ୍ଟମ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2ffeef4..ed8278b 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਸਕ੍ਰੀਨ ਲਾਕ ਦਾਖਲ ਕਰੋ"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ਸੈਂਸਰ ਨੂੰ ਜ਼ੋਰ ਨਾਲ ਦਬਾਓ"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ਫਿੰਗਰਪ੍ਰਿੰਟ \'ਤੇ ਪ੍ਰਕਿਰਿਆ ਨਹੀਂ ਹੋ ਸਕੀ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਾਫ਼ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ਸੈਂਸਰ ਨੂੰ ਸਾਫ਼ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ਸੈਂਸਰ ਨੂੰ ਜ਼ੋਰ ਨਾਲ ਦਬਾਓ"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ਉਂਗਲ ਕਾਫ਼ੀ ਹੌਲੀ ਮੂਵ ਹੋਈ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ਕੋਈ ਹੋਰ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤ ਕੇ ਦੇਖੋ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਚਮਕ"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ਪਾਵਰ ਬਟਨ ਦਬਾਏ ਜਾਣ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ਵਿਵਸਥਿਤ ਕਰਕੇ ਦੇਖੋ"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ਹਰ ਵਾਰ ਆਪਣੀ ਉਂਗਲ ਨੂੰ ਥੋੜ੍ਹਾ ਹਿਲਾਓ"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ, ਕਿਰਪਾ ਕਰਕੇ \'ਪੁਸ਼ਟੀ ਕਰੋ\' ਦਬਾਓ"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਸੈੱਟਅੱਪ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਸਮਾਂ ਸਮਾਪਤ ਹੋ ਗਿਆ ਹੈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਸਮਾਂ ਸਮਾਪਤ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਓਪਰੇਸ਼ਨ ਰੱਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਓਪਰੇਸ਼ਨ ਵਰਤੋਂਕਾਰ ਵੱਲੋਂ ਰੱਦ ਕੀਤਾ ਗਿਆ।"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ. ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸਦੀ ਬਜਾਏ ਸਕ੍ਰੀਨ ਲਾਕ ਵਰਤੋ।"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸਦੀ ਬਜਾਏ ਸਕ੍ਰੀਨ ਲਾਕ ਵਰਤੋ।"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ਫਿੰਗਰਪ੍ਰਿੰਟ \'ਤੇ ਪ੍ਰਕਿਰਿਆ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ਕੋਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਰਜ ਨਹੀਂ ਕੀਤੇ ਗਏ।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ਮੁਰੰਮਤ ਪ੍ਰਦਾਨਕ \'ਤੇ ਜਾਓ।"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"ਤੁਹਾਡੇ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਨਹੀਂ ਬਣਿਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਚਮਕ। ਹਲਕੀ ਚਮਕ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"ਲੋੜੀਂਦੀ ਰੋਸ਼ਨੀ ਨਹੀਂ ਹੈ"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ਫ਼ੋਨ ਨੂੰ ਦੂਰ ਲਿਜਾਓ"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ਫ਼ੋਨ ਨੇੜੇ ਲਿਜਾਓ"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ਫ਼ੋਨ ਨੂੰ ਥੋੜ੍ਹਾ ਉੱਤੇ ਲਿਜਾਓ"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ਐਪਸ ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ਬੂਟ ਪੂਰਾ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"ਤੁਸੀਂ ਪਾਵਰ ਬਟਨ ਨੂੰ ਦਬਾਇਆ ਹੈ — ਇਹ ਆਮ ਤੌਰ \'ਤੇ ਸਕ੍ਰੀਨ ਨੂੰ ਬੰਦ ਕਰ ਦਿੰਦਾ ਹੈ।\n\nਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਸੈੱਟਅੱਪ ਕਰਦੇ ਸਮੇਂ ਹਲਕਾ ਜਿਹਾ ਟੈਪ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"ਸਕ੍ਰੀਨ ਬੰਦ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"ਸਕ੍ਰੀਨ ਬੰਦ ਕਰੋ"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"ਸੈੱਟਅੱਪ ਸਮਾਪਤ ਕਰਨ ਲਈ, ਸਕ੍ਰੀਨ ਨੂੰ ਬੰਦ ਕਰੋ"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ਬੰਦ ਕਰੋ"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"ਕੀ ਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"ਤੁਸੀਂ ਪਾਵਰ ਬਟਨ ਨੂੰ ਦਬਾਇਆ ਹੈ — ਇਹ ਆਮ ਤੌਰ \'ਤੇ ਸਕ੍ਰੀਨ ਨੂੰ ਬੰਦ ਕਰ ਦਿੰਦਾ ਹੈ।\n\nਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ ਹਲਕਾ ਜਿਹਾ ਟੈਪ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"ਸਕ੍ਰੀਨ ਬੰਦ ਕਰੋ"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ਫ਼ੋਨ ਕਰੋ"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ਡੌਕ ਸਪੀਕਰਸ"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"ਬਾਹਰੀ ਡੀਵਾਈਸ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ਹੈੱਡਫ਼ੋਨ"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"ਸਿਸਟਮ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 88b54b0..a3fbbad 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Używaj blokady ekranu"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Użyj blokady ekranu, aby kontynuować"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Mocno naciśnij czujnik"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nie udało się przetworzyć odcisku palca. Spróbuj ponownie."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Nie rozpoznaję odcisku palca. Spróbuj ponownie."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Wyczyść czytnik linii papilarnych i spróbuj ponownie"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Wyczyść czujnik i spróbuj ponownie"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Mocno naciśnij czujnik"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Palec został obrócony zbyt wolno. Spróbuj ponownie."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Użyj odcisku innego palca"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zbyt jasno"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Wykryto naciśnięcie przycisku zasilania"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Popraw"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Za każdym razem lekko zmieniaj ułożenie palca"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Twarz rozpoznana, kliknij Potwierdź"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Czytnik linii papilarnych nie jest dostępny."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nie można skonfigurować odcisku palca"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Osiągnięto limit czasu odczytu odcisków palców. Spróbuj ponownie."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Upłynął limit czasu konfiguracji odcisku palca. Spróbuj ponownie."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Odczyt odcisku palca został anulowany."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Odczyt odcisku palca został anulowany przez użytkownika."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Zbyt wiele prób. Spróbuj ponownie później."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Zbyt wiele prób. Użyj blokady ekranu."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Zbyt wiele prób. Użyj blokady ekranu."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Spróbuj ponownie."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nie udało się przetworzyć odcisku palca. Spróbuj ponownie."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nie zarejestrowano odcisków palców."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Odwiedź serwis."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Nie można utworzyć modelu twarzy. Spróbuj ponownie."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Zbyt jasno. Spróbuj przy słabszym świetle."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Za mało światła"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Odsuń telefon"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Przybliż telefon"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Przesuń telefon wyżej"</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Uruchamianie aplikacji."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Kończenie uruchamiania."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Naciśnięto przycisk zasilania — zwykle powoduje to wyłączenie ekranu.\n\nKlikaj delikatnie podczas konfigurowania odcisku palca."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Kliknij, aby wyłączyć ekran"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Wyłącz ekran"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Aby zakończyć konfigurację, wyłącz ekran"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Wyłącz"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Kontynuować weryfikację odcisku palca?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Naciśnięto przycisk zasilania — zwykle powoduje to wyłączenie ekranu.\n\nKliknij delikatnie, aby zweryfikować odcisk palca."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Wyłącz ekran"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Telewizor"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Głośniki stacji dokującej"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Urządzenie zewnętrzne"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Słuchawki"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 7d5721a..55f5bcf 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Insira seu bloqueio de tela para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pressione o sensor com firmeza"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Não foi possível reconhecer a impressão digital. Tente de novo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressão digital e tente novamente"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pressione o sensor com firmeza"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"O movimento do dedo está muito lento. Tente novamente."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"O botão liga/desliga foi pressionado"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ajuste a posição do dedo"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mude a posição do dedo ligeiramente a cada momento"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não foi possível configurar a impressão digital"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"A configuração da impressão digital expirou. Tente de novo."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo usuário."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Excesso de tentativas. Tente novamente mais tarde."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Excesso de tentativas. Use o bloqueio de tela."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Excesso de tentativas. Use o bloqueio de tela."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Tente novamente."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Não foi possível processar a impressão digital. Tente de novo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Entre em contato com uma assistência técnica."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Falha ao criar o modelo de rosto. Tente de novo."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Muito iluminado. Diminua a iluminação."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Não há luz suficiente"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Afaste o smartphone"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Aproxime o smartphone do seu rosto"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Mova o smartphone para cima"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Concluindo a inicialização."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Você pressionou o botão liga/desliga. Normalmente, essa ação desliga a tela.\n\nToque levemente na tela durante a configuração da impressão digital."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Toque para desligar a tela"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Desligar a tela"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Desligue a tela para encerrar a configuração"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Desativar"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continuar a verificação da digital?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Você pressionou o botão liga/desliga. Normalmente, essa ação desliga a tela.\n\nToque levemente na tela para verificar sua impressão digital."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Desligar a tela"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefone"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Alto-falantes na base"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispositivo externo"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Fones de ouvido"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 1fe0db7a..2938b96 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -53,7 +53,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID do Autor da Chamada"</string>
-    <string name="ClirMmi" msgid="6752346475055446417">"Ocultar identificação do autor da chamada efetuada"</string>
+    <string name="ClirMmi" msgid="6752346475055446417">"Ocultar identificação do autor da chamada feita"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID de linha ligada"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Restrição de ID de linha ligada"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Encaminhamento de chamadas"</string>
@@ -350,7 +350,7 @@
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar atalhos"</string>
     <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permite que a app remova atalhos do Ecrã principal sem a intervenção do utilizador."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"redirecionar as chamadas efetuadas"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Permite que a app veja o número que é marcado durante uma chamada efetuada, com a opção de redirecionar a chamada para um número diferente ou terminar a chamada."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Permite que a app veja o número que é marcado durante uma chamada feita, com a opção de redirecionar a chamada para um número diferente ou terminar a chamada."</string>
     <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"atender chamadas telefónicas"</string>
     <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Permite que a app atenda chamadas recebidas."</string>
     <string name="permlab_receiveSms" msgid="505961632050451881">"receber mensagens de texto (SMS)"</string>
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utilizar o bloqueio de ecrã"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introduza o bloqueio de ecrã para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Prima firmemente o sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Não é possível reconhecer a impressão digital. Tente novamente."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressões digitais e tente novamente"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Prima firmemente o sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Moveu o dedo demasiado lentamente. Tente novamente."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Experimente outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Está demasiado claro"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Detetou-se que o botão ligar/desligar foi premido"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Experimente ajustar"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Altere a posição do seu dedo ligeiramente de cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado. Prima Confirmar."</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não é possível configurar a impressão digital"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Foi atingido o limite de tempo da impressão digital. Tente novamente."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"A configuração da impressão digital expirou. Tente novamente."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo utilizador."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Demasiadas tentativas. Tente novamente mais tarde."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Demasiadas tentativas. Em alternativa, use o bloqueio de ecrã."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Demasiadas tentativas. Em alternativa, use o bloqueio de ecrã."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Tente novamente."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Não é possível processar a impressão digital. Tente novamente."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visite um fornecedor de serviços de reparação."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Impossível criar modelo de rosto. Tente novamente."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Demasiado clara. Experimente uma luz mais suave."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Não há luz suficiente"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Afaste ainda mais o telemóvel"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Aproxime o telemóvel do rosto"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Mova o telemóvel mais para cima"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"A iniciar aplicações"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"A concluir o arranque."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Premiu o botão ligar/desligar. Geralmente, esta ação desliga o ecrã.\n\nExperimente tocar levemente ao configurar a sua impressão digital."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Toque para desligar o ecrã"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Desligar ecrã"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Termine a configuração ao desligar ecrã"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Desativar"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continuar a validar a impressão digital?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Premiu o botão ligar/desligar. Geralmente, esta ação desliga o ecrã.\n\nExperimente tocar levemente para validar a sua impressão digital."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Desligar ecrã"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telemóvel"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Altif. estação ancoragem"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispositivo externo"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Auscultadores"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 7d5721a..55f5bcf 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Insira seu bloqueio de tela para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pressione o sensor com firmeza"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Não foi possível reconhecer a impressão digital. Tente de novo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressão digital e tente novamente"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pressione o sensor com firmeza"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"O movimento do dedo está muito lento. Tente novamente."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"O botão liga/desliga foi pressionado"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ajuste a posição do dedo"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mude a posição do dedo ligeiramente a cada momento"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não foi possível configurar a impressão digital"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"A configuração da impressão digital expirou. Tente de novo."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo usuário."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Excesso de tentativas. Tente novamente mais tarde."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Excesso de tentativas. Use o bloqueio de tela."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Excesso de tentativas. Use o bloqueio de tela."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Tente novamente."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Não foi possível processar a impressão digital. Tente de novo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Entre em contato com uma assistência técnica."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Falha ao criar o modelo de rosto. Tente de novo."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Muito iluminado. Diminua a iluminação."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Não há luz suficiente"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Afaste o smartphone"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Aproxime o smartphone do seu rosto"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Mova o smartphone para cima"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Concluindo a inicialização."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Você pressionou o botão liga/desliga. Normalmente, essa ação desliga a tela.\n\nToque levemente na tela durante a configuração da impressão digital."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Toque para desligar a tela"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Desligar a tela"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Desligue a tela para encerrar a configuração"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Desativar"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continuar a verificação da digital?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Você pressionou o botão liga/desliga. Normalmente, essa ação desliga a tela.\n\nToque levemente na tela para verificar sua impressão digital."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Desligar a tela"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefone"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Alto-falantes na base"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispositivo externo"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Fones de ouvido"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistema"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 27b04d6..7c34345 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -40,10 +40,10 @@
     <string name="badPin" msgid="888372071306274355">"Codul PIN vechi introdus nu este corect."</string>
     <string name="badPuk" msgid="4232069163733147376">"Codul PUK introdus nu este corect."</string>
     <string name="mismatchPin" msgid="2929611853228707473">"Codurile PIN introduse nu se potrivesc."</string>
-    <string name="invalidPin" msgid="7542498253319440408">"Introduceți un cod PIN alcătuit din 4 până la 8 cifre."</string>
-    <string name="invalidPuk" msgid="8831151490931907083">"Introduceți un cod PUK care să aibă 8 cifre sau mai mult."</string>
-    <string name="needPuk" msgid="7321876090152422918">"Cardul SIM este blocat cu codul PUK. Introduceți codul PUK pentru a-l debloca."</string>
-    <string name="needPuk2" msgid="7032612093451537186">"Introduceți codul PUK2 pentru a debloca cardul SIM."</string>
+    <string name="invalidPin" msgid="7542498253319440408">"Introdu un cod PIN alcătuit din 4 până la 8 cifre."</string>
+    <string name="invalidPuk" msgid="8831151490931907083">"Introdu un cod PUK care să aibă 8 cifre sau mai mult."</string>
+    <string name="needPuk" msgid="7321876090152422918">"Cardul SIM este blocat cu codul PUK. Introdu codul PUK pentru a-l debloca."</string>
+    <string name="needPuk2" msgid="7032612093451537186">"Introdu codul PUK2 pentru a debloca cardul SIM."</string>
     <string name="enablePin" msgid="2543771964137091212">"Operațiunea nu a reușit. Activați blocarea cardului SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="few">V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> încercări până la blocarea cardului SIM.</item>
@@ -53,7 +53,7 @@
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
     <string name="ClipMmi" msgid="4110549342447630629">"ID apelant de primire"</string>
-    <string name="ClirMmi" msgid="6752346475055446417">"Ascundeți ID-ul apelantului"</string>
+    <string name="ClirMmi" msgid="6752346475055446417">"Ascunde ID-ul apelantului"</string>
     <string name="ColpMmi" msgid="4736462893284419302">"ID-ul liniei conectate"</string>
     <string name="ColrMmi" msgid="5889782479745764278">"Restricționarea ID-ului liniei conectate"</string>
     <string name="CfMmi" msgid="8390012691099787178">"Redirecționarea apelurilor"</string>
@@ -159,7 +159,7 @@
     <string name="httpErrorAuth" msgid="469553140922938968">"Nu s-a realizat autentificarea."</string>
     <string name="httpErrorProxyAuth" msgid="7229662162030113406">"Autentificarea prin intermediul serverului proxy nu a reușit."</string>
     <string name="httpErrorConnect" msgid="3295081579893205617">"Nu s-a putut stabili conexiunea cu serverul."</string>
-    <string name="httpErrorIO" msgid="3860318696166314490">"Nu s-a putut efectua comunicarea cu serverul. Încercați din nou mai târziu."</string>
+    <string name="httpErrorIO" msgid="3860318696166314490">"Nu s-a putut efectua comunicarea cu serverul. Încearcă din nou mai târziu."</string>
     <string name="httpErrorTimeout" msgid="7446272815190334204">"Conexiunea la server a expirat."</string>
     <string name="httpErrorRedirectLoop" msgid="8455757777509512098">"Pagina conține prea multe redirecționări de server."</string>
     <string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"Protocolul nu este acceptat."</string>
@@ -167,15 +167,15 @@
     <string name="httpErrorBadUrl" msgid="754447723314832538">"Pagina nu a putut fi deschisă, deoarece adresa URL nu este validă."</string>
     <string name="httpErrorFile" msgid="3400658466057744084">"Fișierul nu a putut fi accesat."</string>
     <string name="httpErrorFileNotFound" msgid="5191433324871147386">"Nu s-a putut găsi fișierul solicitat."</string>
-    <string name="httpErrorTooManyRequests" msgid="2149677715552037198">"Există prea multe solicitări în curs de procesare. Încercați din nou mai târziu."</string>
+    <string name="httpErrorTooManyRequests" msgid="2149677715552037198">"Există prea multe solicitări în curs de procesare. Încearcă din nou mai târziu."</string>
     <string name="notification_title" msgid="5783748077084481121">"Eroare de conectare pentru <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
     <string name="contentServiceSync" msgid="2341041749565687871">"Sincronizare"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"Nu se poate sincroniza"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"Ați încercat să ștergeți prea multe <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
-    <string name="low_memory" product="tablet" msgid="5557552311566179924">"Stocarea pe tabletă este plină. Ștergeți câteva fișiere pentru a elibera spațiu."</string>
-    <string name="low_memory" product="watch" msgid="3479447988234030194">"Spațiul de stocare de pe ceas este plin! Ștergeți câteva fișiere pentru a elibera spațiu."</string>
-    <string name="low_memory" product="tv" msgid="6663680413790323318">"Spațiul de stocare de pe dispozitivul Android TV este plin. Ștergeți câteva fișiere pentru a elibera spațiu."</string>
-    <string name="low_memory" product="default" msgid="2539532364144025569">"Stocarea pe telefon este plină. Ștergeți câteva fișiere pentru a elibera spațiu."</string>
+    <string name="low_memory" product="tablet" msgid="5557552311566179924">"Stocarea pe tabletă este plină. Șterge câteva fișiere pentru a elibera spațiu."</string>
+    <string name="low_memory" product="watch" msgid="3479447988234030194">"Spațiul de stocare de pe ceas este plin! Șterge câteva fișiere pentru a elibera spațiu."</string>
+    <string name="low_memory" product="tv" msgid="6663680413790323318">"Spațiul de stocare de pe dispozitivul Android TV este plin. Șterge câteva fișiere pentru a elibera spațiu."</string>
+    <string name="low_memory" product="default" msgid="2539532364144025569">"Stocarea pe telefon este plină. Șterge câteva fișiere pentru a elibera spațiu."</string>
     <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{S-a instalat o autoritate de certificare}few{S-au instalat autorități de certificare}other{S-au instalat autorități de certificare}}"</string>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"De o terță parte necunoscută"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"De administratorul profilului dvs. de serviciu"</string>
@@ -213,7 +213,7 @@
     <string name="turn_on_radio" msgid="2961717788170634233">"Activați funcția wireless"</string>
     <string name="turn_off_radio" msgid="7222573978109933360">"Dezactivați funcția wireless"</string>
     <string name="screen_lock" msgid="2072642720826409809">"Blocați ecranul"</string>
-    <string name="power_off" msgid="4111692782492232778">"Opriți"</string>
+    <string name="power_off" msgid="4111692782492232778">"Oprește"</string>
     <string name="silent_mode_silent" msgid="5079789070221150912">"Sonerie dezactivată"</string>
     <string name="silent_mode_vibrate" msgid="8821830448369552678">"Vibrare sonerie"</string>
     <string name="silent_mode_ring" msgid="6039011004781526678">"Sonerie activată"</string>
@@ -229,7 +229,7 @@
     <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"Ceasul dvs. se va închide."</string>
     <string name="shutdown_confirm" product="default" msgid="136816458966692315">"Telefonul dvs. se va închide."</string>
     <string name="shutdown_confirm_question" msgid="796151167261608447">"Doriți să închideți?"</string>
-    <string name="reboot_safemode_title" msgid="5853949122655346734">"Reporniți în modul sigur"</string>
+    <string name="reboot_safemode_title" msgid="5853949122655346734">"Repornește în modul sigur"</string>
     <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Doriți să reporniți în modul sigur? Astfel vor fi dezactivate toate aplicațiile terță parte pe care le-ați instalat. Acestea vor fi restabilite când reporniți din nou."</string>
     <string name="recent_tasks_title" msgid="8183172372995396653">"Recente"</string>
     <string name="no_recent_tasks" msgid="9063946524312275906">"Nu există aplicații recente."</string>
@@ -237,9 +237,9 @@
     <string name="global_actions" product="tv" msgid="3871763739487450369">"Opțiuni pentru Android TV"</string>
     <string name="global_actions" product="default" msgid="6410072189971495460">"Opțiuni telefon"</string>
     <string name="global_action_lock" msgid="6949357274257655383">"Blocați ecranul"</string>
-    <string name="global_action_power_off" msgid="4404936470711393203">"Opriți"</string>
+    <string name="global_action_power_off" msgid="4404936470711393203">"Oprește"</string>
     <string name="global_action_power_options" msgid="1185286119330160073">"Alimentare"</string>
-    <string name="global_action_restart" msgid="4678451019561687074">"Reporniți"</string>
+    <string name="global_action_restart" msgid="4678451019561687074">"Repornește"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"Urgență"</string>
     <string name="global_action_bug_report" msgid="5127867163044170003">"Raport despre erori"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"Încheiați sesiunea"</string>
@@ -287,7 +287,7 @@
     <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Folosirea accesibilității"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> folosește bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicații folosesc bateria"</string>
-    <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
+    <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Atinge pentru mai multe detalii privind bateria și utilizarea datelor"</string>
     <string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="8974401416068943888">"Mod sigur"</string>
     <string name="android_system_label" msgid="5974767339591067210">"Sistemul Android"</string>
@@ -455,9 +455,9 @@
     <string name="permdesc_camera" msgid="5240801376168647151">"Această aplicație poate să fotografieze și să înregistreze videoclipuri folosind camera foto când este în uz."</string>
     <string name="permlab_backgroundCamera" msgid="7549917926079731681">"să fotografieze și să înregistreze videoclipuri în fundal"</string>
     <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Această aplicație poate să fotografieze și să înregistreze videoclipuri folosind camera foto oricând."</string>
-    <string name="permlab_systemCamera" msgid="3642917457796210580">"Permiteți unei aplicații sau unui serviciu accesul la camerele de sistem, ca să fotografieze și să înregistreze videoclipuri"</string>
+    <string name="permlab_systemCamera" msgid="3642917457796210580">"Permite unei aplicații sau unui serviciu accesul la camerele de sistem, ca să fotografieze și să înregistreze videoclipuri"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"Această aplicație de sistem privilegiată poate să fotografieze și să înregistreze videoclipuri folosind o cameră de sistem în orice moment. Necesită și permisiunea android.permission.CAMERA pentru aplicație"</string>
-    <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Permiteți unei aplicații sau unui serviciu să primească apeluri inverse atunci când sunt deschise sau închise dispozitive cu cameră."</string>
+    <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Permite unei aplicații sau unui serviciu să primească apeluri inverse atunci când sunt deschise sau închise dispozitive cu cameră."</string>
     <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Această aplicație poate primi apeluri inverse atunci când este deschis (de aplicație) sau închis orice dispozitiv cu cameră."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlează vibrarea"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite aplicației să controleze mecanismul de vibrare."</string>
@@ -471,7 +471,7 @@
     <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"să citească informații de bază, precum activitatea și starea telefonului"</string>
     <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Permite ca aplicația să acceseze funcțiile de telefonie de bază ale dispozitivului."</string>
     <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"să direcționeze apelurile prin intermediul sistemului"</string>
-    <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Permiteți aplicației să direcționeze apelurile prin intermediul sistemului pentru a îmbunătăți calitatea apelurilor."</string>
+    <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Permite aplicației să direcționeze apelurile prin intermediul sistemului pentru a îmbunătăți calitatea apelurilor."</string>
     <string name="permlab_callCompanionApp" msgid="3654373653014126884">"Vedeți și controlați apelurile prin intermediul sistemului."</string>
     <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Permite aplicației să vadă și să controleze apelurile în desfășurare pe dispozitiv. Aceasta include informații ca numerele pentru apeluri și starea apelurilor."</string>
     <string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"scutită de restricțiile pentru înregistrarea conținutului audio"</string>
@@ -541,7 +541,7 @@
     <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"să transmită anunțuri pe dispozitive Bluetooth din apropiere"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite aplicației să difuzeze anunțuri pe dispozitive Bluetooth din apropiere"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
-    <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permiteți-i aplicației să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
+    <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite-i aplicației să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"să interacționeze cu dispozitive Wi‑Fi din apropiere"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite aplicației să se conecteze la dispozitive Wi-Fi din apropiere, să transmită anunțuri și să stabilească poziția relativă a acestora"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informații despre serviciul de plăți NFC preferat"</string>
@@ -583,14 +583,15 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"Eroare la autentificare"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Folosiți blocarea ecranului"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introduceți blocarea ecranului ca să continuați"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Apăsați ferm pe senzor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Amprenta nu a putut fi procesată. Încercați din nou."</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Apasă ferm pe senzor"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Amprenta nu a fost recunoscută. Încearcă din nou."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Curățați senzorul de amprentă și încercați din nou"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Curățați senzorul și încercați din nou"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Apăsați ferm pe senzor"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Apasă ferm pe senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Ați mișcat degetul prea lent. Încercați din nou."</string>
-    <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Încercați altă amprentă"</string>
+    <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Încearcă altă amprentă"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Prea luminos"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"S-a detectat apăsarea butonului de alimentare"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Încercați să ajustați"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Schimbați ușor poziția degetului de fiecare dată"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Chip autentificat, apăsați Confirmați"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware-ul pentru amprentă nu este disponibil."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nu se poate configura amprenta"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Timpul pentru amprentare a expirat. Încercați din nou."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Configurarea amprentei a expirat. Încearcă din nou."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operațiunea privind amprenta a fost anulată."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operațiunea privind amprenta a fost anulată de utilizator."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Prea multe încercări. Încercați din nou mai târziu."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Prea multe încercări. Folosește blocarea ecranului."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Prea multe încercări. Folosește blocarea ecranului."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Încercați din nou."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Nu putem procesa amprenta. Încearcă din nou."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nu au fost înregistrate amprente."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
@@ -620,34 +621,33 @@
     <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Folosiți amprenta sau blocarea ecranului pentru a continua"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
-    <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"A apărut o eroare. Încercați din nou."</string>
+    <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"A apărut o eroare. Încearcă din nou."</string>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pictograma amprentă"</string>
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Deblocare facială"</string>
     <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problemă cu Deblocarea facială"</string>
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Atingeți pentru a șterge modelul facial, apoi adăugați din nou fața"</string>
-    <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurați Deblocarea facială"</string>
+    <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurează Deblocarea facială"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Deblocați-vă telefonul uitându-vă la acesta"</string>
     <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Pentru a folosi Deblocarea facială, activați "<b>"Accesul la cameră"</b>" în Setări și confidențialitate"</string>
-    <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurați mai multe moduri de deblocare"</string>
+    <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurează mai multe moduri de deblocare"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Atingeți ca să adăugați o amprentă"</string>
     <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Deblocare cu amprenta"</string>
     <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Nu se poate folosi senzorul de amprentă"</string>
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Vizitați un furnizor de servicii de reparații."</string>
-    <string name="face_acquired_insufficient" msgid="6889245852748492218">"Nu se poate crea modelul facial. Reîncercați."</string>
-    <string name="face_acquired_too_bright" msgid="8070756048978079164">"Prea luminos. Încercați o lumină mai slabă."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
-    <string name="face_acquired_too_close" msgid="4453646176196302462">"Mutați telefonul mai departe"</string>
-    <string name="face_acquired_too_far" msgid="2922278214231064859">"Mutați telefonul mai aproape"</string>
-    <string name="face_acquired_too_high" msgid="8278815780046368576">"Mutați telefonul mai sus"</string>
-    <string name="face_acquired_too_low" msgid="4075391872960840081">"Mutați telefonul mai jos"</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"Mutați telefonul spre stânga"</string>
-    <string name="face_acquired_too_left" msgid="9201762240918405486">"Mutați telefonul spre dreapta"</string>
+    <string name="face_acquired_insufficient" msgid="6889245852748492218">"Nu se poate crea modelul facial. Reîncearcă."</string>
+    <string name="face_acquired_too_bright" msgid="8070756048978079164">"Prea luminos. Încearcă o lumină mai slabă."</string>
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Lumină insuficientă"</string>
+    <string name="face_acquired_too_close" msgid="4453646176196302462">"Mută telefonul mai departe"</string>
+    <string name="face_acquired_too_far" msgid="2922278214231064859">"Mută telefonul mai aproape"</string>
+    <string name="face_acquired_too_high" msgid="8278815780046368576">"Mută telefonul mai sus"</string>
+    <string name="face_acquired_too_low" msgid="4075391872960840081">"Mută telefonul mai jos"</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"Mută telefonul spre stânga"</string>
+    <string name="face_acquired_too_left" msgid="9201762240918405486">"Mută telefonul spre dreapta"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Priviți mai direct spre dispozitiv."</string>
     <string name="face_acquired_not_detected" msgid="1057966913397548150">"Nu vi se vede fața. Țineți telefonul la nivelul ochilor."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Prea multă mișcare. Țineți telefonul nemișcat."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Reînregistrați-vă chipul."</string>
-    <string name="face_acquired_too_different" msgid="2520389515612972889">"Chipul nu a fost recunoscut. Reîncercați."</string>
+    <string name="face_acquired_too_different" msgid="2520389515612972889">"Chipul nu a fost recunoscut. Reîncearcă."</string>
     <string name="face_acquired_too_similar" msgid="8882920552674125694">"Schimbați ușor poziția capului"</string>
     <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Priviți direct spre telefon"</string>
     <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Priviți direct spre telefon"</string>
@@ -658,20 +658,20 @@
     <skip />
     <!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
     <skip />
-    <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Nu se poate crea modelul facial. Reîncercați."</string>
+    <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Nu se poate crea modelul facial. Reîncearcă."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"S-au detectat ochelari de culoare închisă. Chipul trebuie să fie vizibil în totalitate."</string>
     <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"S-a detectat un articol care acoperă chipul. Chipul trebuie să fie vizibil în totalitate."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"Nu se poate confirma fața. Hardware-ul nu este disponibil."</string>
-    <string name="face_error_timeout" msgid="2598544068593889762">"Încercați din nou Deblocarea facială"</string>
-    <string name="face_error_no_space" msgid="5649264057026021723">"Nu se pot stoca date faciale noi. Ștergeți întâi unele vechi."</string>
+    <string name="face_error_timeout" msgid="2598544068593889762">"Încearcă din nou Deblocarea facială"</string>
+    <string name="face_error_no_space" msgid="5649264057026021723">"Nu se pot stoca date faciale noi. Șterge întâi unele vechi."</string>
     <string name="face_error_canceled" msgid="2164434737103802131">"Operațiunea privind chipul a fost anulată."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Deblocarea facială a fost anulată de utilizator"</string>
-    <string name="face_error_lockout" msgid="7864408714994529437">"Prea multe încercări. Reîncercați mai târziu."</string>
+    <string name="face_error_lockout" msgid="7864408714994529437">"Prea multe încercări. Reîncearcă mai târziu."</string>
     <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Prea multe încercări. Deblocarea facială este dezactivată."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Prea multe încercări. Folosiți blocarea ecranului."</string>
-    <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nu se poate confirma fața. Încercați din nou."</string>
+    <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nu se poate confirma fața. Încearcă din nou."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Nu ați configurat Deblocarea facială"</string>
     <string name="face_error_hw_not_present" msgid="7940978724978763011">"Deblocarea facială nu este acceptată pe acest dispozitiv"</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"Senzorul este dezactivat temporar."</string>
@@ -682,7 +682,7 @@
     <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Folosiți-vă chipul sau blocarea ecranului pentru a continua"</string>
   <string-array name="face_error_vendor">
   </string-array>
-    <string name="face_error_vendor_unknown" msgid="7387005932083302070">"A apărut o eroare. Încercați din nou."</string>
+    <string name="face_error_vendor_unknown" msgid="7387005932083302070">"A apărut o eroare. Încearcă din nou."</string>
     <string name="face_icon_content_description" msgid="465030547475916280">"Pictograma chip"</string>
     <string name="permlab_readSyncSettings" msgid="6250532864893156277">"citire setări sincronizare"</string>
     <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Permite aplicației să citească setările de sincronizare ale unui cont. De exemplu, cu această permisiune aplicația poate determina dacă aplicația Persoane este sincronizată cu un anumit cont."</string>
@@ -770,16 +770,16 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"Să blocheze ecranul"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Stabiliți modul și timpul în care se blochează ecranul."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Să șteargă toate datele"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Ștergeți datele de pe tabletă fără avertisment, efectuând resetarea configurării din fabrică."</string>
-    <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Ștergeți datele de pe dispozitivul Android TV fără avertisment, efectuând o revenire la setările din fabrică."</string>
-    <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Ștergeți datele din sistemul de infotainment fără avertisment, prin revenirea la setările din fabrică."</string>
-    <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Ștergeți datele din telefon fără avertisment, efectuând resetarea configurării din fabrică."</string>
-    <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Ștergeți datele de profil"</string>
-    <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Ștergeți datele utilizatorului"</string>
-    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Ștergeți datele acestui utilizator de pe această tabletă fără avertisment."</string>
-    <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Ștergeți datele acestui utilizator de pe acest dispozitiv Android TV fără avertisment"</string>
-    <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Ștergeți datele profilului din acest sistem de infotainment fără avertisment."</string>
-    <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Ștergeți datele acestui utilizator de pe acest telefon fără avertisment."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Șterge datele de pe tabletă fără avertisment, efectuând resetarea configurării din fabrică."</string>
+    <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Șterge datele de pe dispozitivul Android TV fără avertisment, efectuând o revenire la setările din fabrică."</string>
+    <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Șterge datele din sistemul de infotainment fără avertisment, prin revenirea la setările din fabrică."</string>
+    <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Șterge datele din telefon fără avertisment, efectuând resetarea configurării din fabrică."</string>
+    <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Șterge datele de profil"</string>
+    <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Șterge datele utilizatorului"</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Șterge datele acestui utilizator de pe această tabletă fără avertisment."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Șterge datele acestui utilizator de pe acest dispozitiv Android TV fără avertisment"</string>
+    <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Șterge datele profilului din acest sistem de infotainment fără avertisment."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Șterge datele acestui utilizator de pe acest telefon fără avertisment."</string>
     <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Setați serverul proxy global pentru dispozitiv"</string>
     <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Setați serverul proxy global pentru dispozitiv, care să fie utilizat cât timp politica este activă. Numai proprietarul dispozitivului poate seta serverul proxy global."</string>
     <string name="policylab_expirePassword" msgid="6015404400532459169">"Setați expirarea parolei pentru blocarea ecranului"</string>
@@ -904,41 +904,41 @@
     <string name="sipAddressTypeWork" msgid="7873967986701216770">"Serviciu"</string>
     <string name="sipAddressTypeOther" msgid="6317012577345187275">"Altul"</string>
     <string name="quick_contacts_not_available" msgid="1262709196045052223">"Nu s-a găsit nicio aplicație pentru a afișa această persoană de contact."</string>
-    <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Introduceți codul PIN"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"Introduceți codul PUK și noul cod PIN"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Introdu codul PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"Introdu codul PUK și noul cod PIN"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"Codul PUK"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"Noul cod PIN"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"Atingeți ca să introduceți parola"</font></string>
-    <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Introduceți parola pentru a debloca"</string>
-    <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Introduceți codul PIN pentru a debloca"</string>
+    <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Introdu parola pentru a debloca"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Introdu codul PIN pentru a debloca"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"Cod PIN incorect."</string>
     <string name="keyguard_label_text" msgid="3841953694564168384">"Pentru a debloca, apăsați Meniu, apoi 0."</string>
     <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Număr de urgență"</string>
     <string name="lockscreen_carrier_default" msgid="6192313772955399160">"Fără semnal"</string>
     <string name="lockscreen_screen_locked" msgid="7364905540516041817">"Ecranul este blocat."</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Apăsați Meniu pentru a debloca sau pentru a efectua apeluri de urgență."</string>
-    <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Apăsați Meniu pentru deblocare."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Apasă Meniu pentru a debloca sau pentru a efectua apeluri de urgență."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Apasă Meniu pentru deblocare."</string>
     <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Desenați modelul pentru a debloca"</string>
     <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Urgență"</string>
     <string name="lockscreen_return_to_call" msgid="3156883574692006382">"Reveniți la apel"</string>
     <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Corect!"</string>
-    <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Încercați din nou"</string>
-    <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Încercați din nou"</string>
+    <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Încearcă din nou"</string>
+    <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Încearcă din nou"</string>
     <string name="lockscreen_storage_locked" msgid="634993789186443380">"Deblocați pentru toate funcțiile și datele"</string>
     <string name="faceunlock_multiple_failures" msgid="681991538434031708">"S-a depășit numărul maxim de încercări pentru Deblocare facială"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"Fără SIM"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"Nu există card SIM în computerul tablet PC."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="2582768023352171073">"Nu există un card SIM în dispozitivul Android TV."</string>
     <string name="lockscreen_missing_sim_message" product="default" msgid="1408695081255172556">"Telefonul nu are card SIM."</string>
-    <string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"Introduceți un card SIM."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"Cardul SIM lipsește sau nu poate fi citit. Introduceți un card SIM."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="8473601862688263903">"Introdu un card SIM."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"Cardul SIM lipsește sau nu poate fi citit. Introdu un card SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="3812893366715730539">"Card SIM inutilizabil."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="4358929052509450807">"Cardul dvs. SIM este dezactivat definitiv.\n Contactați furnizorul de servicii wireless pentru a obține un alt card SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"Melodia anterioară"</string>
     <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Melodia următoare"</string>
     <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pauză"</string>
     <string name="lockscreen_transport_play_description" msgid="106868788691652733">"Redați"</string>
-    <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Opriți"</string>
+    <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Oprește"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Derulați"</string>
     <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Derulați rapid înainte"</string>
     <string name="emergency_calls_only" msgid="3057351206678279851">"Numai apeluri de urgență"</string>
@@ -959,7 +959,7 @@
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a dispozitivului Android TV. Acesta va reveni la setările din fabrică."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Acesta va fi acum resetat la setările prestabilite din fabrică."</string>
-    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Încercați din nou peste <xliff:g id="NUMBER">%d</xliff:g>   secunde."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Încearcă din nou peste <xliff:g id="NUMBER">%d</xliff:g>   secunde."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Ați uitat modelul?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Deblocare cont"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Prea multe încercări de desenare a modelului"</string>
@@ -980,7 +980,7 @@
     <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"Modelul a fost desenat"</string>
     <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"Zonă model."</string>
     <string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s. Widget %2$d din %3$d."</string>
-    <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"Adăugați un widget."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"Adaugă un widget."</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"Gol"</string>
     <string name="keyguard_accessibility_unlock_area_expanded" msgid="7768634718706488951">"Zona de deblocare a fost extinsă."</string>
     <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"Zona de deblocare a fost restrânsă."</string>
@@ -992,7 +992,7 @@
     <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"A început reordonarea widgeturilor."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Reordonarea widgeturilor s-a încheiat."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Widgetul <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> a fost eliminat."</string>
-    <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Extindeți zona de deblocare."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Extinde zona de deblocare."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Deblocare prin glisare."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Deblocare cu model."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Deblocare facială."</string>
@@ -1012,7 +1012,7 @@
     <string name="factorytest_failed" msgid="3190979160945298006">"Testarea de fabrică nu a reușit"</string>
     <string name="factorytest_not_system" msgid="5658160199925519869">"Acțiunea FACTORY_TEST este acceptată doar pentru pachetele instalate în /system/app."</string>
     <string name="factorytest_no_action" msgid="339252838115675515">"Nu s-a găsit niciun pachet care să ofere acțiunea FACTORY_TEST."</string>
-    <string name="factorytest_reboot" msgid="2050147445567257365">"Reporniți"</string>
+    <string name="factorytest_reboot" msgid="2050147445567257365">"Repornește"</string>
     <string name="js_dialog_title" msgid="7464775045615023241">"La pagina de la „<xliff:g id="TITLE">%s</xliff:g>” apare:"</string>
     <string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
     <string name="js_dialog_before_unload_title" msgid="7012587995876771246">"Confirmați părăsirea paginii"</string>
@@ -1074,12 +1074,12 @@
     <string name="menu_space_shortcut_label" msgid="5949311515646872071">"spațiu"</string>
     <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
     <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"delete"</string>
-    <string name="search_go" msgid="2141477624421347086">"Căutați"</string>
-    <string name="search_hint" msgid="455364685740251925">"Căutați…"</string>
-    <string name="searchview_description_search" msgid="1045552007537359343">"Căutați"</string>
+    <string name="search_go" msgid="2141477624421347086">"Caută"</string>
+    <string name="search_hint" msgid="455364685740251925">"Caută…"</string>
+    <string name="searchview_description_search" msgid="1045552007537359343">"Caută"</string>
     <string name="searchview_description_query" msgid="7430242366971716338">"Interogare de căutare"</string>
-    <string name="searchview_description_clear" msgid="1989371719192982900">"Ștergeți interogarea"</string>
-    <string name="searchview_description_submit" msgid="6771060386117334686">"Trimiteți interogarea"</string>
+    <string name="searchview_description_clear" msgid="1989371719192982900">"Șterge interogarea"</string>
+    <string name="searchview_description_submit" msgid="6771060386117334686">"Trimite interogarea"</string>
     <string name="searchview_description_voice" msgid="42360159504884679">"Căutare vocală"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Activați Explorați prin atingere?"</string>
     <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> dorește să activeze funcția Explorați prin atingere. Când această funcție este activată, puteți auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteți efectua gesturi pentru a interacționa cu tableta."</string>
@@ -1132,22 +1132,22 @@
     <string name="Midnight" msgid="8176019203622191377">"Miezul nopții"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="1532369154488982046">"Selectați-le pe toate"</string>
-    <string name="cut" msgid="2561199725874745819">"Decupați"</string>
-    <string name="copy" msgid="5472512047143665218">"Copiați"</string>
+    <string name="selectAll" msgid="1532369154488982046">"Selectează-le pe toate"</string>
+    <string name="cut" msgid="2561199725874745819">"Decupează"</string>
+    <string name="copy" msgid="5472512047143665218">"Copiază"</string>
     <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Eroare la copierea în clipboard"</string>
-    <string name="paste" msgid="461843306215520225">"Inserați"</string>
-    <string name="paste_as_plain_text" msgid="7664800665823182587">"Inserați ca text simplu"</string>
+    <string name="paste" msgid="461843306215520225">"Inserează"</string>
+    <string name="paste_as_plain_text" msgid="7664800665823182587">"Inserează ca text simplu"</string>
     <string name="replace" msgid="7842675434546657444">"Înlocuiți..."</string>
-    <string name="delete" msgid="1514113991712129054">"Ștergeți"</string>
-    <string name="copyUrl" msgid="6229645005987260230">"Copiați adresa URL"</string>
-    <string name="selectTextMode" msgid="3225108910999318778">"Selectați text"</string>
-    <string name="undo" msgid="3175318090002654673">"Anulați"</string>
+    <string name="delete" msgid="1514113991712129054">"Șterge"</string>
+    <string name="copyUrl" msgid="6229645005987260230">"Copiază adresa URL"</string>
+    <string name="selectTextMode" msgid="3225108910999318778">"Selectează text"</string>
+    <string name="undo" msgid="3175318090002654673">"Anulează"</string>
     <string name="redo" msgid="7231448494008532233">"Repetați"</string>
     <string name="autofill" msgid="511224882647795296">"Completare automată"</string>
     <string name="textSelectionCABTitle" msgid="5151441579532476940">"Selectare text"</string>
-    <string name="addToDictionary" msgid="8041821113480950096">"Adăugați în dicționar"</string>
-    <string name="deleteText" msgid="4200807474529938112">"Ștergeți"</string>
+    <string name="addToDictionary" msgid="8041821113480950096">"Adaugă în dicționar"</string>
+    <string name="deleteText" msgid="4200807474529938112">"Șterge"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Metodă de intrare"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Acțiuni pentru text"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Înapoi"</string>
@@ -1156,11 +1156,11 @@
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Este posibil ca unele funcții de sistem să nu funcționeze"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Spațiu de stocare insuficient pentru sistem. Asigurați-vă că aveți 250 MB de spațiu liber și reporniți."</string>
     <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> rulează acum"</string>
-    <string name="app_running_notification_text" msgid="5120815883400228566">"Atingeți pentru mai multe informații sau pentru a opri aplicația."</string>
+    <string name="app_running_notification_text" msgid="5120815883400228566">"Atinge pentru mai multe informații sau pentru a opri aplicația."</string>
     <string name="ok" msgid="2646370155170753815">"OK"</string>
-    <string name="cancel" msgid="6908697720451760115">"Anulați"</string>
+    <string name="cancel" msgid="6908697720451760115">"Anulează"</string>
     <string name="yes" msgid="9069828999585032361">"OK"</string>
-    <string name="no" msgid="5122037903299899715">"Anulați"</string>
+    <string name="no" msgid="5122037903299899715">"Anulează"</string>
     <string name="dialog_alert_title" msgid="651856561974090712">"Atenție"</string>
     <string name="loading" msgid="3138021523725055037">"Se încarcă…"</string>
     <string name="capital_on" msgid="2770685323900821829">"DA"</string>
@@ -1174,24 +1174,24 @@
     <string name="whichApplication" msgid="5432266899591255759">"Finalizare acțiune utilizând"</string>
     <string name="whichApplicationNamed" msgid="6969946041713975681">"Finalizați acțiunea utilizând %1$s"</string>
     <string name="whichApplicationLabel" msgid="7852182961472531728">"Finalizați acțiunea"</string>
-    <string name="whichViewApplication" msgid="5733194231473132945">"Deschideți cu"</string>
-    <string name="whichViewApplicationNamed" msgid="415164730629690105">"Deschideți cu %1$s"</string>
-    <string name="whichViewApplicationLabel" msgid="7367556735684742409">"Deschideți"</string>
-    <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Deschideți linkurile <xliff:g id="HOST">%1$s</xliff:g> cu"</string>
-    <string name="whichOpenLinksWith" msgid="1120936181362907258">"Deschideți linkurile cu"</string>
-    <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Deschideți linkurile cu <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
-    <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Deschideți linkurile <xliff:g id="HOST">%1$s</xliff:g> cu <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
-    <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Permiteți accesul"</string>
+    <string name="whichViewApplication" msgid="5733194231473132945">"Deschide cu"</string>
+    <string name="whichViewApplicationNamed" msgid="415164730629690105">"Deschide cu %1$s"</string>
+    <string name="whichViewApplicationLabel" msgid="7367556735684742409">"Deschide"</string>
+    <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"Deschide linkurile <xliff:g id="HOST">%1$s</xliff:g> cu"</string>
+    <string name="whichOpenLinksWith" msgid="1120936181362907258">"Deschide linkurile cu"</string>
+    <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"Deschide linkurile cu <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"Deschide linkurile <xliff:g id="HOST">%1$s</xliff:g> cu <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"Permite accesul"</string>
     <string name="whichEditApplication" msgid="6191568491456092812">"Editați cu"</string>
     <string name="whichEditApplicationNamed" msgid="8096494987978521514">"Editați cu %1$s"</string>
     <string name="whichEditApplicationLabel" msgid="1463288652070140285">"Editați"</string>
-    <string name="whichSendApplication" msgid="4143847974460792029">"Trimiteți"</string>
+    <string name="whichSendApplication" msgid="4143847974460792029">"Trimite"</string>
     <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Distribuiți cu %1$s"</string>
-    <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Trimiteți"</string>
-    <string name="whichSendToApplication" msgid="77101541959464018">"Trimiteți folosind"</string>
-    <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Trimiteți folosind %1$s"</string>
-    <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Trimiteți"</string>
-    <string name="whichHomeApplication" msgid="8276350727038396616">"Selectați o aplicație de pe ecranul de pornire"</string>
+    <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Trimite"</string>
+    <string name="whichSendToApplication" msgid="77101541959464018">"Trimite folosind"</string>
+    <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Trimite folosind %1$s"</string>
+    <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Trimite"</string>
+    <string name="whichHomeApplication" msgid="8276350727038396616">"Selectează o aplicație de pe ecranul de pornire"</string>
     <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"Utilizați %1$s ca ecran de pornire"</string>
     <string name="whichHomeApplicationLabel" msgid="8907334282202933959">"Fotografiați"</string>
     <string name="whichImageCaptureApplication" msgid="2737413019463215284">"Fotografiați cu"</string>
@@ -1199,20 +1199,20 @@
     <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Fotografiați"</string>
     <string name="alwaysUse" msgid="3153558199076112903">"Se utilizează în mod prestabilit pentru această acțiune."</string>
     <string name="use_a_different_app" msgid="4987790276170972776">"Utilizați altă aplicație"</string>
-    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Ștergeți setările prestabilite din Setări de sistem &gt; Aplicații &gt; Descărcate."</string>
-    <string name="chooseActivity" msgid="8563390197659779956">"Alegeți o acțiune"</string>
-    <string name="chooseUsbActivity" msgid="2096269989990986612">"Alegeți o aplicație pentru dispozitivul USB"</string>
+    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Șterge setările prestabilite din Setări de sistem &gt; Aplicații &gt; Descărcate."</string>
+    <string name="chooseActivity" msgid="8563390197659779956">"Alege o acțiune"</string>
+    <string name="chooseUsbActivity" msgid="2096269989990986612">"Alege o aplicație pentru dispozitivul USB"</string>
     <string name="noApplications" msgid="1186909265235544019">"Această acțiune nu poate fi efectuată de nicio aplicație."</string>
     <string name="aerr_application" msgid="4090916809370389109">"<xliff:g id="APPLICATION">%1$s</xliff:g> s-a oprit"</string>
     <string name="aerr_process" msgid="4268018696970966407">"<xliff:g id="PROCESS">%1$s</xliff:g> s-a oprit"</string>
     <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> se oprește încontinuu"</string>
     <string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> se oprește încontinuu"</string>
-    <string name="aerr_restart" msgid="2789618625210505419">"Deschideți din nou aplicația"</string>
-    <string name="aerr_report" msgid="3095644466849299308">"Trimiteți feedback"</string>
-    <string name="aerr_close" msgid="3398336821267021852">"Închideți"</string>
+    <string name="aerr_restart" msgid="2789618625210505419">"Deschide din nou aplicația"</string>
+    <string name="aerr_report" msgid="3095644466849299308">"Trimite feedback"</string>
+    <string name="aerr_close" msgid="3398336821267021852">"Închide"</string>
     <string name="aerr_mute" msgid="2304972923480211376">"Dezactivați până la repornirea dispozitivului"</string>
     <string name="aerr_wait" msgid="3198677780474548217">"Așteptați"</string>
-    <string name="aerr_close_app" msgid="8318883106083050970">"Închideți aplicația"</string>
+    <string name="aerr_close_app" msgid="8318883106083050970">"Închide aplicația"</string>
     <string name="anr_title" msgid="7290329487067300120"></string>
     <string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g> nu răspunde"</string>
     <string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nu răspunde"</string>
@@ -1226,13 +1226,13 @@
     <string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> funcționează acum."</string>
     <string name="launch_warning_original" msgid="3332206576800169626">"<xliff:g id="APP_NAME">%1$s</xliff:g> a fost lansată inițial."</string>
     <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Scară"</string>
-    <string name="screen_compat_mode_show" msgid="5080361367584709857">"Afișați întotdeauna"</string>
+    <string name="screen_compat_mode_show" msgid="5080361367584709857">"Afișează întotdeauna"</string>
     <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Reactivați acest mod din Setări de sistem &gt; Aplicații &gt; Descărcate."</string>
     <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu acceptă setarea actuală pentru Dimensiunea afișării și este posibil să aibă un comportament neașteptat."</string>
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Afișează întotdeauna"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> a fost concepută pentru o versiune incompatibilă de sistem de operare Android și este posibil să se comporte în mod neprevăzut. Poate fi disponibilă o versiune actualizată a aplicației."</string>
-    <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Afișați întotdeauna"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Căutați actualizări"</string>
+    <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Afișează întotdeauna"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Caută actualizări"</string>
     <string name="smv_application" msgid="3775183542777792638">"Aplicația <xliff:g id="APPLICATION">%1$s</xliff:g> (procesul <xliff:g id="PROCESS">%2$s</xliff:g>) a încălcat propria politică StrictMode."</string>
     <string name="smv_process" msgid="1398801497130695446">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> a încălcat propria politică StrictMode."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Se actualizează telefonul.…"</string>
@@ -1250,27 +1250,27 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Se pornesc aplicațiile."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Se finalizează pornirea."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Ați apăsat butonul de pornire. De obicei, această acțiune dezactivează ecranul.\n\nAtingeți ușor când vă configurați amprenta."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Atinge pentru a dezactiva ecranul"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Dezactivează ecranul"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Ca să termini configurarea, dezactivează ecranul"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Dezactivează"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continuați cu verificarea amprentei?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Ați apăsat butonul de pornire. De obicei, această acțiune dezactivează ecranul.\n\nAtingeți ușor pentru verificarea amprentei."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Dezactivați ecranul"</string>
     <string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"Continuați"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"Rulează <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Atingeți pentru a reveni la joc"</string>
-    <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Alegeți jocul"</string>
+    <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"Atinge pentru a reveni la joc"</string>
+    <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"Alege jocul"</string>
     <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"Pentru o performanță mai bună, se poate deschide un singur joc odată."</string>
     <string name="old_app_action" msgid="725331621042848590">"Reveniți la <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_action" msgid="547772182913269801">"Deschideți <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_action" msgid="547772182913269801">"Deschide <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> se va închide fără să salveze"</string>
     <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> a depășit limita de memorie"</string>
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"Datele privind memoria heap <xliff:g id="PROC">%1$s</xliff:g> sunt gata"</string>
-    <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Datele privind memoria au fost culese. Atingeți pentru a trimite."</string>
-    <string name="dump_heap_title" msgid="4367128917229233901">"Trimiteți datele privind memoria?"</string>
+    <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Datele privind memoria au fost culese. Atinge pentru a trimite."</string>
+    <string name="dump_heap_title" msgid="4367128917229233901">"Trimiți datele privind memoria?"</string>
     <string name="dump_heap_text" msgid="1692649033835719336">"Procesul <xliff:g id="PROC">%1$s</xliff:g> și-a depășit limita de memorie de <xliff:g id="SIZE">%2$s</xliff:g>. Sunt disponibile datele privind memoria heap, pe care le puteți trimite dezvoltatorului. Atenție: aceste date privind memoria heap pot conține informații cu caracter personal la care aplicația are acces."</string>
     <string name="dump_heap_system_text" msgid="6805155514925350849">"Procesul <xliff:g id="PROC">%1$s</xliff:g> a depășit limita de memorie de <xliff:g id="SIZE">%2$s</xliff:g>. Sunt disponibile datele privind memoria heap, pe care le puteți distribui. Atenție: aceste date privind memoria heap pot conține informații cu caracter personal sensibile la care procesul are acces și care pot include ceea ce tastați."</string>
     <string name="dump_heap_ready_text" msgid="5849618132123045516">"Sunt disponibile datele privind memoria heap a procesului <xliff:g id="PROC">%1$s</xliff:g>, pe care le puteți distribui. Atenție: aceste date privind memoria heap pot conține informații cu caracter personal sensibile la care procesul are acces și care pot include ceea ce tastați."</string>
-    <string name="sendText" msgid="493003724401350724">"Alegeți o acțiune pentru text"</string>
+    <string name="sendText" msgid="493003724401350724">"Alege o acțiune pentru text"</string>
     <string name="volume_ringtone" msgid="134784084629229029">"Volum sonerie"</string>
     <string name="volume_music" msgid="7727274216734955095">"Volum media"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Redare prin Bluetooth"</string>
@@ -1297,7 +1297,7 @@
     <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
     <skip />
     <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nu are acces la internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Atingeți pentru opțiuni"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Atinge pentru opțiuni"</string>
     <string name="mobile_no_internet" msgid="4014455157529909781">"Rețeaua mobilă nu are acces la internet"</string>
     <string name="other_networks_no_internet" msgid="6698711684200067033">"Rețeaua nu are acces la internet"</string>
     <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Serverul DNS privat nu poate fi accesat"</string>
@@ -1315,33 +1315,33 @@
   </string-array>
     <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un tip de rețea necunoscut"</string>
     <string name="accept" msgid="5447154347815825107">"Acceptați"</string>
-    <string name="decline" msgid="6490507610282145874">"Refuzați"</string>
-    <string name="select_character" msgid="3352797107930786979">"Introduceți caracterul"</string>
+    <string name="decline" msgid="6490507610282145874">"Refuz"</string>
+    <string name="select_character" msgid="3352797107930786979">"Introdu caracterul"</string>
     <string name="sms_control_title" msgid="4748684259903148341">"Se trimit mesaje SMS"</string>
-    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; trimite un număr mare de mesaje SMS. Permiteți acestei aplicații să trimită în continuare mesaje?"</string>
-    <string name="sms_control_yes" msgid="4858845109269524622">"Permiteți"</string>
-    <string name="sms_control_no" msgid="4845717880040355570">"Refuzați"</string>
+    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; trimite un număr mare de mesaje SMS. Permiți acestei aplicații să trimită în continuare mesaje?"</string>
+    <string name="sms_control_yes" msgid="4858845109269524622">"Permite"</string>
+    <string name="sms_control_no" msgid="4845717880040355570">"Refuz"</string>
     <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; intenționează să trimită un mesaj la &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
     <string name="sms_short_code_details" msgid="2723725738333388351">"Acest lucru "<b>"poate genera costuri"</b>" în contul dvs. mobil."</string>
     <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"Acest lucru va genera costuri în contul dvs. mobil."</b></string>
-    <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"Trimiteți"</string>
-    <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Anulați"</string>
+    <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"Trimite"</string>
+    <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Anulează"</string>
     <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Doresc să se rețină opțiunea"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Puteți modifica ulterior în Setări &gt; Aplicații"</string>
-    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Permiteți întotdeauna"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Permite întotdeauna"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Nu permiteți niciodată"</string>
     <string name="sim_removed_title" msgid="5387212933992546283">"Card SIM eliminat"</string>
     <string name="sim_removed_message" msgid="9051174064474904617">"Rețeaua mobilă va fi indisponibilă până când reporniți cu un card SIM valid introdus."</string>
     <string name="sim_done_button" msgid="6464250841528410598">"Terminat"</string>
     <string name="sim_added_title" msgid="7930779986759414595">"Card SIM adăugat"</string>
-    <string name="sim_added_message" msgid="6602906609509958680">"Reporniți dispozitivul pentru a accesa rețeaua mobilă."</string>
-    <string name="sim_restart_button" msgid="8481803851341190038">"Reporniți"</string>
+    <string name="sim_added_message" msgid="6602906609509958680">"Repornește dispozitivul pentru a accesa rețeaua mobilă."</string>
+    <string name="sim_restart_button" msgid="8481803851341190038">"Repornește"</string>
     <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Activați serviciul mobil"</string>
     <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Descărcați aplicația operatorului pentru a vă activa noul card SIM"</string>
     <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Descărcați aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> pentru a vă activa noul card SIM"</string>
     <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Descărcați aplicația"</string>
     <string name="carrier_app_notification_title" msgid="5815477368072060250">"S-a introdus un card SIM nou"</string>
-    <string name="carrier_app_notification_text" msgid="6567057546341958637">"Atingeți pentru a-l configura"</string>
+    <string name="carrier_app_notification_text" msgid="6567057546341958637">"Atinge pentru a-l configura"</string>
     <string name="time_picker_dialog_title" msgid="9053376764985220821">"Setați ora"</string>
     <string name="date_picker_dialog_title" msgid="5030520449243071926">"Setați data"</string>
     <string name="date_time_set" msgid="4603445265164486816">"Setați"</string>
@@ -1358,16 +1358,16 @@
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Tetheringul prin USB este activat"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI prin USB este activat"</string>
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Accesoriu USB conectat"</string>
-    <string name="usb_notification_message" msgid="4715163067192110676">"Atingeți pentru mai multe opțiuni."</string>
-    <string name="usb_power_notification_message" msgid="7284765627437897702">"Se încarcă dispozitivul conectat. Atingeți pentru mai multe opțiuni."</string>
+    <string name="usb_notification_message" msgid="4715163067192110676">"Atinge pentru mai multe opțiuni."</string>
+    <string name="usb_power_notification_message" msgid="7284765627437897702">"Se încarcă dispozitivul conectat. Atinge pentru mai multe opțiuni."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"S-a detectat un accesoriu audio analogic"</string>
-    <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Dispozitivul atașat nu este compatibil cu acest telefon. Atingeți pentru a afla mai multe."</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Dispozitivul atașat nu este compatibil cu acest telefon. Atinge pentru a afla mai multe."</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"Remedierea erorilor prin USB conectată"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"Atingeți pentru a dezactiva."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Selectați pentru a dezactiva remedierea erorilor prin USB."</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"Atinge pentru a dezactiva."</string>
+    <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Selectează pentru a dezactiva remedierea erorilor prin USB."</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Remedierea erorilor wireless este activă"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Atinge pentru a dezactiva remedierea erorilor wireless"</string>
-    <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selectați pentru a dezactiva remedierea erorilor wireless."</string>
+    <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selectează pentru a dezactiva remedierea erorilor wireless."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modul Set de testare este activat"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Reveniți la setările din fabrică pentru a dezactiva modul Set de testare."</string>
     <string name="console_running_notification_title" msgid="6087888939261635904">"Consola din serie este activată"</string>
@@ -1379,16 +1379,16 @@
     <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"Portul USB poate fi folosit"</string>
     <string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Telefonul nu mai detectează lichide sau reziduuri."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Se creează un raport de eroare…"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Trimiteți raportul de eroare?"</string>
+    <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Trimiți raportul de eroare?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Se trimite raportul de eroare…"</string>
     <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Administratorul dvs. a solicitat un raport de eroare pentru a remedia problemele acestui dispozitiv. Este posibil să se permită accesul la date și aplicații."</string>
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"TRIMITEȚI"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REFUZAȚI"</string>
-    <string name="select_input_method" msgid="3971267998568587025">"Alegeți metoda de introducere de text"</string>
+    <string name="select_input_method" msgid="3971267998568587025">"Alege metoda de introducere de text"</string>
     <string name="show_ime" msgid="6406112007347443383">"Se păstrează pe ecran cât timp este activată tastatura fizică"</string>
-    <string name="hardware" msgid="1800597768237606953">"Afișați tastatura virtuală"</string>
-    <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Configurați tastatura fizică"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Atingeți pentru a selecta limba și aspectul"</string>
+    <string name="hardware" msgid="1800597768237606953">"Afișează tastatura virtuală"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Configurează tastatura fizică"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Atinge pentru a selecta limba și aspectul"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Afișare peste alte aplicații"</string>
@@ -1401,29 +1401,29 @@
     <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Se analizează spațiul de stocare media"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> nou"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> nu funcționează"</string>
-    <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Atingeți pentru a configura"</string>
-    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selectați pentru a configura"</string>
+    <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Atinge pentru a configura"</string>
+    <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Selectează pentru a configura"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Poate fi nevoie să reformatați dispozitivul. Atingeți pentru a-l scoate."</string>
     <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Pentru stocarea de fotografii, videoclipuri, muzică și altele"</string>
     <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Răsfoiți fișierele media"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problemă cu <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> nu funcționează"</string>
-    <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Atingeți pentru a remedia"</string>
-    <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"<xliff:g id="NAME">%s</xliff:g> este corupt. Selectați pentru a remedia."</string>
+    <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"Atinge pentru a remedia"</string>
+    <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"<xliff:g id="NAME">%s</xliff:g> este corupt. Selectează pentru a remedia."</string>
     <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"Poate fi nevoie să reformatați dispozitivul. Atingeți pentru a-l scoate."</string>
     <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"S-a detectat <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> nu funcționează"</string>
     <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"Atinge pentru a configura"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selectați pentru a configura <xliff:g id="NAME">%s</xliff:g> într-un format acceptat."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Selectează pentru a configura <xliff:g id="NAME">%s</xliff:g> într-un format acceptat."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Poate fi nevoie să reformatați dispozitivul"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> scos pe neașteptate"</string>
-    <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Deconectați din setări dispozitivele media înainte de a le îndepărta, pentru a evita pierderea conținutului"</string>
+    <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Deconectează din setări dispozitivele media înainte de a le îndepărta, pentru a evita pierderea conținutului"</string>
     <string name="ext_media_nomedia_notification_title" msgid="742671636376975890">"S-a eliminat <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"Funcționarea ar putea fi necorespunzătoare. Introduceți un dispozitiv de stocare nou."</string>
+    <string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"Funcționarea ar putea fi necorespunzătoare. Introdu un dispozitiv de stocare nou."</string>
     <string name="ext_media_unmounting_notification_title" msgid="4147986383917892162">"Se deconectează <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmounting_notification_message" msgid="5717036261538754203">"Nu scoateți"</string>
-    <string name="ext_media_init_action" msgid="2312974060585056709">"Configurați"</string>
-    <string name="ext_media_unmount_action" msgid="966992232088442745">"Scoateți"</string>
+    <string name="ext_media_init_action" msgid="2312974060585056709">"Configurează"</string>
+    <string name="ext_media_unmount_action" msgid="966992232088442745">"Scoate"</string>
     <string name="ext_media_browse_action" msgid="344865351947079139">"Explorați"</string>
     <string name="ext_media_seamless_action" msgid="8837030226009268080">"Schimbați ieșirea"</string>
     <string name="ext_media_missing_title" msgid="3209472091220515046">"<xliff:g id="NAME">%s</xliff:g> lipsește"</string>
@@ -1458,11 +1458,11 @@
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite unei aplicații să solicite permisiunea de a ignora optimizările bateriei pentru aplicația respectivă."</string>
     <string name="permlab_queryAllPackages" msgid="2928450604653281650">"să interogheze toate pachetele"</string>
     <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permite unei aplicații să vadă toate pachetele instalate."</string>
-    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Apăsați de două ori pentru a controla mărirea/micșorarea"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Apasă de două ori pentru a controla mărirea/micșorarea"</string>
     <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nu s-a putut adăuga widgetul."</string>
     <string name="ime_action_go" msgid="5536744546326495436">"Accesați"</string>
-    <string name="ime_action_search" msgid="4501435960587287668">"Căutați"</string>
-    <string name="ime_action_send" msgid="8456843745664334138">"Trimiteți"</string>
+    <string name="ime_action_search" msgid="4501435960587287668">"Caută"</string>
+    <string name="ime_action_send" msgid="8456843745664334138">"Trimite"</string>
     <string name="ime_action_next" msgid="4169702997635728543">"Înainte"</string>
     <string name="ime_action_done" msgid="6299921014822891569">"Terminat"</string>
     <string name="ime_action_previous" msgid="6548799326860401611">"Înapoi"</string>
@@ -1470,10 +1470,10 @@
     <string name="dial_number_using" msgid="6060769078933953531">"Formați numărul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="6200708808003692594">"Creați contactul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Următoarele aplicații solicită permisiunea de a accesa contul dvs. acum și în viitor."</string>
-    <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Permiteți această solicitare?"</string>
+    <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Permiți această solicitare?"</string>
     <string name="grant_permissions_header_text" msgid="3420736827804657201">"Solicitare de acces"</string>
-    <string name="allow" msgid="6195617008611933762">"Permiteți"</string>
-    <string name="deny" msgid="6632259981847676572">"Refuzați"</string>
+    <string name="allow" msgid="6195617008611933762">"Permite"</string>
+    <string name="deny" msgid="6632259981847676572">"Refuz"</string>
     <string name="permission_request_notification_title" msgid="1810025922441048273">"Permisiune solicitată"</string>
     <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Permisiune solicitată\npentru contul <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"Permisiune solicitată de <xliff:g id="APP">%1$s</xliff:g>\npentru contul <xliff:g id="ACCOUNT">%2$s</xliff:g>."</string>
@@ -1490,22 +1490,22 @@
     <string name="notification_ranker_binding_label" msgid="432708245635563763">"Serviciul de clasificare a notificărilor"</string>
     <string name="vpn_title" msgid="5906991595291514182">"VPN activat"</string>
     <string name="vpn_title_long" msgid="6834144390504619998">"VPN este activată de <xliff:g id="APP">%s</xliff:g>"</string>
-    <string name="vpn_text" msgid="2275388920267251078">"Apăsați pentru a gestiona rețeaua."</string>
-    <string name="vpn_text_long" msgid="278540576806169831">"Conectat la <xliff:g id="SESSION">%s</xliff:g>. Apăsați pentru a gestiona rețeaua."</string>
+    <string name="vpn_text" msgid="2275388920267251078">"Apasă pentru a gestiona rețeaua."</string>
+    <string name="vpn_text_long" msgid="278540576806169831">"Conectat la <xliff:g id="SESSION">%s</xliff:g>. Apasă pentru a gestiona rețeaua."</string>
     <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Se efectuează conectarea la rețeaua VPN activată permanent…"</string>
     <string name="vpn_lockdown_connected" msgid="2853127976590658469">"Conectat(ă) la rețeaua VPN activată permanent"</string>
     <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Deconectat de la rețeaua VPN activată permanent"</string>
     <string name="vpn_lockdown_error" msgid="4453048646854247947">"Nu s-a putut conecta la rețeaua VPN activată permanent"</string>
     <string name="vpn_lockdown_config" msgid="8331697329868252169">"Modificați setările de rețea sau VPN"</string>
-    <string name="upload_file" msgid="8651942222301634271">"Alegeți un fișier"</string>
+    <string name="upload_file" msgid="8651942222301634271">"Alege un fișier"</string>
     <string name="no_file_chosen" msgid="4146295695162318057">"Nu au fost găsite fișiere"</string>
-    <string name="reset" msgid="3865826612628171429">"Resetați"</string>
-    <string name="submit" msgid="862795280643405865">"Trimiteți"</string>
+    <string name="reset" msgid="3865826612628171429">"Resetează"</string>
+    <string name="submit" msgid="862795280643405865">"Trimite"</string>
     <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Aplicația pentru condus rulează"</string>
     <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Atingeți ca să ieșiți din aplicația pentru condus."</string>
     <string name="back_button_label" msgid="4078224038025043387">"Înapoi"</string>
     <string name="next_button_label" msgid="6040209156399907780">"Înainte"</string>
-    <string name="skip_button_label" msgid="3566599811326688389">"Omiteți"</string>
+    <string name="skip_button_label" msgid="3566599811326688389">"Omite"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nicio potrivire"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Găsiți pe pagină"</string>
     <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# potrivire}few{# din {total}}other{# din {total}}}"</string>
@@ -1523,12 +1523,12 @@
     <string name="gpsVerifNo" msgid="1671201856091564741">"Nu"</string>
     <string name="sync_too_many_deletes" msgid="6999440774578705300">"Limita pentru ștergere a fost depășită"</string>
     <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Există <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>   elemente șterse pentru <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, contul <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Ce doriți să faceți?"</string>
-    <string name="sync_really_delete" msgid="5657871730315579051">"Ștergeți elementele"</string>
-    <string name="sync_undo_deletes" msgid="5786033331266418896">"Anulați aceste ștergeri"</string>
+    <string name="sync_really_delete" msgid="5657871730315579051">"Șterge elementele"</string>
+    <string name="sync_undo_deletes" msgid="5786033331266418896">"Anulează aceste ștergeri"</string>
     <string name="sync_do_nothing" msgid="4528734662446469646">"Nu trebuie să luați nicio măsură deocamdată"</string>
-    <string name="choose_account_label" msgid="5557833752759831548">"Alegeți un cont"</string>
-    <string name="add_account_label" msgid="4067610644298737417">"Adăugați un cont"</string>
-    <string name="add_account_button_label" msgid="322390749416414097">"Adăugați un cont"</string>
+    <string name="choose_account_label" msgid="5557833752759831548">"Alege un cont"</string>
+    <string name="add_account_label" msgid="4067610644298737417">"Adaugă un cont"</string>
+    <string name="add_account_button_label" msgid="322390749416414097">"Adaugă un cont"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"Creșteți"</string>
     <string name="number_picker_decrement_button" msgid="5116948444762708204">"Reduceți"</string>
     <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> atingeți lung."</string>
@@ -1548,16 +1548,16 @@
     <string name="date_picker_prev_month_button" msgid="3418694374017868369">"Luna trecută"</string>
     <string name="date_picker_next_month_button" msgid="4858207337779144840">"Luna viitoare"</string>
     <string name="keyboardview_keycode_alt" msgid="8997420058584292385">"Alt"</string>
-    <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Anulați"</string>
-    <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Ștergeți"</string>
+    <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Anulează"</string>
+    <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Șterge"</string>
     <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Terminat"</string>
     <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Schimbarea modului"</string>
     <string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
-    <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Alegeți o aplicație"</string>
+    <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Alege o aplicație"</string>
     <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Nu s-a putut lansa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Permiteți accesul pentru"</string>
-    <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Permiteți accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Permite accesul pentru"</string>
+    <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Permite accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="982510275422590757">"Mâner glisant. Atingeți și țineți apăsat."</string>
     <string name="description_target_unlock_tablet" msgid="7431571180065859551">"Glisați pentru a debloca."</string>
     <string name="action_bar_home_description" msgid="1501655419158631974">"Navigați la ecranul de pornire"</string>
@@ -1599,12 +1599,12 @@
     <string name="fingerprints" msgid="148690767172613723">"Amprente:"</string>
     <string name="sha256_fingerprint" msgid="7103976380961964600">"Amprentă SHA-256:"</string>
     <string name="sha1_fingerprint" msgid="2339915142825390774">"Amprentă SHA-1:"</string>
-    <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Afișați-le pe toate"</string>
-    <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Alegeți activitatea"</string>
+    <string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Afișează-le pe toate"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Alege activitatea"</string>
     <string name="share_action_provider_share_with" msgid="1904096863622941880">"Distribuiți pentru"</string>
     <string name="sending" msgid="206925243621664438">"Se trimite..."</string>
     <string name="launchBrowserDefault" msgid="6328349989932924119">"Lansați browserul?"</string>
-    <string name="SetupCallDefault" msgid="5581740063237175247">"Acceptați apelul?"</string>
+    <string name="SetupCallDefault" msgid="5581740063237175247">"Accepți apelul?"</string>
     <string name="activity_resolver_use_always" msgid="5575222334666843269">"Întotdeauna"</string>
     <string name="activity_resolver_use_once" msgid="948462794469672658">"Numai o dată"</string>
     <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s nu acceptă profilul de serviciu"</string>
@@ -1612,18 +1612,18 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Difuz. dispozit. andocare"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Dispozitiv extern"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Căști"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Audio Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="8297563323032966831">"Ecran wireless"</string>
-    <string name="media_route_button_content_description" msgid="2299223698196869956">"Trimiteți"</string>
+    <string name="media_route_button_content_description" msgid="2299223698196869956">"Trimite"</string>
     <string name="media_route_chooser_title" msgid="6646594924991269208">"Conectați-vă la dispozitiv"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Proiectați ecranul pe dispozitiv"</string>
     <string name="media_route_chooser_searching" msgid="6119673534251329535">"Se caută dispozitive..."</string>
     <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Setări"</string>
-    <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Deconectați-vă"</string>
+    <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Deconectează-te"</string>
     <string name="media_route_status_scanning" msgid="8045156315309594482">"Se scanează..."</string>
     <string name="media_route_status_connecting" msgid="5845597961412010540">"Se conectează..."</string>
     <string name="media_route_status_available" msgid="1477537663492007608">"Disponibilă"</string>
@@ -1639,15 +1639,15 @@
     <string name="kg_wrong_password" msgid="2384677900494439426">"Parolă greșită"</string>
     <string name="kg_wrong_pin" msgid="3680925703673166482">"Cod PIN greșit"</string>
     <string name="kg_pattern_instructions" msgid="8366024510502517748">"Desenați modelul"</string>
-    <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Introduceți codul PIN al cardului SIM"</string>
-    <string name="kg_pin_instructions" msgid="7355933174673539021">"Introduceți codul PIN"</string>
-    <string name="kg_password_instructions" msgid="7179782578809398050">"Introduceți parola"</string>
+    <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Introdu codul PIN al cardului SIM"</string>
+    <string name="kg_pin_instructions" msgid="7355933174673539021">"Introdu codul PIN"</string>
+    <string name="kg_password_instructions" msgid="7179782578809398050">"Introdu parola"</string>
     <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"Cardul SIM este acum dezactivat. Introduceți codul PUK pentru a continua. Contactați operatorul pentru mai multe detalii."</string>
-    <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Introduceți codul PIN dorit"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Introdu codul PIN dorit"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Confirmați codul PIN dorit"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Se deblochează cardul SIM..."</string>
     <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"Cod PIN incorect."</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Introduceți un cod PIN format din 4 până la 8 cifre."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Introdu un cod PIN format din 4 până la 8 cifre."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"Codul PUK trebuie să conțină 8 numere."</string>
     <string name="kg_invalid_puk" msgid="4809502818518963344">"Reintroduceți codul PUK corect. Încercările repetate vor dezactiva definitiv cardul SIM."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"Codurile PIN nu coincid"</string>
@@ -1691,11 +1691,11 @@
     <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Poate citi tot conținutul de pe ecran și poate afișa conținut peste alte aplicații."</string>
     <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Vă vede interacțiunile și le realizează"</string>
     <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Poate urmări interacțiunile dvs. cu o aplicație sau cu un senzor hardware și poate interacționa cu aplicații în numele dvs."</string>
-    <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permiteți"</string>
-    <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuzați"</string>
+    <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permite"</string>
+    <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuz"</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Atingeți o funcție ca să începeți să o folosiți:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Alegeți funcțiile pe care să le folosiți cu butonul de accesibilitate"</string>
-    <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Alegeți funcțiile pentru comanda rapidă a butonului de volum"</string>
+    <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Alege funcțiile pentru comanda rapidă a butonului de volum"</string>
     <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> a fost dezactivat"</string>
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editați comenzile rapide"</string>
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gata"</string>
@@ -1707,7 +1707,7 @@
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Luminozitate redusă suplimentar"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Apăsați ambele butoane de volum timp de trei secunde pentru a folosi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Apasă ambele butoane de volum timp de trei secunde pentru a folosi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Alegeți o funcție pe care să o folosiți când atingeți butonul de accesibilitate:"</string>
     <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Alegeți o funcție pe care să o folosiți cu gestul de accesibilitate (glisați în sus cu două degete din partea de jos a ecranului):"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Alegeți o funcție pe care să o folosiți cu gestul de accesibilitate (glisați în sus cu trei degete din partea de jos a ecranului):"</string>
@@ -1824,9 +1824,9 @@
     <string name="reason_unknown" msgid="5599739807581133337">"necunoscut"</string>
     <string name="reason_service_unavailable" msgid="5288405248063804713">"Serviciul de printare nu este activat"</string>
     <string name="print_service_installed_title" msgid="6134880817336942482">"Serviciul <xliff:g id="NAME">%s</xliff:g> a fost instalat"</string>
-    <string name="print_service_installed_message" msgid="7005672469916968131">"Atingeți pentru a activa"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"Introduceți codul PIN de administrator"</string>
-    <string name="restr_pin_enter_pin" msgid="373139384161304555">"Introduceți codul PIN"</string>
+    <string name="print_service_installed_message" msgid="7005672469916968131">"Atinge pentru a activa"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"Introdu codul PIN de administrator"</string>
+    <string name="restr_pin_enter_pin" msgid="373139384161304555">"Introdu codul PIN"</string>
     <string name="restr_pin_incorrect" msgid="3861383632940852496">"Incorect"</string>
     <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Codul PIN actual"</string>
     <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Codul PIN nou"</string>
@@ -1834,17 +1834,17 @@
     <string name="restr_pin_create_pin" msgid="917067613896366033">"Creați un cod PIN pentru modificarea restricțiilor"</string>
     <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"Codurile PIN nu se potrivesc. Încercați din nou."</string>
     <string name="restr_pin_error_too_short" msgid="1547007808237941065">"Codul PIN este prea scurt. Trebuie să aibă cel puțin 4 cifre."</string>
-    <string name="restr_pin_try_later" msgid="5897719962541636727">"Reîncercați mai târziu"</string>
+    <string name="restr_pin_try_later" msgid="5897719962541636727">"Reîncearcă mai târziu"</string>
     <string name="immersive_cling_title" msgid="2307034298721541791">"Vizualizare pe ecran complet"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Pentru a ieși, glisați de sus în jos."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Am înțeles"</string>
     <string name="done_label" msgid="7283767013231718521">"Terminat"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Selector circular pentru ore"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Selector circular pentru minute"</string>
-    <string name="select_hours" msgid="5982889657313147347">"Selectați orele"</string>
-    <string name="select_minutes" msgid="9157401137441014032">"Selectați minutele"</string>
-    <string name="select_day" msgid="2060371240117403147">"Selectați luna și ziua"</string>
-    <string name="select_year" msgid="1868350712095595393">"Selectați anul"</string>
+    <string name="select_hours" msgid="5982889657313147347">"Selectează orele"</string>
+    <string name="select_minutes" msgid="9157401137441014032">"Selectează minutele"</string>
+    <string name="select_day" msgid="2060371240117403147">"Selectează luna și ziua"</string>
+    <string name="select_year" msgid="1868350712095595393">"Selectează anul"</string>
     <string name="deleted_key" msgid="9130083334943364001">"<xliff:g id="KEY">%1$s</xliff:g> a fost șters"</string>
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> de serviciu"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> pentru serviciu (2)"</string>
@@ -1875,7 +1875,7 @@
     <string name="zen_mode_forever" msgid="740585666364912448">"Până când dezactivați"</string>
     <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Până când dezactivați „Nu deranja”"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
-    <string name="toolbar_collapse_description" msgid="8009920446193610996">"Restrângeți"</string>
+    <string name="toolbar_collapse_description" msgid="8009920446193610996">"Restrânge"</string>
     <string name="zen_mode_feature_name" msgid="3785547207263754500">"Nu deranja"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Inactivitate"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Nopțile din zilele lucrătoare"</string>
@@ -1897,16 +1897,16 @@
     <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Profil de serviciu"</string>
     <string name="notification_alerted_content_description" msgid="6139691253611265992">"Notificat"</string>
     <string name="notification_verified_content_description" msgid="6401483602782359391">"Confirmat"</string>
-    <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Extindeți"</string>
-    <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Restrângeți"</string>
+    <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Extinde"</string>
+    <string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Restrânge"</string>
     <string name="expand_action_accessibility" msgid="1947657036871746627">"extindeți/restrângeți"</string>
     <string name="usb_midi_peripheral_name" msgid="490523464968655741">"Port USB Android periferic"</string>
     <string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string>
     <string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"Port USB periferic"</string>
     <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"Mai multe opțiuni"</string>
-    <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"Închideți meniul suplimentar"</string>
+    <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"Închide meniul suplimentar"</string>
     <string name="maximize_button_text" msgid="4258922519914732645">"Maximizați"</string>
-    <string name="close_button_text" msgid="10603510034455258">"Închideți"</string>
+    <string name="close_button_text" msgid="10603510034455258">"Închide"</string>
     <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
     <string name="call_notification_answer_action" msgid="5999246836247132937">"Răspundeți"</string>
     <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
@@ -1919,10 +1919,10 @@
     <string name="importance_from_user" msgid="2782756722448800447">"Dvs. setați importanța acestor notificări."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Notificarea este importantă având în vedere persoanele implicate."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificare de aplicație personalizată"</string>
-    <string name="user_creation_account_exists" msgid="2239146360099708035">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>? (există deja un utilizator cu acest cont)"</string>
-    <string name="user_creation_adding" msgid="7305185499667958364">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="supervised_user_creation_label" msgid="6884904353827427515">"Adăugați un utilizator monitorizat"</string>
-    <string name="language_selection_title" msgid="52674936078683285">"Adăugați o limbă"</string>
+    <string name="user_creation_account_exists" msgid="2239146360099708035">"Permiți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>? (există deja un utilizator cu acest cont)"</string>
+    <string name="user_creation_adding" msgid="7305185499667958364">"Permiți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
+    <string name="supervised_user_creation_label" msgid="6884904353827427515">"Adaugă un utilizator monitorizat"</string>
+    <string name="language_selection_title" msgid="52674936078683285">"Adaugă o limbă"</string>
     <string name="country_selection_title" msgid="5221495687299014379">"Regiunea preferată"</string>
     <string name="search_language_hint" msgid="7004225294308793583">"Numele limbii"</string>
     <string name="language_picker_section_suggested" msgid="6556199184638990447">"Sugerate"</string>
@@ -1931,11 +1931,11 @@
     <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"Regiuni sugerate"</string>
     <string name="language_picker_section_all" msgid="1985809075777564284">"Toate limbile"</string>
     <string name="region_picker_section_all" msgid="756441309928774155">"Toate regiunile"</string>
-    <string name="locale_search_menu" msgid="6258090710176422934">"Căutați"</string>
+    <string name="locale_search_menu" msgid="6258090710176422934">"Caută"</string>
     <string name="app_suspended_title" msgid="888873445010322650">"Aplicația nu este disponibilă"</string>
     <string name="app_suspended_default_message" msgid="6451215678552004172">"Momentan, aplicația <xliff:g id="APP_NAME_0">%1$s</xliff:g> nu este disponibilă. Aceasta este gestionată de <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
-    <string name="app_suspended_more_details" msgid="211260942831587014">"Aflați mai multe"</string>
-    <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Anulați întreruperea aplicației"</string>
+    <string name="app_suspended_more_details" msgid="211260942831587014">"Află mai multe"</string>
+    <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Anulează întreruperea aplicației"</string>
     <string name="work_mode_off_title" msgid="961171256005852058">"Activați aplicațiile pentru lucru?"</string>
     <string name="work_mode_off_message" msgid="7319580997683623309">"Obțineți acces la aplicațiile pentru lucru și notificări"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activați"</string>
@@ -1950,28 +1950,28 @@
     <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Setările pentru Android TV sunt indisponibile"</string>
     <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Setările pentru tabletă sunt indisponibile"</string>
     <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Setările pentru telefon sunt indisponibile"</string>
-    <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încercați pe dispozitivul Android TV."</string>
-    <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încercați pe tabletă."</string>
-    <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încercați pe telefon."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Aplicația necesită securitate suplimentară. Încercați pe dispozitivul Android TV."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Aplicația necesită securitate suplimentară. Încercați pe tabletă."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Aplicația necesită securitate suplimentară. Încercați pe telefon."</string>
+    <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încearcă pe dispozitivul Android TV."</string>
+    <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încearcă pe tabletă."</string>
+    <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încearcă pe telefon."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Aplicația necesită securitate suplimentară. Încearcă pe dispozitivul Android TV."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Aplicația necesită securitate suplimentară. Încearcă pe tabletă."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Aplicația necesită securitate suplimentară. Încearcă pe telefon."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Nu se poate accesa pe <xliff:g id="DEVICE">%1$s</xliff:g>. Încearcă pe dispozitivul Android TV."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Nu se poate accesa pe <xliff:g id="DEVICE">%1$s</xliff:g>. Încearcă pe tabletă."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Nu se poate accesa pe <xliff:g id="DEVICE">%1$s</xliff:g>. Încearcă pe telefon."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Această aplicație a fost creată pentru o versiune Android mai veche și este posibil să nu funcționeze corect. Încercați să căutați actualizări sau contactați dezvoltatorul."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Căutați actualizări"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Caută actualizări"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Aveți mesaje noi"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"Deschideți aplicația pentru SMS-uri ca să vizualizați"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"Unele funcții ar putea fi limitate"</string>
     <string name="profile_encrypted_detail" msgid="5279730442756849055">"Profil de serviciu blocat"</string>
     <string name="profile_encrypted_message" msgid="1128512616293157802">"Atingeți ca să deblocați"</string>
     <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Conectat la <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
-    <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Atingeți pentru a vedea fișierele"</string>
+    <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Atinge pentru a vedea fișierele"</string>
     <string name="pin_target" msgid="8036028973110156895">"Fixați"</string>
     <string name="pin_specific_target" msgid="7824671240625957415">"Fixați <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="unpin_target" msgid="3963318576590204447">"Anulați fixarea"</string>
-    <string name="unpin_specific_target" msgid="3859828252160908146">"Anulați fixarea pentru <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="unpin_target" msgid="3963318576590204447">"Anulează fixarea"</string>
+    <string name="unpin_specific_target" msgid="3859828252160908146">"Anulează fixarea pentru <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="app_info" msgid="6113278084877079851">"Informații despre aplicație"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="6577581216125805905">"Se pornește demonstrația…"</string>
@@ -1993,28 +1993,28 @@
     <string name="time_picker_hour_label" msgid="4208590187662336864">"oră"</string>
     <string name="time_picker_minute_label" msgid="8307452311269824553">"minut"</string>
     <string name="time_picker_header_text" msgid="9073802285051516688">"Setați ora"</string>
-    <string name="time_picker_input_error" msgid="8386271930742451034">"Introduceți o oră validă"</string>
-    <string name="time_picker_prompt_label" msgid="303588544656363889">"Introduceți ora"</string>
+    <string name="time_picker_input_error" msgid="8386271930742451034">"Introdu o oră validă"</string>
+    <string name="time_picker_prompt_label" msgid="303588544656363889">"Introdu ora"</string>
     <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Pentru a introduce ora, comutați la modul de introducere a textului."</string>
     <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Pentru a introduce ora, comutați la modul ceas."</string>
     <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Opțiuni de completare automată"</string>
-    <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Salvați pentru completare automată"</string>
+    <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Salvează pentru completare automată"</string>
     <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Conținutul nu poate fi completat automat"</string>
     <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Nicio sugestie de completare automată"</string>
     <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{O sugestie de completare automată}few{# sugestii de completare automată}other{# de sugestii de completare automată}}"</string>
-    <string name="autofill_save_title" msgid="7719802414283739775">"Salvați în "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Salvați <xliff:g id="TYPE">%1$s</xliff:g> în "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Salvați <xliff:g id="TYPE_0">%1$s</xliff:g> și <xliff:g id="TYPE_1">%2$s</xliff:g> în "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Salvați <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> și <xliff:g id="TYPE_2">%3$s</xliff:g> în "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_update_title" msgid="3630695947047069136">"Actualizați în "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Actualizați <xliff:g id="TYPE">%1$s</xliff:g> în "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Actualizați <xliff:g id="TYPE_0">%1$s</xliff:g> și <xliff:g id="TYPE_1">%2$s</xliff:g> în "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
-    <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Actualizați aceste articole în "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> și <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
-    <string name="autofill_save_yes" msgid="8035743017382012850">"Salvați"</string>
+    <string name="autofill_save_title" msgid="7719802414283739775">"Salvezi în "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Salvezi <xliff:g id="TYPE">%1$s</xliff:g> în "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Salvezi <xliff:g id="TYPE_0">%1$s</xliff:g> și <xliff:g id="TYPE_1">%2$s</xliff:g> în "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"Salvezi <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> și <xliff:g id="TYPE_2">%3$s</xliff:g> în "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_update_title" msgid="3630695947047069136">"Actualizezi în "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Actualizezi <xliff:g id="TYPE">%1$s</xliff:g> în "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Actualizezi <xliff:g id="TYPE_0">%1$s</xliff:g> și <xliff:g id="TYPE_1">%2$s</xliff:g> în "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
+    <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Actualizezi aceste articole în "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> și <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
+    <string name="autofill_save_yes" msgid="8035743017382012850">"Salvează"</string>
     <string name="autofill_save_no" msgid="9212826374207023544">"Nu, mulțumesc"</string>
     <string name="autofill_save_notnow" msgid="2853932672029024195">"Nu acum"</string>
     <string name="autofill_save_never" msgid="6821841919831402526">"Niciodată"</string>
-    <string name="autofill_update_yes" msgid="4608662968996874445">"Actualizați"</string>
+    <string name="autofill_update_yes" msgid="4608662968996874445">"Actualizează"</string>
     <string name="autofill_continue_yes" msgid="7914985605534510385">"Continuați"</string>
     <string name="autofill_save_type_password" msgid="5624528786144539944">"parolă"</string>
     <string name="autofill_save_type_address" msgid="3111006395818252885">"adresă"</string>
@@ -2046,10 +2046,10 @@
     <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Nu s-a putut restabili comanda rapidă"</string>
     <string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Comanda rapidă este dezactivată"</string>
     <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEZINSTALAȚI"</string>
-    <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"Deschideți oricum"</string>
+    <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"Deschide oricum"</string>
     <string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplicație dăunătoare detectată"</string>
-    <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permiteți ca <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> să acceseze toate jurnalele dispozitivului?"</string>
-    <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permiteți accesul o dată"</string>
+    <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permiți ca <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> să acceseze toate jurnalele dispozitivului?"</string>
+    <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permite accesul o dată"</string>
     <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nu permiteți"</string>
     <string name="log_access_confirmation_body" msgid="1806692062668620735">"Jurnalele dispozitivului înregistrează activitatea de pe dispozitivul tău. Aplicațiile pot folosi aceste jurnale pentru a identifica și a remedia probleme.\n\nUnele jurnale pot să conțină informații sensibile, prin urmare permite accesul la toate jurnalele dispozitivului doar aplicațiilor în care ai încredere. \n\nDacă nu permiți accesul aplicației la toate jurnalele dispozitivului, aceasta poate în continuare să acceseze propriile jurnale. Este posibil ca producătorul dispozitivului să acceseze în continuare unele jurnale sau informații de pe dispozitiv."</string>
     <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Nu mai afișa"</string>
@@ -2062,26 +2062,26 @@
     <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Funcția nouă Nu deranja ascunde notificările"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Atingeți ca să aflați mai multe și să modificați"</string>
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Funcția Nu deranja s-a schimbat"</string>
-    <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Atingeți pentru a verifica ce este blocat."</string>
+    <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Atinge pentru a verifica ce este blocat."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Examinați setările pentru notificări"</string>
     <string name="review_notification_settings_text" msgid="5916244866751849279">"Începând cu Android 13, aplicațiile pe care le instalați necesită permisiunea de a trimite notificări. Atingeți ca să modificați permisiunea pentru aplicațiile existente."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Mai târziu"</string>
-    <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Închideți"</string>
+    <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Închide"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Setări"</string>
     <string name="notification_appops_camera_active" msgid="8177643089272352083">"Cameră foto"</string>
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"Microfon"</string>
     <string name="notification_appops_overlay_active" msgid="5571732753262836481">"se afișează peste alte aplicații de pe ecran"</string>
     <string name="notification_feedback_indicator" msgid="663476517711323016">"Oferiți feedback"</string>
-    <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"Notificarea a fost promovată la Prestabilită. Atingeți pentru a oferi feedback."</string>
-    <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Notificarea a fost mutată în jos la Silențioasă. Atingeți pentru a oferi feedback."</string>
-    <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Notificarea a fost mutată la un nivel superior. Atingeți pentru a oferi feedback."</string>
-    <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Notificarea a fost mutată la un nivel inferior. Atingeți pentru a oferi feedback."</string>
+    <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"Notificarea a fost promovată la Prestabilită. Atinge pentru a oferi feedback."</string>
+    <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Notificarea a fost mutată în jos la Silențioasă. Atinge pentru a oferi feedback."</string>
+    <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Notificarea a fost mutată la un nivel superior. Atinge pentru a oferi feedback."</string>
+    <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Notificarea a fost mutată la un nivel inferior. Atinge pentru a oferi feedback."</string>
     <string name="nas_upgrade_notification_title" msgid="8436359459300146555">"Notificări optimizate"</string>
     <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Acțiunile și răspunsurile sugerate sunt acum trimise prin notificări optimizate. Notificările adaptive Android nu mai sunt acceptate."</string>
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Dezactivați"</string>
-    <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Aflați mai multe"</string>
+    <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Află mai multe"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Notificările optimizate au înlocuit Notificările adaptive Android de pe Android 12. Această funcție afișează acțiuni și răspunsuri sugerate și vă organizează notificările.\n\nNotificările optimizate pot accesa conținutul notificărilor, inclusiv informații cu caracter personal, precum mesajele și numele persoanelor de contact. În plus, funcția poate să închidă sau să răspundă la notificări, de exemplu, să răspundă la apeluri telefonice și să gestioneze opțiunea Nu deranja."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificare pentru informații despre modul Rutină"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Economisirea bateriei este activată"</string>
@@ -2127,7 +2127,7 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Comandă rapidă de accesibilitate de pe ecran"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de comenzi rapide de accesibilitate de pe ecran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Comandă rapidă de accesibilitate"</string>
-    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Închideți fereastra de notificări"</string>
+    <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Închide fereastra de notificări"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad sus"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad jos"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad stânga"</string>
@@ -2150,7 +2150,7 @@
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Acest conținut nu poate fi trimis cu aplicații personale"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Acest conținut nu poate fi deschis cu aplicații personale"</string>
     <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profilul de serviciu este întrerupt"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Atingeți pentru a activa"</string>
+    <string name="resolver_switch_on_work" msgid="463709043650610420">"Atinge pentru a activa"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nicio aplicație pentru lucru"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nicio aplicație personală"</string>
     <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"Deschideți <xliff:g id="APP">%s</xliff:g> în profilul personal?"</string>
@@ -2162,23 +2162,23 @@
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Codul PIN de deblocare SIM corporativă"</string>
     <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY" msgid="973059024670737358">"Codul PIN de deblocare SIM privind furnizorul de servicii"</string>
     <string name="PERSOSUBSTATE_SIM_SIM_ENTRY" msgid="4487435301206073787">"Codul PIN de deblocare SIM"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY" msgid="768060297218652809">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY" msgid="7129527319490548930">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ENTRY" msgid="2876126640607573252">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="8952595089930109282">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_SIM_SIM_PUK_ENTRY" msgid="3013902515773728996">"Introduceți codul PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY" msgid="768060297218652809">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY" msgid="7129527319490548930">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ENTRY" msgid="2876126640607573252">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="8952595089930109282">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_ENTRY" msgid="3013902515773728996">"Introdu codul PUK"</string>
     <string name="PERSOSUBSTATE_RUIM_NETWORK1_ENTRY" msgid="2974411408893410289">"Codul PIN de deblocare RUIM Network1"</string>
     <string name="PERSOSUBSTATE_RUIM_NETWORK2_ENTRY" msgid="687618528751880721">"Codul PIN de deblocare RUIM Network2"</string>
     <string name="PERSOSUBSTATE_RUIM_HRPD_ENTRY" msgid="6810596579655575381">"Codul PIN de deblocare RUIM Hrpd"</string>
     <string name="PERSOSUBSTATE_RUIM_CORPORATE_ENTRY" msgid="2715929642540980259">"Codul PIN de deblocare RUIM corporativă"</string>
     <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY" msgid="8557791623303951590">"Codul PIN de deblocare RUIM privind furnizorii de servicii"</string>
     <string name="PERSOSUBSTATE_RUIM_RUIM_ENTRY" msgid="7382468767274580323">"Codul PIN de deblocare RUIM"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY" msgid="6730880791104286987">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY" msgid="6432126539782267026">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ENTRY" msgid="1730510161529488920">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="3369885925003346830">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ENTRY" msgid="9129139686191167829">"Introduceți codul PUK"</string>
-    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ENTRY" msgid="2869929685874615358">"Introduceți codul PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY" msgid="6730880791104286987">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY" msgid="6432126539782267026">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ENTRY" msgid="1730510161529488920">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ENTRY" msgid="3369885925003346830">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ENTRY" msgid="9129139686191167829">"Introdu codul PUK"</string>
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ENTRY" msgid="2869929685874615358">"Introdu codul PUK"</string>
     <string name="PERSOSUBSTATE_SIM_SPN_ENTRY" msgid="1238663472392741771">"Codul PIN de deblocare SPN"</string>
     <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ENTRY" msgid="3988705848553894358">"Codul PIN de deblocare privind furnizorul de servicii și Equivalent Home PLMN"</string>
     <string name="PERSOSUBSTATE_SIM_ICCID_ENTRY" msgid="6186770686690993200">"Codul PIN de deblocare ICCID"</string>
@@ -2287,8 +2287,8 @@
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activitate de fundal"</string>
     <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"O aplicație consumă bateria"</string>
     <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"O aplicație este încă activă"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> rulează în fundal. Atingeți pentru a gestiona utilizarea bateriei."</string>
-    <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> poate afecta autonomia bateriei. Atingeți pentru a examina aplicațiile active."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> rulează în fundal. Atinge pentru a gestiona utilizarea bateriei."</string>
+    <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> poate afecta autonomia bateriei. Atinge pentru a examina aplicațiile active."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificați aplicațiile active"</string>
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nu se poate accesa camera foto a telefonului de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nu se poate accesa camera foto a tabletei de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 2cceafc..71668fa 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Использовать блокировку экрана"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Чтобы продолжить, разблокируйте экран."</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Плотно прижмите палец к сканеру."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не удалось распознать отпечаток. Повторите попытку."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Не удалось распознать отпечаток пальца. Повторите попытку."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Очистите сканер отпечатков пальцев и повторите попытку."</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Очистите сканер и повторите попытку."</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Плотно прижмите палец к сканеру."</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Вы перемещали палец слишком медленно. Повторите попытку."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Попробуйте сохранить отпечаток другого пальца."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Слишком светло."</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Вы нажали кнопку питания."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Попробуйте изменить положение пальца."</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Каждый раз немного меняйте положение пальца."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицо распознано, нажмите кнопку \"Подтвердить\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Сканер недоступен"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не удалось сохранить отпечаток."</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Превышено время ожидания. Повторите попытку."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Время настройки отпечатка пальца истекло. Повторите попытку."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Операция с отпечатком отменена."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Операция с отпечатком пальца отменена пользователем."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Слишком много попыток. Повторите позже."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Слишком много попыток. Используйте другой способ разблокировки экрана."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Слишком много попыток. Используйте другой способ разблокировки экрана."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Повторите попытку."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Не удалось распознать отпечаток пальца. Повторите попытку."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Нет отсканированных отпечатков пальцев"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Обратитесь в сервисный центр."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Невозможно создать модель лица. Повторите попытку."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Слишком светло. Сделайте освещение менее ярким."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Недостаточно света"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Переместите телефон дальше от лица"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Переместите телефон ближе к лицу"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Переместите телефон выше"</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Запуск приложений."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Окончание загрузки..."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Вы нажали кнопку питания. Обычно это приводит к отключению экрана.\n\nПри добавлении отпечатка пальца слегка прикоснитесь к кнопке."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Нажмите, чтобы отключить экран"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Отключить экран"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Для завершения нужно отключить экран"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Отключить"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Продолжить сканирование отпечатка?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Вы нажали кнопку питания. Обычно это приводит к отключению экрана.\n\nЧтобы отсканировать отпечаток пальца, слегка прикоснитесь к кнопке."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Отключить экран"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Телевизор"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Динамики док-станции"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Внешнее устройство"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Наушники"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Система"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 06ac0f8..90b71de 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"තිර අගුල භාවිත කරන්න"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ඉදිරියට යාමට ඔබගේ තිර අගුල ඇතුළත් කරන්න"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"සංවේදකය මත තදින් ඔබන්න"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ඇඟිලි සලකුණ පිරිසැකසීමට නොහැකි විය. කරුණාකර නැවත උත්සාහ කරන්න."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ඇඟිලි සලකුණ හඳුනා ගත නොහැක. නැවත උත්සාහ කරන්න."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ඇඟිලි සලකුණු සංවේදකය පිරිසිදු කර නැවත උත්සාහ කරන්න"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"සංවේදකය පිරිසිදු කර නැවත උත්සාහ කරන්න"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"සංවේදකය මත තදින් ඔබන්න"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ඇඟිල්ල වඩා සෙමෙන් ගෙන යන ලදි. කරුණාකර නැවත උත්සාහ කරන්න."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"තවත් ඇඟිලි සලකුණක් උත්සාහ කරන්න"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"දීප්තිය වැඩියි"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"බල එබීම අනාවරණය විය"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"සීරුමාරු කිරීම උත්සාහ කරන්න"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"එක් එක් අවස්ථාවේ ඔබගේ ඇඟිල්ලේ පිහිටීම මදක් වෙනස් කරන්න"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"මුහුණ සත්‍යාපනය කරන ලදී, කරුණාකර තහවුරු කරන්න ඔබන්න"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ඇඟිලි සලකුණු දෘඪාංගය ලද නොහැකිය."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ඇඟිලි සලකුණ පිහිටුවිය නොහැකිය"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"ඇඟිලි සලකුණු කාල නිමාව ළඟා විය. නැවත උත්සාහ කරන්න."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ඇඟිලි සලකුණු පිහිටුවීම කාලය නිමා විය. නැවත උත්සාහ කරන්න."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ඇඟිලි සලකුණු මෙහෙයුම අවලංගු කරන ලදී."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"පරිශීලක විසින් ඇඟිලි සලකුණු මෙහෙයුම අවසන් කරන ලදී."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"උත්සාහයන් ඉතා වැඩි ගණනකි. කරුණාකර පසුව නැවත උත්සාහ කරන්න."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"උත්සාහ ගණන ඉතා වැඩියි. ඒ වෙනුවට තිර අගුල භාවිත කරන්න."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"උත්සාහ ගණන ඉතා වැඩියි. ඒ වෙනුවට තිර අගුල භාවිත කරන්න."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"නැවත උත්සාහ කරන්න."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ඇඟිලි සලකුණ සැකසීමට නොහැක. නැවත උත්සාහ කරන්න."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ඇඟිලි සලකුණු ඇතුළත් කර නොමැත."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"අළුත්වැඩියා සැපයුම්කරුවෙකු බලන්න."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"ඔබගේ මුහුණු ආකෘතිය තැනිය නොහැකිය. නැවත උත්සාහ කරන්න."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"දීප්තිය වැඩියි. තවත් මඳ ආලෝකය උත්සාහ කරන්න."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"ප්‍රමාණවත් ආලෝකයක් නැත"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"දුරකථනය තවත් ඈතට ගෙන යන්න"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"දුරකථනය තවත් සමීපයට ගෙන එන්න"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"දුරකථනය තවත් ඉහළට ගෙන යන්න"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"යෙදුම් ආරම්භ කරමින්."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ඇරඹුම අවසාන කරමින්."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"ඔබ බල බොත්තම එබුවේය — සාමාන්‍යයෙන් මෙය තිරය ක්‍රියාවිරහිත කරයි.\n\nඔබගේ ඇඟිලි සලකුණ පිහිටුවන අතරතුර සැහැල්ලුවෙන් තට්ටු කිරීමට උත්සාහ කරන්න."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"තිරය අක්‍රිය කිරීමට තට්ටු කරන්න"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"තිරය අක්‍රිය කරන්න"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"පිහිටුවීම නිම කිරීමට, තිරය අක්‍රිය කරන්න"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ක්‍රියාවිරහිත කරන්න"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"ඔබගේ ඇඟිලි සලකුණ සත්‍යාපනය දිගටම කරන්නද?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"ඔබ බල බොත්තම එබුවේය — සාමාන්‍යයෙන් මෙය තිරය ක්‍රියාවිරහිත කරයි.\n\nඔබගේ ඇඟිලි සලකුණ සත්‍යාපනය කිරීමට සැහැල්ලුවෙන් තට්ටු කිරීමට උත්සාහ කරන්න."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"තිරය අක්‍රිය කරන්න"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"රූපවාහිනී"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"දුරකථනය"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"නාදක ඩොක් කරන්න"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"බාහිර උපාංගය"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ඉස් බණු"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"පද්ධතිය"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index cdc6829..121e410 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použiť zámku obrazovky"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Pokračujte zadaním zámky obrazovky"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pevne pridržte senzor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Odtlačok prsta sa nepodarilo spracovať. Skúste to znova."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Odtlačok prsta sa nedá rozpoznať. Skúste to znova."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistite senzor odtlačkov prstov a skúste to znova"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistite senzor a skúste to znova"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevne pridržte senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pohli ste prstom príliš pomaly. Skúste to znova."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Vyskúšajte iný odtlačok prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Príliš jasno"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Bolo zistené stlačenie vypínača"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Vyskúšajte upraviť"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Zakaždým trocha zmeňte pozíciu prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Tvár bola overená, stlačte tlačidlo potvrdenia"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardvér na snímanie odtlačku prsta nie je k dispozícii"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Odtlačok prsta sa nedá nastaviť"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Časový limit rozpoznania odtlačku prsta vypršal. Skúste to znova."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Nastavenie odtlačku prsta vypršalo. Skúste to znova."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operácia týkajúca sa odtlačku prsta bola zrušená"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Overenie odtlačku prsta zrušil používateľ."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Príliš veľa pokusov. Skúste to neskôr."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Príliš veľa pokusov. Použite radšej zámku obrazovky."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Príliš veľa pokusov. Použite radšej zámku obrazovky."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Skúste to znova"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Odtlačok prsta sa nedá spracovať. Skúste to znova."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neregistrovali ste žiadne odtlačky prstov."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Navštívte poskytovateľa opráv."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Model tváre sa nedá vytvoriť. Skúste to znova."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Príliš veľa svetla. Skúste jemnejšie osvetlenie."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nie je dostatok svetla"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Oddiaľte telefón"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Priblížte telefón"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Posuňte telefón vyššie"</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Prebieha spúšťanie aplikácií."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Prebieha dokončovanie spúšťania."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Stlačili ste vypínač. Obvykle tým vypnete obrazovku.\n\nPri nastavovaní odtlačku prsta skúste klepnúť jemne."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Klepnutím vypnite obrazovku"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Vypnúť obrazovku"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Nastavovanie ukončíte vypnutím obrazovky"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Vypnúť"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Pokračovať v overovaní odtlačku prsta?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Stlačili ste vypínač. Obvykle tým vypnete obrazovku.\n\nAk chcete overiť odtlačok prsta, skúste klepnúť jemne."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Vypnúť obrazovku"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Televízor"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefón"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Reproduktory doku"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Externé zariadenie"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Slúchadlá"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Systém"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 6da07f8..8fc73ce 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Uporaba odklepanja s poverilnico"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Odklenite zaslon, če želite nadaljevati."</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Prst dobro pridržite na tipalu."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Prstnega odtisa ni bilo mogoče obdelati. Poskusite znova."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Prstnega odtisa ni mogoče prepoznati. Poskusite znova."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Očistite tipalo prstnih odtisov in poskusite znova."</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Očistite tipalo in poskusite znova."</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Prst dobro pridržite na tipalu."</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Prepočasen premik prsta. Poskusite znova."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Poskusite z drugim prstnim odtisom."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvetlo je."</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Zaznan je bil pritisk gumba za vklop."</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Poskusite popraviti položaj prsta."</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Vsakič nekoliko spremenite položaj prsta."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Pristnost obraza je preverjena. Pritisnite gumb »Potrdi«."</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Strojna oprema za prstne odtise ni na voljo."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Prstnega odtisa ni mogoče nastaviti."</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Dosežena časovna omejitev za prstni odtis. Poskusite znova."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Čas za nastavitev prstnega odtisa je potekel. Poskusite znova."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Dejanje s prstnim odtisom je bilo preklicano."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Dejanje s prstnim odtisom je preklical uporabnik."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Preveč poskusov. Poskusite znova pozneje."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Preveč poskusov. Odklenite z načinom za zaklepanje zaslona."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Preveč poskusov. Odklenite z zaklepanjem zaslona."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Poskusite znova."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Prstnega odtisa ni mogoče obdelati. Poskusite znova."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ni registriranih prstnih odtisov."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Obiščite ponudnika popravil."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Modela obraza ni mogoče ustvariti. Poskusite znova."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Presvetlo. Poskusite z blažjo osvetlitvijo."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Premalo svetlobe"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Telefon nekoliko odmaknite."</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Bolj približajte telefon."</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Telefon premaknite višje."</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Zagon aplikacij."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Dokončevanje zagona."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Pritisnili ste gumb za vklop, s čimer običajno izklopite zaslon.\n\nPoskusite se narahlo dotakniti med nastavljanjem prstnega odtisa."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Dotaknite se za izklop zaslona"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Izklopi zaslon"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Za končanje nastavitve izklopite zaslon"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Izklopi"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Želite nadaljevati preverjanje prstnega odtisa?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Pritisnili ste gumb za vklop, s čimer običajno izklopite zaslon.\n\nZa preverjanje prstnega odtisa se poskusite narahlo dotakniti."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Izklopi zaslon"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Televizor"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Zvočniki stojala"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Zunanja naprava"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Slušalke"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 587215a..77fe612 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Përdor kyçjen e ekranit"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Fut kyçjen e ekranit për të vazhduar"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Shtyp fort te sensori"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Gjurma e gishtit nuk mund të përpunohej. Provo përsëri."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Nuk mund ta dallojë gjurmën e gishtit. Provo përsëri."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Pastro sensorin e gjurmës së gishtit dhe provo sërish"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Pastro sensorin dhe provo sërish"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Shtyp fort te sensori"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Gishti lëvizi shumë ngadalë. Provo përsëri."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Provo një gjurmë gishti tjetër"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Me shumë ndriçim"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"U zbulua shtypja e \"Energjisë\""</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Provo ta rregullosh"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ndrysho pak pozicionin e gishtit çdo herë"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Fytyra u vërtetua, shtyp \"Konfirmo\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardueri i gjurmës së gishtit nuk mundësohet."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Nuk mund të konfigurohet gjurma e gishtit"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Koha e veprimit për gjurmën e gishtit skadoi. Provo përsëri."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Konfigurimi i gjurmës së gishtit skadoi. Provo përsëri."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operacioni i gjurmës së gishtit u anulua."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Veprimi i gjurmës së gishtit u anulua nga përdoruesi."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Keni bërë shumë tentativa. Provo përsëri më vonë."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Shumë përpjekje. Përdor më mirë kyçjen e ekranit."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Shumë përpjekje. Përdor më mirë kyçjen e ekranit."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Provo përsëri."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Gjurma e gishtit nuk mund të përpunohet. Provo përsëri."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nuk ka asnjë gjurmë gishti të regjistruar."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Vizito një ofrues të shërbimit të riparimit."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Modeli i fytyrës nuk krijohet. Provo sërish."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Me shumë ndriçim. Provo një ndriçim më të butë."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Nuk ka dritë të mjaftueshme"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Lëvize telefonin më larg"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Lëvize telefonin më afër"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Lëvize telefonin më lart"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Aplikacionet e fillimit."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Po përfundon nisjen."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Shtype butonin e energjisë — zakonisht, kjo e fik ekranin.\n\nProvo të trokasësh lehtë ndërkohë që konfiguron gjurmën e gishtit."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Trokit për ta fikur ekranin"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Fik ekranin"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Përfundo konfigurimin; fik ekranin"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Çaktivizo"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Të vazhdohet verifikimi i gjurmës?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Shtype butonin e energjisë — zakonisht, kjo e fik ekranin.\n\nProvo të trokasësh lehtë për të verifikuar gjurmën e gishtit."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Fik ekranin"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Televizori"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Altoparlantët e stacionit"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Pajisje e jashtme"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Kufjet"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistemi"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 2acaf5c..c38c771 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -584,13 +584,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користите закључавање екрана"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Употребите закључавање екрана да бисте наставили"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Јако притисните сензор"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Није успела обрада отиска прста. Пробајте поново."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Препознавање отиска прста није успело. Пробајте поново."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Обришите сензор за отисак прста и пробајте поново"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Обришите сензор и пробајте поново"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Јако притисните сензор"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Превише споро сте померили прст. Пробајте поново."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте са другим отиском прста"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Превише је светло"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Откривен је притисак дугмета за укључивање"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да прилагодите"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Сваки пут помало промените положај прста"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -602,12 +603,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лице је потврђено. Притисните Потврди"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Хардвер за отиске прстију није доступан."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Подешавање отиска прста није успело"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Временско ограничење за отисак прста је истекло. Пробајте поново."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Време за подешавање отиска прста је истекло. Пробајте поново."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Радња са отиском прста је отказана."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Корисник је отказао радњу са отиском прста."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Превише покушаја. Пробајте поново касније."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Превише покушаја. Користите закључавање екрана уместо тога."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Превише покушаја. Користите закључавање екрана уместо тога."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Пробајте поново."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Обрађивање отиска прста није успело. Пробајте поново."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Није регистрован ниједан отисак прста."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
@@ -635,8 +636,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Посетите добављача за поправке."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Прављење модела лица није успело. Пробајте поново."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Превише је светло. Пробајте са слабијим осветљењем."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Нема довољно светла"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Удаљите телефон"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Приближите телефон"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Померите телефон нагоре"</string>
@@ -1250,8 +1250,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Покретање апликација."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Завршавање покретања."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Притиснули сте дугме за укључивање – тиме обично искључујете екран.\n\nПробајте лагано да додирнете док подешавате отисак прста."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Додирните да бисте искључили екран"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Искључи екран"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Завршите подешавање искључивањем екрана"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Искључи"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Настављате верификацију отиска прста?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Притиснули сте дугме за укључивање – тиме обично искључујете екран.\n\nПробајте лагано да додирнете да бисте верификовали отисак прста."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Искључи екран"</string>
@@ -1612,7 +1612,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ТВ"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Звучници базне станице"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Спољни уређај"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Слушалице"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Систем"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index a6c162a..e65231d 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Använd skärmlåset"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Fortsätt med hjälp av ditt skärmlås"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tryck på sensorn med ett stadigt tryck"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Det gick inte att bearbeta fingeravtrycket. Försök igen."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Fingeravtrycket kändes inte igen. Försök igen."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengör fingeravtryckssensorn och försök igen"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengör sensorn och försök igen"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tryck hårt på sensorn"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du rörde fingret för långsamt. Försök igen."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Testa ett annat fingeravtryck"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Det är för ljust"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Tryckning registrerades"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Testa att justera fingeravtrycket"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Flytta fingret lite varje gång"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet har autentiserats. Tryck på Bekräfta"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Det finns ingen maskinvara för fingeravtryck."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Det gick inte att konfigurera fingeravtryck"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Tidsgränsen för fingeravtrycket har uppnåtts. Försök igen."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingeravtryckskonfigurering nådde tidsgränsen. Försök igen."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingeravtrycksåtgärden avbröts."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeravtrycksåtgärden avbröts av användaren."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Du har gjort för många försök. Försök igen senare."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"För många försök. Använd låsskärmen i stället."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"För många försök. Använd låsskärmen i stället."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Försök igen."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Det gick inte att bearbeta fingeravtrycket. Försök igen."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Inga fingeravtryck har registrerats."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Besök ett reparationsställe."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Ansiktsmodellen kunde inte skapas. Försök igen."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Det är för ljust. Testa lägre belysning."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"För lite ljus"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Flytta telefonen längre bort"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"För telefonen närmare"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Höj telefonen"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Appar startas."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Uppgraderingen är klar."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Du tryckte på av/på-knappen, vilket vanligtvis stänger av skärmen.\n\nTesta att trycka lätt när du konfigurerar fingeravtrycket."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Tryck för att stänga av skärmen"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Stäng av skärmen"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Stäng av skärmen för att avbryta"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Stäng av"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Vill du verifiera ditt fingeravtryck?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Du tryckte på av/på-knappen, vilket vanligtvis stänger av skärmen.\n\nTesta att trycka lätt för att verifiera ditt fingeravtryck."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Stäng av skärmen"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Mobil"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dockningsstationens högtalare"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Extern enhet"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Hörlurar"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index b17f58e..8ec29b3 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Tumia mbinu ya kufunga skrini"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Weka mbinu yako ya kufunga skrini ili uendelee"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Bonyeza kwa uthabiti kwenye kitambuzi"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Imeshindwa kuchakata alama ya kidole. Tafadhali jaribu tena."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Imeshindwa kutambua alama ya kidole. Jaribu tena."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Safisha kitambua alama ya kidole kisha ujaribu tena"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Safisha kitambuzi kisha ujaribu tena"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Bonyeza kwa nguvu kwenye kitambuzi"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Kidole kilisogezwa polepole zaidi. Tafadhali jaribu tena."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Jaribu alama nyingine ya kidole"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Inang\'aa mno"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Kubonyeza kitufe cha kuwasha/kuzima kumetambuliwa"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Jaribu kurekebisha"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Badilisha mkao wa kidole chako kiasi kila wakati"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Uso umethibitishwa, tafadhali bonyeza thibitisha"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Maunzi ya alama ya kidole hayapatikani."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Imeshindwa kuweka mipangilio ya alama ya kidole"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Muda wa kuweka alama ya kidole umekwisha. Jaribu tena."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Muda wa kuweka alama ya kidole umeisha. Jaribu tena."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Mchakato wa alama ya kidole umeghairiwa."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Mtumiaji ameghairi uthibitishaji wa alama ya kidole."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Majaribio mengi mno. Jaribu tena baadaye."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Umejaribu mara nyingi mno. Badala yake, tumia mbinu ya kufunga skrini."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Umejaribu mara nyingi mno. Badala yake, tumia mbinu ya kufunga skrini."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Jaribu tena."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Imeshindwa kutambua alama ya kidole. Jaribu tena."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hakuna alama za vidole zilizojumuishwa."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Tembelea mtoa huduma za urekebishaji."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Imeshindwa kuunda muundo wa uso wako. Jaribu tena."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Inang\'aa mno. Jaribu mwangaza hafifu"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Hakuna mwangaza wa kutosha"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Sogeza simu mbali kiasi"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Sogeza simu karibu"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Sogeza simu juu zaidi"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Programu zinaanza"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Inamaliza kuwasha."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Umebonyeza kitufe cha kuwasha/kuzima — kwa kawaida, hali hii huzima skrini.\n\nJaribu kugusa taratibu unapoweka mipangilio ya alama ya kidole chako."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Gusa ili uzime skrini"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Zima skrini"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Kusitisha kuweka alama ya kidole, zima skrini"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Zima"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Utaendelea kuthibitisha alama ya kidole chako?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Umebonyeza kitufe cha kuwasha/kuzima — kwa kawaida, hali hii huzima skrini.\n\nJaribu kugusa taratibu ili uthibitishe alama ya kidole chako."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Zima skrini"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Runinga"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Simu"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Vipasa sauti vya kituo"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Kifaa cha Nje"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Vipokeasauti"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Mfumo"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 6a7973e..ea5227c 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"திரைப் பூட்டைப் பயன்படுத்து"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"தொடர்வதற்கு உங்கள் திரைப் பூட்டை உள்ளிடுங்கள்"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"சென்சாரின் மீது நன்றாக அழுத்தவும்"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"கைரேகையைச் செயலாக்க முடியவில்லை. மீண்டும் முயலவும்."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"கைரேகையை அடையாளம் காண முடியவில்லை. மீண்டும் முயலவும்."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"கைரேகை சென்சாரைச் சுத்தம் செய்துவிட்டு மீண்டும் முயலவும்"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"சென்சாரைச் சுத்தம் செய்துவிட்டு மீண்டும் முயலவும்"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"சென்சாரின் மீது நன்றாக அழுத்தவும்"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"விரலை மிகவும் மெதுவாக நகர்த்திவிட்டீர்கள். மீண்டும் முயற்சிக்கவும்."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"வேறு கைரேகையை முயலவும்"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"அதிக வெளிச்சமாக உள்ளது"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"பவர் பட்டனை அழுத்தியது கண்டறியப்பட்டது"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"விரலைச் சரியாக வைக்கவும்"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ஒவ்வொரு முறையும் விரலின் நிலையைச் சிறிதளவு மாற்றுங்கள்"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"முகம் அங்கீகரிக்கப்பட்டது. ’உறுதிப்படுத்துக’ என்பதை அழுத்துக"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"கைரேகை வன்பொருள் இல்லை."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"கைரேகையை அமைக்க முடியவில்லை"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"கைரேகைக்கான நேரம் முடிந்தது. மீண்டும் முயலவும்."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"கைரேகை அமைவுக்கான நேரம் முடிந்துவிட்டது. மீண்டும் முயலவும்."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"கைரேகை செயல்பாடு ரத்துசெய்யப்பட்டது."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"பயனர், கைரேகை உறுதிப்படுத்துதலை ரத்துசெய்தார்."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"அதிகமான முயற்சிகள். பிறகு முயற்சிக்கவும்."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"பலமுறை முயன்றுவிட்டீர்கள். இதற்குப் பதிலாகத் திரைப்பூட்டைப் பயன்படுத்தவும்."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"பலமுறை முயன்றுவிட்டீர்கள். இதற்குப் பதிலாகத் திரைப்பூட்டைப் பயன்படுத்தவும்."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"மீண்டும் முயற்சிக்கவும்."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"கைரேகையைச் செயலாக்க முடியவில்லை. மீண்டும் முயலவும்."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"கைரேகைப் பதிவுகள் எதுவும் இல்லை."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"பழுதுபார்ப்புச் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"முகத் தோற்றம் பதிவாகவில்லை. மீண்டும் முயலவும்."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"அதிக ஒளிர்வு. மிதமான ஒளியில் முயலவும்."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"போதிய வெளிச்சம் இல்லை"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"மொபைலை முகத்தில் இருந்து தள்ளிப் பிடிக்கவும்"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"மொபைலை அருகில் நகர்த்தவும்"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"மொபைலை மேலே நகர்த்தவும்"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ஆப்ஸ் தொடங்கப்படுகின்றன."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"துவக்குதலை முடிக்கிறது."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"நீங்கள் பவர் பட்டனை அழுத்தியுள்ளீர்கள் — வழக்கமாக இது திரையை ஆஃப் செய்யும்.\n\nஉங்கள் கைரேகையை அமைக்கும்போது மெதுவாகத் தொடுங்கள்."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"திரையை அணைக்க தட்டவும்"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"திரையை அணை"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"அமைவை நிறைவுசெய்ய திரையை முடக்குங்கள்"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"முடக்கு"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"கைரேகைச் சரிபார்ப்பைத் தொடரவா?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"நீங்கள் பவர் பட்டனை அழுத்தியுள்ளீர்கள் — வழக்கமாக இது திரையை ஆஃப் செய்யும்.\n\nஉங்கள் கைரேகையைச் சரிபார்க்க மெதுவாகத் தொடுங்கள்."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"திரையை ஆஃப் செய்"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"டிவி"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ஃபோன்"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"மொபைல் வைக்கும் கருவியின் ஸ்பீக்கர்கள்"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"வெளிப்புறச் சாதனம்"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ஹெட்ஃபோன்கள்"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"சிஸ்டம்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 8c53b13..66dcac6 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"కొనసాగించడానికి మీ స్క్రీన్ లాక్‌ను ఎంటర్ చేయండి"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"సెన్సార్ మీద గట్టిగా నొక్కండి"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"వేలిముద్రను ప్రాసెస్ చేయడం సాధ్యపడలేదు. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"వేలిముద్రను గుర్తించడం సాధ్యపడదు. మళ్లీ ట్రై చేయండి."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"వేలిముద్ర సెన్సార్‌ను క్లీన్ చేసి, మళ్లీ ట్రై చేయండి"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"సెన్సార్‌ను క్లీన్ చేసి, మళ్లీ ట్రై చేయండి"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"సెన్సార్ మీద గట్టిగా నొక్కండి"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"వేలిని చాలా నెమ్మదిగా కదిలించారు. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"మరొక వేలిముద్రను ట్రై చేయండి"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"వెలుతురు అధికంగా ఉంది"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"పవర్ బటన్ కనుగొనబడింది"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"సర్దుబాటు చేయడానికి ట్రై చేయండి"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ప్రతిసారీ మీ వేళ్ల స్థానాన్ని కొద్దిగా మార్చండి"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ముఖం ప్రమాణీకరించబడింది, దయచేసి ధృవీకరించును నొక్కండి"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"వేలిముద్ర హార్డ్‌వేర్ అందుబాటులో లేదు."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"వేలిముద్రను సెటప్ చేయడం సాధ్యం కాదు"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"వేలిముద్ర గడువు సమయం చేరుకుంది. మళ్లీ ప్రయత్నించండి."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"వేలిముద్ర సెటప్ సమయం ముగిసింది. మళ్లీ ట్రై చేయండి."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"వేలిముద్ర యాక్టివిటీ రద్దయింది."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"వేలిముద్ర చర్యని వినియోగదారు రద్దు చేశారు."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"చాలా ఎక్కువ ప్రయత్నాలు చేశారు. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"చాలా ఎక్కువ సార్లు ప్రయత్నించారు. బదులుగా స్క్రీన్ లాక్‌ను ఉపయోగించండి."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"చాలా ఎక్కువ సార్లు ప్రయత్నించారు. బదులుగా స్క్రీన్ లాక్‌ను ఉపయోగించండి."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"మళ్లీ ప్రయత్నించండి."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"వేలిముద్రను ప్రాసెస్ చేయడం సాధ్యపడదు. మళ్లీ ట్రై చేయండి."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"వేలిముద్రలు నమోదు చేయబడలేదు."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"రిపెయిర్ ప్రొవైడర్‌ను సందర్శించండి."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"మీ ఫేస్‌మోడల్ క్రియేషన్ కుదరదు. మళ్లీ ట్రై చేయండి."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"వెలుతురు అధికంగా ఉంది. తక్కువ ఉండేలా చూడండి."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"తగిన కాంతి లేదు"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ఫోన్‌ను కాస్త దూరంగా జరపండి"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ఫోన్‌ను దగ్గరగా పట్టుకోండి"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ఫోన్‌ను పైకి పట్టుకోండి"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"యాప్‌లను ప్రారంభిస్తోంది."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"బూట్‌ను ముగిస్తోంది."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"మీరు పవర్ బటన్‌ను నొక్కారు — ఇది సాధారణంగా స్క్రీన్‌ను ఆఫ్ చేస్తుంది.\n\nమీ వేలిముద్రను సెటప్ చేస్తున్నప్పుడు తేలికగా ట్యాప్ చేయడానికి ట్రై చేయండి."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"స్క్రీన్‌ను ఆఫ్ చేయడానికి ట్యాప్ చేయండి"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"స్క్రీన్‌ను ఆఫ్ చేయి"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"సెటప్ ముగించడానికి, స్క్రీన్‌ను ఆఫ్ చేయి"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ఆఫ్ చేయండి"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"మీ వేలిముద్ర వెరిఫై‌ను కొనసాగించాలా?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"మీరు పవర్ బటన్‌ను నొక్కారు — ఇది సాధారణంగా స్క్రీన్‌ను ఆఫ్ చేస్తుంది.\n\nమీ వేలిముద్రను వెరిఫై చేయడానికి తేలికగా ట్యాప్ చేయడం ట్రై చేయండి."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"స్క్రీన్‌ను ఆఫ్ చేయి"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"టీవీ"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ఫోన్"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"డాక్ స్పీకర్‌లు"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"బాహ్య పరికరం"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"హెడ్‌ఫోన్‌లు"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"సిస్టమ్"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 7826774..0d1ea17 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ใช้การล็อกหน้าจอ"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ป้อนข้อมูลการล็อกหน้าจอเพื่อดำเนินการต่อ"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"กดเซ็นเซอร์ให้แน่น"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ประมวลผลลายนิ้วมือไม่ได้ โปรดลองอีกครั้ง"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ไม่รู้จักลายนิ้วมือ โปรดลองอีกครั้ง"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ทำความสะอาดเซ็นเซอร์ลายนิ้วมือแล้วลองอีกครั้ง"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ทำความสะอาดเซ็นเซอร์แล้วลองอีกครั้ง"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"กดเซ็นเซอร์ให้แน่น"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"นิ้วเคลื่อนที่ช้าเกินไป โปรดลองอีกครั้ง"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ลองลายนิ้วมืออื่น"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"สว่างเกินไป"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ตรวจพบว่ามีการกดปุ่มเปิด/ปิด"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ลองปรับการวางนิ้ว"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"เปลี่ยนตำแหน่งของนิ้วเล็กน้อยไปเรื่อยๆ ทุกครั้ง"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ตรวจสอบสิทธิ์ใบหน้าแล้ว โปรดกดยืนยัน"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ฮาร์ดแวร์ลายนิ้วมือไม่พร้อมใช้งาน"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"ตั้งค่าลายนิ้วมือไม่ได้"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"หมดเวลาใช้ลายนิ้วมือแล้ว โปรดลองอีกครั้ง"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"การตั้งค่าลายนิ้วมือหมดเวลา โปรดลองอีกครั้ง"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"ยกเลิกการทำงานของลายนิ้วมือ"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ผู้ใช้ยกเลิกการทำงานของลายนิ้วมือ"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"ดำเนินการหลายครั้งเกินไป ลองอีกครั้งในภายหลัง"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"ลองหลายครั้งเกินไป ใช้การล็อกหน้าจอแทน"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"ลองหลายครั้งเกินไป ใช้การล็อกหน้าจอแทน"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ลองอีกครั้ง"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"ประมวลผลลายนิ้วมือไม่ได้ โปรดลองอีกครั้ง"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ไม่มีลายนิ้วมือที่ลงทะเบียน"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"โปรดติดต่อผู้ให้บริการซ่อม"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"สร้างรูปแบบใบหน้าไม่ได้ โปรดลองอีกครั้ง"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"สว่างเกินไป ลองหาตำแหน่งที่แสงน้อยกว่านี้"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"แสงสว่างไม่เพียงพอ"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"ถือโทรศัพท์ให้ห่างกว่านี้"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"ถือโทรศัพท์ให้ใกล้กว่านี้"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"ยกโทรศัพท์ให้สูงขึ้น"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"กำลังเริ่มต้นแอปพลิเคชัน"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"เสร็จสิ้นการบูต"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"คุณกดปุ่มเปิด/ปิดซึ่งโดยปกติจะเป็นการปิดหน้าจอ\n\nลองแตะเบาๆ ขณะตั้งค่าลายนิ้วมือ"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"แตะเพื่อปิดหน้าจอ"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"ปิดหน้าจอ"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"ปิดหน้าจอเพื่อสิ้นสุดการตั้งค่า"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ปิด"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"ยืนยันลายนิ้วมือต่อไหม"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"คุณกดปุ่มเปิด/ปิดซึ่งโดยปกติจะเป็นการปิดหน้าจอ\n\nลองแตะเบาๆ เพื่อยืนยันลายนิ้วมือ"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"ปิดหน้าจอ"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"ทีวี"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"โทรศัพท์"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ลำโพงแท่นชาร์จ"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"อุปกรณ์ภายนอก"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"หูฟัง"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"ระบบ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index e9d17a9..84f6112 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gumamit ng lock ng screen"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ilagay ang iyong lock ng screen para magpatuloy"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pumindot nang madiin sa sensor"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Hindi maproseso ang fingerprint. Pakisubukan ulit."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Hindi makilala ang fingerprint. Subukan ulit."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Linisin ang sensor para sa fingerprint at subukan ulit"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Linisin ang sensor at subukan ulit"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pumindot nang madiin sa sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Masyadong mabagal ang paggalaw ng daliri. Pakisubukan ulit."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Sumubok ng ibang fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Masyadong maliwanag"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"May na-detect na pagpindot sa Power"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Subukang isaayos"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Bahagyang baguhin ang posisyon ng iyong daliri sa bawat pagkakataon"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Na-authenticate ang mukha, pakipindot ang kumpirmahin"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hindi available ang hardware na ginagamitan ng fingerprint."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Hindi ma-set up ang fingerprint"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Nag-time out ang fingerprint. Subukang muli."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Nag-time out ang pag-set up ng fingerprint. Subukan ulit."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Nakansela ang operasyong ginagamitan ng fingerprint."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Kinansela ng user ang operasyon sa fingerprint."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Napakaraming pagtatangka. Subukan ulit sa ibang pagkakataon."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Masyadong maraming pagsubok. Gamitin na lang ang lock ng screen."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Masyadong maraming pagsubok. Gamitin na lang ang lock ng screen."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Subukang muli."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Hindi maproseso ang fingerprint. Subukan ulit."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Walang naka-enroll na fingerprint."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Bumisita sa provider ng pag-aayos."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Hindi magawa ang iyong face model. Subukan ulit."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Masyadong maliwanag. Subukang bawasan ang liwanag."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Hindi sapat ang liwanag"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Ilayo pa ang telepono"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Ilapit pa ang telepono"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Itaas pa ang telepono"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Sinisimulan ang apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Pagtatapos ng pag-boot."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Pinindot mo ang power button — karaniwan nitong ino-off ang screen.\n\nSubukang i-tap habang sine-set up ang iyong fingerprint."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Mag-tap para i-off ang screen"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"I-off ang screen"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"I-off ang screen para tapusin ang setup"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"I-off"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Magpatuloy sa pag-verify ng fingerprint?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Pinindot mo ang power button — karaniwan nitong ino-off ang screen.\n\nSubukang i-tap para i-verify ang iyong fingerprint."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"I-off ang screen"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telepono"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Mga speaker ng dock"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"External na Device"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Mga Headphone"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"System"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 762b731..e0c1585 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran kilidi kullan"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Devam etmek için ekran kilidinizi girin"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Sensöre sıkıca bastırın"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Parmak izi işlenemedi. Lütfen tekrar deneyin."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Parmak izi tanınamadı. Tekrar deneyin."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Parmak izi sensörünü temizleyip tekrar deneyin"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensörü temizleyip tekrar deneyin"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Sensöre sıkıca bastırın"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Parmak hareketi çok yavaştı. Lütfen tekrar deneyin."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Başka bir parmak izi deneyin"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Çok parlak"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Güç düğmesine basma algılandı"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ayarlamayı deneyin"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Her defasında parmağınızın konumunu biraz değiştirin"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yüz kimliği doğrulandı, lütfen onayla\'ya basın"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Parmak izi donanımı kullanılamıyor."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Parmak izi ayarlanamıyor"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Parmak izi için zaman aşımı oluştu. Tekrar deneyin."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Parmak izi kurulumu zaman aşımına uğradı. Tekrar deneyin."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Parmak izi işlemi iptal edildi."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Parmak izi işlemi kullanıcı tarafından iptal edildi."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Çok fazla deneme yapıldı. Daha sonra tekrar deneyin."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Çok fazla deneme yapıldı. Bunun yerine ekran kilidini kullanın."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Çok fazla deneme yapıldı. Bunun yerine ekran kilidini kullanın."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Tekrar deneyin."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Parmak izi işlenemiyor. Tekrar deneyin."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Parmak izi kaydedilmedi."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Bir onarım hizmeti sağlayıcıyı ziyaret edin."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Yüzünüzün modeli oluşturulamıyor. Tekrar deneyin."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Çok parlak. Parlaklığı daha az bir ışıklandırma deneyin."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Yeterli ışık yok"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Telefonu uzaklaştırın"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Telefonu yaklaştırın"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Telefonu daha yukarı kaldırın"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Uygulamalar başlatılıyor"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Açılış tamamlanıyor."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Güç düğmesine bastınız. Bu düğmeye basıldığında genellikle ekran kapanır.\n\nParmak izinizi tanımlarken hafifçe dokunmayı deneyin."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Ekranı kapatmak için dokunun"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Ekranı kapat"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Ekranı kapatarak kurulumu sonlandırın"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Kapat"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Parmak izi doğrulamaya devam edilsin mi?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Güç düğmesine bastınız. Bu düğmeye basıldığında genellikle ekran kapanır.\n\nParmak izinizi doğrulamak için hafifçe dokunmayı deneyin."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Ekranı kapat"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Yuva hoparlörleri"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Harici Cihaz"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Kulaklıklar"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistem"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 730cfac..c76d6a3 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -585,13 +585,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Доступ розблокуванням екрана"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Щоб продовжити, введіть дані для розблокування екрана"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Міцно притисніть палець до сканера"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не вдалось обробити відбиток пальця. Повторіть спробу."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Відбиток пальця не розпізнано. Повторіть спробу."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Очистьте сканер відбитків пальців і повторіть спробу"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Очистьте сканер і повторіть спробу"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Міцно притисніть палець до сканера"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Ви провели пальцем надто повільно. Повторіть спробу."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Спробуйте інший відбиток пальця"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Надто яскраво"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Виявлено натискання кнопки живлення"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Спробуйте відкоригувати відбиток пальця"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Щоразу трохи змінюйте положення пальця"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -603,12 +604,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Обличчя автентифіковано. Натисніть \"Підтвердити\""</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Сканер відбитків пальців недоступний."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Не вдалося створити відбиток пальця"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Час очікування відбитка пальця минув. Повторіть спробу."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Час очікування для налаштування відбитка пальця минув. Повторіть спробу."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Дію з відбитком пальця скасовано."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Користувач скасував дію з відбитком пальця."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Забагато спроб. Спробуйте пізніше."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Забагато спроб. Використайте натомість розблокування екрана."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Забагато спроб. Використайте натомість розблокування екрана."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Повторіть спробу."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Не вдалось обробити відбиток пальця. Повторіть спробу."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Відбитки пальців не зареєстровано."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
@@ -636,8 +637,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Зверніться до постачальника послуг із ремонту."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Модель обличчя не створено. Повторіть спробу."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Занадто яскраво. Потрібно менше світла."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Замало світла"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Тримайте телефон далі від обличчя"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Тримайте телефон ближче до обличчя"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Підніміть телефон вище"</string>
@@ -1251,8 +1251,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Запуск програм."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Завершення завантаження."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Ви натиснули кнопку живлення – зазвичай після цього вимикається екран.\n\nЩоб зареєструвати відбиток пальця, спробуйте лише злегка торкнутися датчика."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Натисніть, щоб вимкнути екран"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Вимкнути екран"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Щоб завершити, вимкніть екран"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Вимкнути"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Продовжити підтвердження відбитка?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Ви натиснули кнопку живлення – зазвичай після цього вимикається екран.\n\nЩоб підтвердити відбиток пальця, спробуйте лише злегка торкнутися датчика."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Вимкнути екран"</string>
@@ -1613,7 +1613,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"Телевізор"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Телефон"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Динаміки док-станції"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Зовнішній пристрій"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Навушники"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Система"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 6fa0071..c589440 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"اسکرین لاک استعمال کریں"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"جاری رکھنے کے لیے اپنا اسکرین لاک درج کریں"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"سینسر پر اچھی طرح دبائیں"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"فنگر پرنٹ پر کارروائی نہیں کی جا سکی۔ براہ کرم دوبارہ کوشش کریں۔"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"فنگر پرنٹ کی شناخت نہیں کی جا سکی۔ دوبارہ کوشش کریں۔"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"فنگر پرنٹ سینسر صاف کریں اور دوبارہ کوشش کریں"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"سینسر صاف کریں اور دوبارہ کوشش کریں"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"سینسر پر اچھی طرح دبائیں"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"انگلی کو بہت آہستہ ہٹایا گیا۔ براہ کرم دوبارہ کوشش کریں۔"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"دوسرا فنگر پرنٹ آزمائیں"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"کافی روشنی ہے"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"پاور پریس کا پتہ چلا"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ایڈجسٹ کرنے کی کوشش کریں"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ہر بار اپنی انگلی کی پوزیشن کو تھوڑا تبدیل کریں"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چہرے کی تصدیق ہو گئی، براہ کرم \'تصدیق کریں\' کو دبائيں"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"فنگر پرنٹ ہارڈ ویئر دستیاب نہیں ہے۔"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"فنگر پرنٹ کو سیٹ اپ نہیں کیا جا سکا"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"فنگر پرنٹ کی میعاد ختم ہوگئی۔ دوبارہ کوشش کریں۔"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"فنگر پرنٹ کے سیٹ اپ کا وقت ختم ہو گیا۔ دوبارہ کوشش کریں۔"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"فنگر پرنٹ کی کارروائی منسوخ ہوگئی۔"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"صارف نے فنگر پرنٹ کی کارروائی منسوخ کر دی۔"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"کافی زیادہ کوششیں کی گئیں۔ بعد میں دوبارہ کوشش کریں۔"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"کافی زیادہ کوششیں۔ اس کے بجائے اسکرین لاک کا استعمال کریں۔"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"کافی زیادہ کوششیں۔ اس کے بجائے اسکرین لاک کا استعمال کریں۔"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"دوبارہ کوشش کریں۔"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"فنگر پرنٹ پروسیس نہیں ہو سکتا۔ دوبارہ کوشش کریں۔"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"کوئی فنگر پرنٹ مندرج شدہ نہیں ہے۔"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ایک مرمت فراہم کنندہ کو ملاحظہ کریں۔"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"آپکے چہرے کا ماڈل تخلیق نہیں ہو سکا۔ پھر کوشش کریں۔"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"کافی روشنی ہے۔ ہلکی روشنی میں آزمائیں۔"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"کافی روشنی نہیں ہے"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"فون کو تھوڑا دور کریں"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"فون کو تھوڑا قریب کریں"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"فون کو تھوڑا اوپر لے جائیں"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ایپس شروع ہو رہی ہیں۔"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"بوٹ مکمل ہو رہا ہے۔"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"آپ نے پاور بٹن دبایا — اس سے عام طور پر اسکرین آف ہو جاتی ہے۔\n\nاپنے فنگر پرنٹ کو سیٹ اپ کرنے کے دوران ہلکا سا تھپتھپانے کی کوشش کریں۔"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"اسکرین آف کرنے کیلئے تھپتھپائیں"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"اسکرین آف کریں"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"سیٹ اپ ختم کرنے کیلئے، اسکرین آف کریں"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"آف کریں"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"اپنے فنگر پرنٹ کی توثیق کرنا جاری رکھیں؟"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"آپ نے پاور بٹن دبایا — اس سے عام طور پر اسکرین آف ہو جاتی ہے۔\n\nاپنے فنگر پرنٹ کی توثیق کرنے کے لیے ہلکا سا تھپتھپانے کی کوشش کریں۔"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"اسکرین آف کریں"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"فون"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"ڈاک اسپیکرز"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"بیرونی آلہ"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"ہیڈ فونز"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"سسٹم"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index b9a0ae5..a0bcc98 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran qulfi"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ekran qulfini kiritish bilan davom eting"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Sensorni mahkam bosing"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmoq izi aniqlanmadi. Qaytadan urining."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Bu barmoq izi notanish. Qayta urining."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Barmoq izi skanerini tozalang va qayta urining"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensorni tozalang va qayta urining"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Sensorni mahkam bosing"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Barmoq juda sekin harakatlandi. Qayta urinib ko‘ring."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Boshqa barmoq izi bilan urining"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Juda yorqin"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Quvvat tugmasi bosildi"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Moslashga urining"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Barmoqni har safar biroz surib joylang"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yuzingiz aniqlandi, tasdiqlash uchun bosing"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Barmoq izi skaneri ish holatida emas."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Barmoq izi sozlanmadi"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Barmoq izini aniqlash vaqti tugab qoldi. Qayta urinib ko‘ring."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Barmoq izini sozlash vaqti tugadi. Qayta urining."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Barmoq izi tekshiruvi bekor qilindi."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Barmoq izi amali foydalanuvchi tomonidan bekor qilindi"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Urinishlar soni ko‘payib ketdi. Keyinroq qayta urinib ko‘ring."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Juda koʻp urinildi. Ekran qulfi orqali urining."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Juda koʻp urinildi. Ekran qulfi orqali urining."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Qayta urinib ko‘ring."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Barmoq izi tekshirilmadi. Qayta urining."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hech qanday barmoq izi qayd qilinmagan."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Xizmat koʻrsatish markaziga murojaat qiling."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Yuzingiz modeli yaratilmadi. Qayta urining."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Juda yorqin. Biroz soyaroq joy tanlang."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Yorugʻlik yetarli emas"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Telefonni biroz uzoqroq tuting"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Telefonni yaqinroq tuting"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Telefonni teparoq tuting"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Ilovalar ishga tushirilmoqda."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Tizimni yuklashni tugatish."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Quvvat tugmasini bosdingiz — bu odatda ekranni oʻchiradi.\n\nBarmoq izini qoʻshish vaqtida tugmaga yengilgina tegining."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Ekranni oʻchirish uchun bosing"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Ekranni oʻchirish"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Sozlashni yakunlash uchun ekranni oʻchiring"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Faolsizlantirish"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Barmoq izi tasdiqlashda davom etilsinmi?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Quvvat tugmasini bosdingiz. Bu odatda ekranni oʻchiradi.\n\nBarmoq izingizni tasdiqlash uchun tugmaga yengilgina tegining."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Ekranni oʻchirish"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Taglik karnaylar"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Tashqi qurilma"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Quloq karnaychalari"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Tizim"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ad4a3899..c94730a 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Dùng phương thức khóa màn hình"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Hãy nhập phương thức khóa màn hình của bạn để tiếp tục"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Nhấn chắc trên cảm biến"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Không thể xử lý vân tay. Vui lòng thử lại."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Không nhận dạng được vân tay. Hãy thử lại."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hãy vệ sinh cảm biến vân tay rồi thử lại"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vệ sinh cảm biến rồi thử lại"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Nhấn chắc trên cảm biến"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Di chuyển ngón tay quá chậm. Vui lòng thử lại."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Hãy thử một vân tay khác"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Quá sáng"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Phát hiện thấy thao tác nhấn nút Nguồn"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Hãy thử điều chỉnh"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mỗi lần, hãy thay đổi vị trí ngón tay một chút"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Đã xác thực khuôn mặt, vui lòng nhấn để xác nhận"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Phần cứng vân tay không khả dụng."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Không thể thiết lập vân tay"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Đã hết thời gian chờ vân tay. Hãy thử lại."</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Hết thời gian thiết lập vân tay. Hãy thử lại."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Thao tác dùng dấu vân tay bị hủy."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Người dùng đã hủy thao tác dùng dấu vân tay."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Quá nhiều lần thử. Hãy thử lại sau."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Bạn đã thử quá nhiều lần. Hãy dùng phương thức khoá màn hình."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Bạn đã thử quá nhiều lần. Hãy dùng phương thức khoá màn hình."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Thử lại."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Không xử lý được vân tay. Hãy thử lại."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Chưa đăng ký vân tay."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Hãy liên hệ với một nhà cung cấp dịch vụ sửa chữa."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Không thể tạo mẫu khuôn mặt của bạn. Hãy thử lại."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Quá sáng. Hãy thử giảm độ sáng."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Không đủ ánh sáng"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Đưa điện thoại ra xa hơn"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Đưa điện thoại lại gần hơn"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Nâng điện thoại lên cao hơn"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Khởi động ứng dụng."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Hoàn tất khởi động."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Bạn đã nhấn nút nguồn – thao tác này thường tắt màn hình.\n\nHãy thử nhấn nhẹ khi thiết lập vân tay của bạn."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Nhấn để tắt màn hình"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Tắt màn hình"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Để kết thúc thiết lập, hãy tắt màn hình"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Tắt"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Tiếp tục xác minh vân tay của bạn?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Bạn đã nhấn nút nguồn – thao tác này thường tắt màn hình.\n\nHãy thử nhấn nhẹ để xác minh vân tay."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Tắt màn hình"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Điện thoại"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Loa đế"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Thiết bị bên ngoài"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Tai nghe"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Hệ thống"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index ce5cd53..b81633e4 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用屏幕锁定凭据"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"输入您的屏幕锁定凭据才能继续"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"请用力按住传感器"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"无法处理指纹,请重试。"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"无法识别指纹,请重试。"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"请清洁指纹传感器,然后重试"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"请清洁传感器,然后重试"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"请用力按住传感器"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"手指移动太慢,请重试。"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"请试试其他指纹"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"光线太亮"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"检测到按下“电源”按钮的操作"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"请尝试调整指纹"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"请在每次放手指时略微更改手指的位置"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"面孔已验证,请按确认按钮"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指纹硬件无法使用。"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"无法设置指纹"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"指纹录入操作超时,请重试。"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指纹设置已超时,请重试。"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"指纹操作已取消。"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"用户取消了指纹操作。"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"尝试次数过多,请稍后重试。"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"尝试次数过多,请通过屏幕锁定功能解锁。"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"尝试次数过多,请通过屏幕锁定功能解锁。"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"请重试。"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"无法处理指纹,请重试。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未注册任何指纹。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"请联系维修服务提供商。"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"无法创建您的脸部模型,请重试。"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"亮度过高,请尝试使用较柔和的亮度。"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"光线不足"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"请将手机拿远一点"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"请将手机拿近一点"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"请将手机举高一点"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"正在启动应用。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"即将完成启动。"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"您已按电源按钮,这通常会关闭屏幕。\n\n请尝试在设置指纹时轻轻按一下。"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"按一下即可关闭屏幕"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"关闭屏幕"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"若要结束设置,请关闭屏幕"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"关闭"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"要继续验证您的指纹吗?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"您已按电源按钮,这通常会关闭屏幕。\n\n请尝试轻轻按一下来验证您的指纹。"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"关闭屏幕"</string>
@@ -1482,7 +1482,7 @@
     <string name="sync_binding_label" msgid="469249309424662147">"同步"</string>
     <string name="accessibility_binding_label" msgid="1974602776545801715">"无障碍"</string>
     <string name="wallpaper_binding_label" msgid="1197440498000786738">"壁纸"</string>
-    <string name="chooser_wallpaper" msgid="3082405680079923708">"更改壁纸"</string>
+    <string name="chooser_wallpaper" msgid="3082405680079923708">"更换壁纸"</string>
     <string name="notification_listener_binding_label" msgid="2702165274471499713">"通知侦听器"</string>
     <string name="vr_listener_binding_label" msgid="8013112996671206429">"VR 监听器"</string>
     <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"条件提供程序"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"电视"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"手机"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"基座扬声器"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"外部设备"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"耳机"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"系统"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 96c7b0b..d7f33a5 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定解鎖憑證"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"請用力按住感應器"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋。請再試一次。"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"無法辨識指紋,請再試一次。"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"請清潔指紋感應器,然後再試一次"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"請清潔感應器,然後再試一次"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"請用力按住感應器"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"手指移動太慢,請重試。"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"偵測到按下開關按鈕"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"嘗試調整"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"每次掃瞄時請稍微變更手指的位置"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"面孔已經驗證,請㩒一下 [確認]"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"無法使用指紋軟件。"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"無法設定指紋"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"指紋已逾時。請再試一次。"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指紋設定逾時,請再試一次。"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋操作已取消。"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"使用者已取消指紋操作。"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"嘗試次數過多,請稍後再試。"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"嘗試次數過多,請改用螢幕鎖定功能。"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"嘗試次數過多,請改用螢幕鎖定功能。"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"再試一次。"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"無法處理指紋,請再試一次。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未註冊任何指紋"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"請諮詢維修服務供應商。"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"無法建立面部模型,請再試一次。"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"影像太亮。請嘗試在更暗的環境下使用。"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"光線不足"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"請將手機移開一點"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"請將手機移近一點"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"請將手機向上移"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"正在啟動應用程式。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"啟動完成。"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"您已按下開關按鈕,這麼做通常會關閉螢幕。\n\n設定指紋時請嘗試輕按開關按鈕。"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"輕按即可關閉螢幕"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"關閉螢幕"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"如要結束設定,請關閉螢幕"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"關閉"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"要繼續驗證指紋嗎?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"您已按下開關按鈕,這麼做通常會關閉螢幕。\n\n嘗試輕按開關按鈕以驗證指紋。"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"關閉螢幕"</string>
@@ -1565,7 +1565,7 @@
     <string name="action_bar_home_description_format" msgid="5087107531331621803">"%1$s:%2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="4346835454749569826">"%1$s (%2$s):%3$s"</string>
     <string name="storage_internal" msgid="8490227947584914460">"內部共用儲存空間"</string>
-    <string name="storage_sd_card" msgid="3404740277075331881">"SD 記憶卡"</string>
+    <string name="storage_sd_card" msgid="3404740277075331881">"SD 卡"</string>
     <string name="storage_sd_card_label" msgid="7526153141147470509">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 卡"</string>
     <string name="storage_usb_drive" msgid="448030813201444573">"USB 驅動器"</string>
     <string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB 驅動器"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"電視"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"手機"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"插座喇叭"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"外部裝置"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"耳機"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"系統"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 46d95c7f..44aeb10 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定功能"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定憑證"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"請確實按住感應器"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋,請再試一次。"</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"無法辨識指紋,請再試一次。"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"請清潔指紋感應器,然後再試一次"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"清潔感應器,然後再試一次"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"請確實按住感應器"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"手指移動速度過慢,請再試一次。"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"偵測到按下電源鍵"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"請試著調整"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"每次掃描時請稍微改變手指的位置"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"臉孔驗證成功,請按下 [確認] 按鈕"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指紋硬體無法使用。"</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"無法設定指紋"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"指紋處理作業逾時,請再試一次。"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指紋設定逾時,請再試一次。"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋作業已取消。"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"使用者已取消指紋驗證作業。"</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"嘗試次數過多,請稍後再試。"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"嘗試次數過多,請改用螢幕鎖定功能。"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"嘗試次數過多,請改用螢幕鎖定功能。"</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"請再試一次。"</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"無法處理指紋,請再試一次。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未登錄任何指紋。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"請洽詢維修供應商。"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"無法建立臉部模型,請再試一次。"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"亮度過高,請嘗試使用較柔和的照明方式。"</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"光線不足"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"請將手機拿遠一點"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"請將手機拿近一點"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"請將手機舉高一點"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"正在啟動應用程式。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"啟動完成。"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"你已按下電源鍵,這麼做通常會關閉螢幕。\n\n設定指紋時請試著減輕觸碰電源鍵的力道。"</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"輕觸即可關閉螢幕"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"關閉螢幕"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"如要結束設定,請關閉螢幕"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"關閉"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"要繼續驗證指紋嗎?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"你已按下電源鍵,這麼做通常會關閉螢幕。\n\n驗證指紋時,請試著減輕觸碰電源鍵的力道。"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"關閉螢幕"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"電視"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"手機"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"座架喇叭"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"外部裝置"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"耳機"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"系統"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 6e640c6..d4d1f2a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -583,13 +583,14 @@
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Sebenzisa isikhiya sesikrini"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Faka ukukhiya isikrini kwakho ukuze uqhubeke"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Cindezela ngokuqinile kunzwa"</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ayikwazanga ukucubungula izigxivizo zeminwe. Sicela uzame futhi."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Ayisazi isigxivizo somunwe. Zama futhi."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hlanza inzwa yesigxivizo somunwe bese uzame futhi"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Hlanza inzwa bese uzame futhi"</string>
     <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Cindezela ngokuqinile kunzwa"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Umnwe uhanjiswe kancane kakhulu. Sicela uzame futhi."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zama ezinye izigxivizo zeminwe"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Kukhanya kakhulu"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Ukucindezela kwamandla kutholiwe"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Zama ukulungisa"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Shintsha indawo yomunwe wakho kancane isikhathi ngasinye"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -601,12 +602,12 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ukuqinisekiswa kobuso, sicela ucindezele okuthi qinisekisa"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Izingxenyekazi zekhompuyutha zezigxivizo zeminwe azitholakali."</string>
     <string name="fingerprint_error_no_space" msgid="7285481581905967580">"Ayikwazi ukusetha izigxivizo zeminwe"</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Kufinyelelwe isikhathi sokuvala sezigxivizo zeminwe. Zama futhi"</string>
+    <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Ukusethwa kwesigxivizo somunwe kuphelelwe yisikhathi Zama futhi."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Ukusebenza kwezigxivizo zeminwe kukhanseliwe."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Umsebenzi wezigxivizo zomunwe ukhanselwe umsebenzisi."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Imizamo eminingi kakhulu. Zama futhi emuva kwesikhathi."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Imizamo eminingi kakhulu. Sebenzisa ukukhiya isikrini kunalokho."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Imizamo eminingi kakhulu. Sebenzisa ukukhiya isikrini kunalokho."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Zama futhi."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Ayikwazi ukucubungula isigxivizo somunwe. Zama futhi."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Azikho izigxivizo zeminwe ezibhalisiwe."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string>
@@ -634,8 +635,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Vakashela umhlinzeki wokulungisa."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Ayikwazi ukusungula imodeli yobuso bakho. Zama futhi."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Kukhanya kakhulu. Zama ukukhanya okuthambile."</string>
-    <!-- no translation found for face_acquired_too_dark (8539853432479385326) -->
-    <skip />
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Ukukhanya okunganele"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Yisa ifoni kude"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Sondeza ifoni eduze"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Yisa ifoni phezulu"</string>
@@ -1249,8 +1249,8 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Qalisa izinhlelo zokusebenza."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Qedela ukuqala kabusha."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Ucindezele inkinobho yamandla — lokhu kuvame ukuvala isikrini.\n\nZama ukuthepha kancane ngenkathi usetha isigxivizo sakho somunwe."</string>
-    <string name="fp_power_button_enrollment_title" msgid="8997641910928785172">"Thepha ukuze uvale isikrini"</string>
-    <string name="fp_power_button_enrollment_button_text" msgid="8351290204990805109">"Vala isikrini"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Ukuze umise ukusetha, vala isikrini"</string>
+    <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Vala"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Qhubeka uqinisekise isigxivizo sakho somunwe?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Ucindezele inkinobho yamandla — lokhu kuvame ukuvala isikrini.\n\nZama ukuthepha kancane ukuze uqinisekise isigxivizo sakho somunwe."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Vala isikrini"</string>
@@ -1611,7 +1611,7 @@
     <string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"I-TV"</string>
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Ifoni"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Izipikha ze-Dock"</string>
-    <string name="default_audio_route_name_external_device" msgid="5474470558160717850">"HDMI"</string>
+    <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Idivayisi Yangaphandle"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Ama-headphone"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"I-USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Isistimu"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index dfada13..1d2ce7e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4850,9 +4850,6 @@
         -->
     </array>
 
-    <!-- How long it takes for the HW to start illuminating after the illumination is requested. -->
-    <integer name="config_udfps_illumination_transition_ms">50</integer>
-
     <!-- Indicates whether device has a power button fingerprint sensor. -->
     <bool name="config_is_powerbutton_fps" translatable="false" >false</bool>
 
@@ -5191,7 +5188,7 @@
     <!-- Vertical position of a center of the letterboxed app window.
         0 corresponds to the upper side of the screen and 1 to the lower side. If given value < 0
         or > 1, it is ignored and central position is used (0.5). -->
-    <item name="config_letterboxVerticalPositionMultiplier" format="float" type="dimen">0.5</item>
+    <item name="config_letterboxVerticalPositionMultiplier" format="float" type="dimen">0.0</item>
 
     <!-- Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps.
     -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7e8423a..95a81e8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2705,7 +2705,6 @@
   <java-symbol type="bool" name="allow_test_udfps" />
   <java-symbol type="array" name="config_udfps_sensor_props" />
   <java-symbol type="array" name="config_sfps_sensor_props" />
-  <java-symbol type="integer" name="config_udfps_illumination_transition_ms" />
   <java-symbol type="bool" name="config_is_powerbutton_fps" />
   <java-symbol type="array" name="config_udfps_enroll_stage_thresholds" />
   <java-symbol type="array" name="config_sfps_enroll_stage_thresholds" />
diff --git a/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java b/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
index ddc05e0..7338c3a 100644
--- a/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
+++ b/core/tests/coretests/src/android/graphics/drawable/AdaptiveIconDrawableTest.java
@@ -204,19 +204,6 @@
         assertEquals(100, Color.alpha(bitmap.getPixel(50, 50)));
     }
 
-    @Test
-    public void testSetBounds() throws Exception {
-        mIconDrawable = new AdaptiveIconDrawable(mBackgroundDrawable, mForegroundDrawable);
-        mIconDrawable.setBounds(0, 0, 100, 100);
-
-        assertEquals(new Rect(-25, -25, 125, 125), mBackgroundDrawable.getBounds());
-        assertEquals(new Rect(-25, -25, 125, 125), mForegroundDrawable.getBounds());
-
-        mIconDrawable.setBounds(10, 10, 110, 110);
-        assertEquals(new Rect(-15, -15, 135, 135), mBackgroundDrawable.getBounds());
-        assertEquals(new Rect(-15, -15, 135, 135), mForegroundDrawable.getBounds());
-    }
-
     //
     // Utils
     //
diff --git a/core/tests/coretests/src/android/internal/os/anr/AnrLatencyTrackerTests.java b/core/tests/coretests/src/android/internal/os/anr/AnrLatencyTrackerTests.java
new file mode 100644
index 0000000..ebd78b46
--- /dev/null
+++ b/core/tests/coretests/src/android/internal/os/anr/AnrLatencyTrackerTests.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.os.anr;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for {@link AnrLatencyTracekr.java}.
+ *
+ */
+public class AnrLatencyTrackerTests {
+
+    private AnrLatencyTracker mLatencyTracker;
+
+    @Before
+    public void setup() {
+        mLatencyTracker = spy(new AnrLatencyTracker(0, 50L));
+        when(mLatencyTracker.getUptimeMillis())
+            .thenReturn(55L)
+            .thenReturn(60L)
+            .thenReturn(70L)
+            .thenReturn(80L)
+            .thenReturn(88L)
+            .thenReturn(99L)
+            .thenReturn(101L)
+            .thenReturn(105L)
+            .thenReturn(108L)
+            .thenReturn(110L)
+            .thenReturn(117L)
+            .thenReturn(121L)
+            .thenReturn(129L)
+            .thenReturn(135L)
+            .thenReturn(150L)
+            .thenReturn(155L)
+            .thenReturn(157L)
+            .thenReturn(158L)
+            .thenReturn(165L)
+            .thenReturn(175L)
+            .thenReturn(188L);
+    }
+
+    @Test
+    public void testNormalScenario() {
+
+        mLatencyTracker.appNotRespondingStarted();
+        mLatencyTracker.waitingOnAnrRecordLockStarted();
+        mLatencyTracker.waitingOnAnrRecordLockEnded();
+        mLatencyTracker.anrRecordPlacingOnQueueWithSize(3);
+        mLatencyTracker.appNotRespondingEnded();
+
+        mLatencyTracker.anrProcessingStarted();
+        mLatencyTracker.updateCpuStatsNowCalled();
+        mLatencyTracker.updateCpuStatsNowReturned();
+        mLatencyTracker.currentPsiStateCalled();
+        mLatencyTracker.currentPsiStateReturned();
+        mLatencyTracker.processCpuTrackerMethodsCalled();
+        mLatencyTracker.processCpuTrackerMethodsReturned();
+        mLatencyTracker.criticalEventLogStarted();
+        mLatencyTracker.criticalEventLogEnded();
+
+        mLatencyTracker.waitingOnGlobalLockStarted();
+        mLatencyTracker.waitingOnGlobalLockEnded();
+        mLatencyTracker.waitingOnPidLockStarted();
+        mLatencyTracker.waitingOnPidLockEnded();
+        mLatencyTracker.waitingOnAMSLockStarted();
+        mLatencyTracker.waitingOnAMSLockEnded();
+        mLatencyTracker.waitingOnProcLockStarted();
+        mLatencyTracker.waitingOnProcLockEnded();
+
+        mLatencyTracker.dumpStackTracesStarted();
+        mLatencyTracker.dumpingFirstPidsStarted();
+        mLatencyTracker.dumpingPidStarted(1);
+        mLatencyTracker.dumpingPidEnded();
+        mLatencyTracker.dumpingFirstPidsEnded();
+        mLatencyTracker.dumpingNativePidsStarted();
+        mLatencyTracker.dumpingPidStarted(3);
+        mLatencyTracker.dumpingPidEnded();
+        mLatencyTracker.dumpingNativePidsEnded();
+        mLatencyTracker.dumpingExtraPidsStarted();
+        mLatencyTracker.dumpingPidStarted(10);
+        mLatencyTracker.dumpingPidEnded();
+        mLatencyTracker.dumpingPidStarted(11);
+        mLatencyTracker.dumpingPidEnded();
+        mLatencyTracker.dumpingExtraPidsEnded();
+        mLatencyTracker.dumpStackTracesEnded();
+        mLatencyTracker.anrProcessingEnded();
+
+        mLatencyTracker.close();
+
+        assertThat(mLatencyTracker.dumpAsCommaSeparatedArrayWithHeader())
+            .isEqualTo("DurationsV1: 50,5,25,8,100,2,3,7,8,15,2,7,13,10,3,4\n\n");
+        verify(mLatencyTracker, times(1)).pushAtom();
+    }
+
+    @Test
+    public void testCloseIdempotency() {
+
+        mLatencyTracker.appNotRespondingStarted();
+        mLatencyTracker.waitingOnAnrRecordLockStarted();
+        mLatencyTracker.waitingOnAnrRecordLockEnded();
+        mLatencyTracker.anrRecordPlacingOnQueueWithSize(3);
+        mLatencyTracker.appNotRespondingEnded();
+
+        mLatencyTracker.anrProcessingStarted();
+        mLatencyTracker.updateCpuStatsNowCalled();
+        mLatencyTracker.updateCpuStatsNowReturned();
+        mLatencyTracker.currentPsiStateCalled();
+        mLatencyTracker.currentPsiStateReturned();
+        mLatencyTracker.processCpuTrackerMethodsCalled();
+        mLatencyTracker.processCpuTrackerMethodsReturned();
+        mLatencyTracker.criticalEventLogStarted();
+        mLatencyTracker.criticalEventLogEnded();
+
+        mLatencyTracker.waitingOnGlobalLockStarted();
+        mLatencyTracker.waitingOnGlobalLockEnded();
+        mLatencyTracker.waitingOnPidLockStarted();
+        mLatencyTracker.waitingOnPidLockEnded();
+        mLatencyTracker.waitingOnAMSLockStarted();
+        mLatencyTracker.waitingOnAMSLockEnded();
+        mLatencyTracker.waitingOnProcLockStarted();
+        mLatencyTracker.waitingOnProcLockEnded();
+
+        mLatencyTracker.dumpStackTracesStarted();
+        mLatencyTracker.dumpingFirstPidsStarted();
+        mLatencyTracker.dumpingPidStarted(1);
+        mLatencyTracker.dumpingPidEnded();
+        mLatencyTracker.dumpingFirstPidsEnded();
+        mLatencyTracker.dumpingNativePidsStarted();
+        mLatencyTracker.dumpingPidStarted(3);
+        mLatencyTracker.dumpingPidEnded();
+        mLatencyTracker.dumpingNativePidsEnded();
+        mLatencyTracker.dumpingExtraPidsStarted();
+        mLatencyTracker.dumpingPidStarted(10);
+        mLatencyTracker.dumpingPidEnded();
+        mLatencyTracker.dumpingPidStarted(11);
+        mLatencyTracker.dumpingPidEnded();
+        mLatencyTracker.dumpingExtraPidsEnded();
+        mLatencyTracker.dumpStackTracesEnded();
+        mLatencyTracker.anrProcessingEnded();
+
+        mLatencyTracker.close();
+        mLatencyTracker.close();
+
+        verify(mLatencyTracker, times(1)).pushAtom();
+    }
+
+    @Test
+    public void testSkipInProcessErrorStateRecordAppNotResponding() {
+
+        mLatencyTracker.appNotRespondingStarted();
+        mLatencyTracker.waitingOnAnrRecordLockStarted();
+        mLatencyTracker.waitingOnAnrRecordLockEnded();
+        mLatencyTracker.anrRecordPlacingOnQueueWithSize(3);
+        mLatencyTracker.appNotRespondingEnded();
+
+        mLatencyTracker.anrProcessingStarted();
+        mLatencyTracker.updateCpuStatsNowCalled();
+        mLatencyTracker.updateCpuStatsNowReturned();
+        mLatencyTracker.currentPsiStateCalled();
+        mLatencyTracker.currentPsiStateReturned();
+        mLatencyTracker.processCpuTrackerMethodsCalled();
+        mLatencyTracker.processCpuTrackerMethodsReturned();
+        mLatencyTracker.criticalEventLogStarted();
+        mLatencyTracker.criticalEventLogEnded();
+
+        mLatencyTracker.waitingOnGlobalLockStarted();
+        mLatencyTracker.waitingOnGlobalLockEnded();
+        mLatencyTracker.waitingOnPidLockStarted();
+        mLatencyTracker.waitingOnPidLockEnded();
+        mLatencyTracker.waitingOnAMSLockStarted();
+        mLatencyTracker.waitingOnAMSLockEnded();
+        mLatencyTracker.waitingOnProcLockStarted();
+        mLatencyTracker.waitingOnProcLockEnded();
+
+        mLatencyTracker.anrSkippedProcessErrorStateRecordAppNotResponding();
+
+        mLatencyTracker.anrProcessingEnded();
+
+        mLatencyTracker.close();
+
+        verify(mLatencyTracker, times(0)).pushAtom();
+    }
+
+    @Test
+    public void testSkipInDumpTraces() {
+
+        mLatencyTracker.appNotRespondingStarted();
+        mLatencyTracker.waitingOnAnrRecordLockStarted();
+        mLatencyTracker.waitingOnAnrRecordLockEnded();
+        mLatencyTracker.anrRecordPlacingOnQueueWithSize(3);
+        mLatencyTracker.appNotRespondingEnded();
+
+        mLatencyTracker.anrProcessingStarted();
+        mLatencyTracker.updateCpuStatsNowCalled();
+        mLatencyTracker.updateCpuStatsNowReturned();
+        mLatencyTracker.currentPsiStateCalled();
+        mLatencyTracker.currentPsiStateReturned();
+        mLatencyTracker.processCpuTrackerMethodsCalled();
+        mLatencyTracker.processCpuTrackerMethodsReturned();
+        mLatencyTracker.criticalEventLogStarted();
+        mLatencyTracker.criticalEventLogEnded();
+
+        mLatencyTracker.waitingOnGlobalLockStarted();
+        mLatencyTracker.waitingOnGlobalLockEnded();
+        mLatencyTracker.waitingOnPidLockStarted();
+        mLatencyTracker.waitingOnPidLockEnded();
+        mLatencyTracker.waitingOnAMSLockStarted();
+        mLatencyTracker.waitingOnAMSLockEnded();
+        mLatencyTracker.waitingOnProcLockStarted();
+        mLatencyTracker.waitingOnProcLockEnded();
+
+        mLatencyTracker.dumpStackTracesStarted();
+        mLatencyTracker.anrSkippedDumpStackTraces();
+        mLatencyTracker.dumpStackTracesEnded();
+
+        mLatencyTracker.anrProcessingEnded();
+
+        mLatencyTracker.close();
+
+        verify(mLatencyTracker, times(0)).pushAtom();
+    }
+
+}
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index 4770fa6..7674135 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -262,6 +262,8 @@
                         && f.getType() == int.class)
                 .collect(Collectors.toMap(this::getIntFieldChecked, Field::getName));
 
+        assertThat(enumsMap.size() - 1).isEqualTo(cujs.size());
+
         cujs.forEach(f -> {
             final int cuj = getIntFieldChecked(f);
             final String cujName = f.getName();
@@ -279,7 +281,9 @@
                     .that(expectedEnumName.equals(enumName))
                     .isTrue();
             mExpect
-                    .withMessage(formatSimple("getNameOfCuj(%d) not matches %s", cuj, cujName))
+                    .withMessage(
+                            formatSimple("getNameOfCuj(%d) not matches: %s, expected=%s",
+                                    cuj, cujName, expectedNameOfCuj))
                     .that(cujName.equals(expectedNameOfCuj))
                     .isTrue();
         });
diff --git a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
new file mode 100644
index 0000000..e384e69
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static android.text.TextUtils.formatSimple;
+
+import static com.android.internal.util.LatencyTracker.STATSD_ACTION;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import androidx.test.filters.SmallTest;
+
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@SmallTest
+public class LatencyTrackerTest {
+    private static final String ENUM_NAME_PREFIX = "UIACTION_LATENCY_REPORTED__ACTION__";
+
+    @Rule
+    public final Expect mExpect = Expect.create();
+
+    @Test
+    public void testCujsMapToEnumsCorrectly() {
+        List<Field> actions = Arrays.stream(LatencyTracker.class.getDeclaredFields())
+                .filter(f -> f.getName().startsWith("ACTION_")
+                        && Modifier.isStatic(f.getModifiers())
+                        && f.getType() == int.class)
+                .collect(Collectors.toList());
+
+        Map<Integer, String> enumsMap = Arrays.stream(FrameworkStatsLog.class.getDeclaredFields())
+                .filter(f -> f.getName().startsWith(ENUM_NAME_PREFIX)
+                        && Modifier.isStatic(f.getModifiers())
+                        && f.getType() == int.class)
+                .collect(Collectors.toMap(this::getIntFieldChecked, Field::getName));
+
+        assertThat(enumsMap.size() - 1).isEqualTo(actions.size());
+
+        actions.forEach(f -> {
+            final int action = getIntFieldChecked(f);
+            final String actionName = f.getName();
+            final String expectedEnumName = formatSimple("%s%s", ENUM_NAME_PREFIX, actionName);
+            final int enumKey = STATSD_ACTION[action];
+            final String enumName = enumsMap.get(enumKey);
+            final String expectedActionName = LatencyTracker.getNameOfAction(enumKey);
+            mExpect
+                    .withMessage(formatSimple(
+                            "%s (%d) not matches %s (%d)", actionName, action, enumName, enumKey))
+                    .that(expectedEnumName.equals(enumName))
+                    .isTrue();
+            mExpect
+                    .withMessage(
+                            formatSimple("getNameOfAction(%d) not matches: %s, expected=%s",
+                                    enumKey, actionName, expectedActionName))
+                    .that(actionName.equals(expectedActionName))
+                    .isTrue();
+        });
+    }
+
+    @Test
+    public void testCujTypeEnumCorrectlyDefined() throws Exception {
+        List<Field> cujEnumFields =
+                Arrays.stream(LatencyTracker.class.getDeclaredFields())
+                        .filter(field -> field.getName().startsWith("ACTION_")
+                                && Modifier.isStatic(field.getModifiers())
+                                && field.getType() == int.class)
+                        .collect(Collectors.toList());
+
+        HashSet<Integer> allValues = new HashSet<>();
+        for (Field field : cujEnumFields) {
+            int fieldValue = field.getInt(null);
+            assertWithMessage(
+                    "Field %s must have a mapping to a value in STATSD_ACTION",
+                    field.getName())
+                    .that(fieldValue < STATSD_ACTION.length)
+                    .isTrue();
+            assertWithMessage("All CujType values must be unique. Field %s repeats existing value.",
+                    field.getName())
+                    .that(allValues.add(fieldValue))
+                    .isTrue();
+        }
+    }
+
+    private int getIntFieldChecked(Field field) {
+        try {
+            return field.getInt(null);
+        } catch (IllegalAccessException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}
diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
index 940ca96..4679a9e 100644
--- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
@@ -19,14 +19,15 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -51,8 +52,11 @@
 import com.android.internal.widget.IWeakEscrowTokenRemovedListener;
 import com.android.internal.widget.LockPatternUtils;
 
+import com.google.android.collect.Lists;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
 import java.nio.charset.StandardCharsets;
@@ -172,13 +176,61 @@
     }
 
     @Test
-    public void testGetEnabledTrustAgentsNotNull() throws RemoteException {
+    public void testSetEnabledTrustAgents() throws RemoteException {
         int testUserId = 10;
         ILockSettings ils = createTestLockSettings();
-        when(ils.getString(anyString(), any(), anyInt())).thenReturn("");
+        ArgumentCaptor<String> valueCaptor = ArgumentCaptor.forClass(String.class);
+        doNothing().when(ils).setString(anyString(), valueCaptor.capture(), anyInt());
+        List<ComponentName> enabledTrustAgents = Lists.newArrayList(
+                ComponentName.unflattenFromString("com.android/.TrustAgent"),
+                ComponentName.unflattenFromString("com.test/.TestAgent"));
+
+        mLockPatternUtils.setEnabledTrustAgents(enabledTrustAgents, testUserId);
+
+        assertThat(valueCaptor.getValue()).isEqualTo("com.android/.TrustAgent,com.test/.TestAgent");
+    }
+
+    @Test
+    public void testGetEnabledTrustAgents() throws RemoteException {
+        int testUserId = 10;
+        ILockSettings ils = createTestLockSettings();
+        when(ils.getString(anyString(), any(), anyInt())).thenReturn(
+                "com.android/.TrustAgent,com.test/.TestAgent");
+
         List<ComponentName> trustAgents = mLockPatternUtils.getEnabledTrustAgents(testUserId);
-        assertNotNull(trustAgents);
-        assertEquals(0, trustAgents.size());
+
+        assertThat(trustAgents).containsExactly(
+                ComponentName.unflattenFromString("com.android/.TrustAgent"),
+                ComponentName.unflattenFromString("com.test/.TestAgent"));
+    }
+
+    @Test
+    public void testSetKnownTrustAgents() throws RemoteException {
+        int testUserId = 10;
+        ILockSettings ils = createTestLockSettings();
+        ArgumentCaptor<String> valueCaptor = ArgumentCaptor.forClass(String.class);
+        doNothing().when(ils).setString(anyString(), valueCaptor.capture(), anyInt());
+        List<ComponentName> knownTrustAgents = Lists.newArrayList(
+                ComponentName.unflattenFromString("com.android/.TrustAgent"),
+                ComponentName.unflattenFromString("com.test/.TestAgent"));
+
+        mLockPatternUtils.setKnownTrustAgents(knownTrustAgents, testUserId);
+
+        assertThat(valueCaptor.getValue()).isEqualTo("com.android/.TrustAgent,com.test/.TestAgent");
+    }
+
+    @Test
+    public void testGetKnownTrustAgents() throws RemoteException {
+        int testUserId = 10;
+        ILockSettings ils = createTestLockSettings();
+        when(ils.getString(anyString(), any(), anyInt())).thenReturn(
+                "com.android/.TrustAgent,com.test/.TestAgent");
+
+        List<ComponentName> trustAgents = mLockPatternUtils.getKnownTrustAgents(testUserId);
+
+        assertThat(trustAgents).containsExactly(
+                ComponentName.unflattenFromString("com.android/.TrustAgent"),
+                ComponentName.unflattenFromString("com.test/.TestAgent"));
     }
 
     private ILockSettings createTestLockSettings() {
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index a186aca..af96c74 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -302,6 +302,11 @@
 key 318   BUTTON_THUMBR
 
 
+key 329   STYLUS_BUTTON_TERTIARY
+key 331   STYLUS_BUTTON_PRIMARY
+key 332   STYLUS_BUTTON_SECONDARY
+
+
 # key 352 "KEY_OK"
 key 353   DPAD_CENTER
 # key 354 "KEY_GOTO"
@@ -424,6 +429,8 @@
 key usage 0x0c0173 MEDIA_AUDIO_TRACK
 key usage 0x0c019C PROFILE_SWITCH
 key usage 0x0c01A2 ALL_APPS
+key usage 0x0d0044 STYLUS_BUTTON_PRIMARY
+key usage 0x0d005a STYLUS_BUTTON_SECONDARY
 
 # Joystick and game controller axes.
 # Axes that are not mapped will be assigned generic axis numbers by the input subsystem.
diff --git a/data/sounds/AudioTv.mk b/data/sounds/AudioTv.mk
index fd53aff..d288e0e 100644
--- a/data/sounds/AudioTv.mk
+++ b/data/sounds/AudioTv.mk
@@ -15,7 +15,6 @@
 LOCAL_PATH := frameworks/base/data/sounds
 
 PRODUCT_COPY_FILES += \
-    $(LOCAL_PATH)/Alarm_Beep_01.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_02.ogg \
     $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \
diff --git a/docs/html/reference/images/input_method/stylus_handwriting/delete_range_gesture_rects.png b/docs/html/reference/images/input_method/stylus_handwriting/delete_range_gesture_rects.png
new file mode 100644
index 0000000..1855820
--- /dev/null
+++ b/docs/html/reference/images/input_method/stylus_handwriting/delete_range_gesture_rects.png
Binary files differ
diff --git a/docs/html/reference/images/input_method/stylus_handwriting/select_range_gesture_rects.png b/docs/html/reference/images/input_method/stylus_handwriting/select_range_gesture_rects.png
new file mode 100644
index 0000000..e080126
--- /dev/null
+++ b/docs/html/reference/images/input_method/stylus_handwriting/select_range_gesture_rects.png
Binary files differ
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index a8ab6d9..54d6428 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -670,8 +670,9 @@
     /**
      * @hide
      */
-    public void punchHole(float left, float top, float right, float bottom, float rx, float ry) {
-        nPunchHole(mNativeCanvasWrapper, left, top, right, bottom, rx, ry);
+    public void punchHole(float left, float top, float right, float bottom, float rx, float ry,
+            float alpha) {
+        nPunchHole(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, alpha);
     }
 
     /**
@@ -823,5 +824,5 @@
             float hOffset, float vOffset, int flags, long nativePaint);
 
     private static native void nPunchHole(long renderer, float left, float top, float right,
-            float bottom, float rx, float ry);
+            float bottom, float rx, float ry, float alpha);
 }
diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java
index d06f665..1ba79b8 100644
--- a/graphics/java/android/graphics/BaseRecordingCanvas.java
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -610,8 +610,9 @@
      * @hide
      */
     @Override
-    public void punchHole(float left, float top, float right, float bottom, float rx, float ry) {
-        nPunchHole(mNativeCanvasWrapper, left, top, right, bottom, rx, ry);
+    public void punchHole(float left, float top, float right, float bottom, float rx, float ry,
+            float alpha) {
+        nPunchHole(mNativeCanvasWrapper, left, top, right, bottom, rx, ry, alpha);
     }
 
     @FastNative
@@ -742,5 +743,5 @@
 
     @FastNative
     private static native void nPunchHole(long renderer, float left, float top, float right,
-            float bottom, float rx, float ry);
+            float bottom, float rx, float ry, float alpha);
 }
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 47de37d..688425a 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -26,6 +26,8 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
 import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -37,6 +39,8 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.graphics.Shader;
+import android.graphics.Shader.TileMode;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.PathParser;
@@ -102,8 +106,7 @@
     private static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);
 
     /**
-     * Unused path.
-     * TODO: Remove once the layoutLib is updated
+     * Clip path defined in R.string.config_icon_mask.
      */
     private static Path sMask;
 
@@ -111,10 +114,9 @@
      * Scaled mask based on the view bounds.
      */
     private final Path mMask;
-    private final Path mMaskTransformed;
+    private final Path mMaskScaleOnly;
     private final Matrix mMaskMatrix;
     private final Region mTransparentRegion;
-    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 
     /**
      * Indices used to access {@link #mLayerState.mChildDrawable} array for foreground and
@@ -129,10 +131,19 @@
      */
     LayerState mLayerState;
 
+    private Shader mLayersShader;
+    private Bitmap mLayersBitmap;
+
     private final Rect mTmpOutRect = new Rect();
     private Rect mHotspotBounds;
     private boolean mMutated;
 
+    private boolean mSuspendChildInvalidation;
+    private boolean mChildRequestedInvalidation;
+    private final Canvas mCanvas;
+    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG |
+        Paint.FILTER_BITMAP_FLAG);
+
     /**
      * Constructor used for xml inflation.
      */
@@ -146,16 +157,19 @@
      */
     AdaptiveIconDrawable(@Nullable LayerState state, @Nullable Resources res) {
         mLayerState = createConstantState(state, res);
-        // config_icon_mask from context bound resource may have been changed using
+        // config_icon_mask from context bound resource may have been chaged using
         // OverlayManager. Read that one first.
         Resources r = ActivityThread.currentActivityThread() == null
                 ? Resources.getSystem()
                 : ActivityThread.currentActivityThread().getApplication().getResources();
-        mMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
-        mMaskTransformed = new Path();
+        // TODO: either make sMask update only when config_icon_mask changes OR
+        // get rid of it all-together in layoutlib
+        sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
+        mMask = new Path(sMask);
+        mMaskScaleOnly = new Path(mMask);
         mMaskMatrix = new Matrix();
+        mCanvas = new Canvas();
         mTransparentRegion = new Region();
-        mPaint.setColor(Color.BLACK);
     }
 
     private ChildDrawable createChildDrawable(Drawable drawable) {
@@ -266,7 +280,7 @@
      * @return the mask path object used to clip the drawable
      */
     public Path getIconMask() {
-        return mMaskTransformed;
+        return mMask;
     }
 
     /**
@@ -308,47 +322,92 @@
         if (bounds.isEmpty()) {
             return;
         }
-        // Set the child layer bounds bigger than the view port size
-        // by {@link #DEFAULT_VIEW_PORT_SCALE}
-        float cX = bounds.exactCenterX();
-        float cY = bounds.exactCenterY();
-        float insetWidth = bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2);
-        float insetHeight = bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2);
-        final Rect outRect = mTmpOutRect;
-        outRect.set(
-                (int) (cX - insetWidth),
-                (int) (cY - insetHeight),
-                (int) (cX + insetWidth),
-                (int) (cY + insetHeight));
+        updateLayerBounds(bounds);
+    }
+
+    private void updateLayerBounds(Rect bounds) {
+        if (bounds.isEmpty()) {
+            return;
+        }
+        try {
+            suspendChildInvalidation();
+            updateLayerBoundsInternal(bounds);
+            updateMaskBoundsInternal(bounds);
+        } finally {
+            resumeChildInvalidation();
+        }
+    }
+
+    /**
+     * Set the child layer bounds bigger than the view port size by {@link #DEFAULT_VIEW_PORT_SCALE}
+     */
+    private void updateLayerBoundsInternal(Rect bounds) {
+        int cX = bounds.width() / 2;
+        int cY = bounds.height() / 2;
 
         for (int i = 0, count = mLayerState.N_CHILDREN; i < count; i++) {
             final ChildDrawable r = mLayerState.mChildren[i];
-            if (r.mDrawable != null) {
-                r.mDrawable.setBounds(outRect);
+            final Drawable d = r.mDrawable;
+            if (d == null) {
+                continue;
             }
+
+            int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2));
+            int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2));
+            final Rect outRect = mTmpOutRect;
+            outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight);
+
+            d.setBounds(outRect);
+        }
+    }
+
+    private void updateMaskBoundsInternal(Rect b) {
+        // reset everything that depends on the view bounds
+        mMaskMatrix.setScale(b.width() / MASK_SIZE, b.height() / MASK_SIZE);
+        sMask.transform(mMaskMatrix, mMaskScaleOnly);
+
+        mMaskMatrix.postTranslate(b.left, b.top);
+        sMask.transform(mMaskMatrix, mMask);
+
+        if (mLayersBitmap == null || mLayersBitmap.getWidth() != b.width()
+                || mLayersBitmap.getHeight() != b.height()) {
+            mLayersBitmap = Bitmap.createBitmap(b.width(), b.height(), Bitmap.Config.ARGB_8888);
         }
 
-        // Update the clipping mask
-        mMaskMatrix.setScale(bounds.width() / MASK_SIZE, bounds.height() / MASK_SIZE);
-        mMaskMatrix.postTranslate(bounds.left, bounds.top);
-        mMask.transform(mMaskMatrix, mMaskTransformed);
-
-        // Clear the transparent region, it is calculated lazily
+        mPaint.setShader(null);
         mTransparentRegion.setEmpty();
+        mLayersShader = null;
     }
 
     @Override
     public void draw(Canvas canvas) {
-        int saveCount = canvas.save();
-        canvas.clipPath(mMaskTransformed);
-        canvas.drawPaint(mPaint);
-        if (mLayerState.mChildren[BACKGROUND_ID].mDrawable != null) {
-            mLayerState.mChildren[BACKGROUND_ID].mDrawable.draw(canvas);
+        if (mLayersBitmap == null) {
+            return;
         }
-        if (mLayerState.mChildren[FOREGROUND_ID].mDrawable != null) {
-            mLayerState.mChildren[FOREGROUND_ID].mDrawable.draw(canvas);
+        if (mLayersShader == null) {
+            mCanvas.setBitmap(mLayersBitmap);
+            mCanvas.drawColor(Color.BLACK);
+            if (mLayerState.mChildren[BACKGROUND_ID].mDrawable != null) {
+                mLayerState.mChildren[BACKGROUND_ID].mDrawable.draw(mCanvas);
+            }
+            if (mLayerState.mChildren[FOREGROUND_ID].mDrawable != null) {
+                mLayerState.mChildren[FOREGROUND_ID].mDrawable.draw(mCanvas);
+            }
+            mLayersShader = new BitmapShader(mLayersBitmap, TileMode.CLAMP, TileMode.CLAMP);
+            mPaint.setShader(mLayersShader);
         }
-        canvas.restoreToCount(saveCount);
+        if (mMaskScaleOnly != null) {
+            Rect bounds = getBounds();
+            canvas.translate(bounds.left, bounds.top);
+            canvas.drawPath(mMaskScaleOnly, mPaint);
+            canvas.translate(-bounds.left, -bounds.top);
+        }
+    }
+
+    @Override
+    public void invalidateSelf() {
+        mLayersShader = null;
+        super.invalidateSelf();
     }
 
     @Override
@@ -541,9 +600,37 @@
         return false;
     }
 
+    /**
+     * Temporarily suspends child invalidation.
+     *
+     * @see #resumeChildInvalidation()
+     */
+    private void suspendChildInvalidation() {
+        mSuspendChildInvalidation = true;
+    }
+
+    /**
+     * Resumes child invalidation after suspension, immediately performing an
+     * invalidation if one was requested by a child during suspension.
+     *
+     * @see #suspendChildInvalidation()
+     */
+    private void resumeChildInvalidation() {
+        mSuspendChildInvalidation = false;
+
+        if (mChildRequestedInvalidation) {
+            mChildRequestedInvalidation = false;
+            invalidateSelf();
+        }
+    }
+
     @Override
     public void invalidateDrawable(@NonNull Drawable who) {
-        invalidateSelf();
+        if (mSuspendChildInvalidation) {
+            mChildRequestedInvalidation = true;
+        } else {
+            invalidateSelf();
+        }
     }
 
     @Override
@@ -627,13 +714,6 @@
     @Override
     public void setAlpha(int alpha) {
         mPaint.setAlpha(alpha);
-        final ChildDrawable[] array = mLayerState.mChildren;
-        for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
-            final Drawable dr = array[i].mDrawable;
-            if (dr != null) {
-                dr.setAlpha(alpha);
-            }
-        }
     }
 
     @Override
@@ -736,6 +816,10 @@
             }
         }
 
+        if (changed) {
+            updateLayerBounds(getBounds());
+        }
+
         return changed;
     }
 
@@ -751,6 +835,10 @@
             }
         }
 
+        if (changed) {
+            updateLayerBounds(getBounds());
+        }
+
         return changed;
     }
 
@@ -891,7 +979,6 @@
         int mDensity;
 
         // The density to use when inflating/looking up the children drawables. A value of 0 means
-
         // use the system's density.
         int mSrcDensityOverride = 0;
 
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index d9a7994..dbd918e 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -29,6 +29,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
 import java.util.Collection;
 import java.util.Locale;
 
@@ -675,6 +677,26 @@
             }
         }
 
+        /**
+         * @hide
+         */
+        @NonNull public static @DigestEnum
+                AlgorithmParameterSpec fromKeymasterToMGF1ParameterSpec(int digest) {
+            switch (digest) {
+                default:
+                case KeymasterDefs.KM_DIGEST_SHA1:
+                    return MGF1ParameterSpec.SHA1;
+                case KeymasterDefs.KM_DIGEST_SHA_2_224:
+                    return MGF1ParameterSpec.SHA224;
+                case KeymasterDefs.KM_DIGEST_SHA_2_256:
+                    return MGF1ParameterSpec.SHA256;
+                case KeymasterDefs.KM_DIGEST_SHA_2_384:
+                    return MGF1ParameterSpec.SHA384;
+                case KeymasterDefs.KM_DIGEST_SHA_2_512:
+                    return MGF1ParameterSpec.SHA512;
+            }
+        }
+
         @NonNull
         public static @DigestEnum String fromKeymasterToSignatureAlgorithmDigest(int digest) {
             switch (digest) {
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java b/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
index e808c5c..7571e44 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
@@ -69,6 +69,7 @@
  */
 abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStoreCryptoOperation {
     private static final String TAG = "AndroidKeyStoreCipherSpiBase";
+    public static final String DEFAULT_MGF1_DIGEST = "SHA-1";
 
     // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after
     // doFinal finishes.
@@ -133,24 +134,28 @@
                 if ("RSA/ECB/OAEPWithSHA-224AndMGF1Padding".equals(transform)) {
                     OAEPParameterSpec spec =
                             new OAEPParameterSpec("SHA-224", "MGF1",
-                                    new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT);
+                                    new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST),
+                                    PSource.PSpecified.DEFAULT);
                     mCipher.init(opmode, key, spec, random);
                 } else if ("RSA/ECB/OAEPWithSHA-256AndMGF1Padding".equals(transform)) {
                     OAEPParameterSpec spec =
                             new OAEPParameterSpec("SHA-256", "MGF1",
-                                    new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT);
+                                    new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST),
+                                    PSource.PSpecified.DEFAULT);
                     mCipher.init(opmode, key, spec, random);
 
                 } else if ("RSA/ECB/OAEPWithSHA-384AndMGF1Padding".equals(transform)) {
                     OAEPParameterSpec spec =
                             new OAEPParameterSpec("SHA-384", "MGF1",
-                                    new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT);
+                                    new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST),
+                                    PSource.PSpecified.DEFAULT);
                     mCipher.init(opmode, key, spec, random);
 
                 } else if ("RSA/ECB/OAEPWithSHA-512AndMGF1Padding".equals(transform)) {
                     OAEPParameterSpec spec =
                             new OAEPParameterSpec("SHA-512", "MGF1",
-                                    new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT);
+                                    new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST),
+                                    PSource.PSpecified.DEFAULT);
                     mCipher.init(opmode, key, spec, random);
                 } else {
                     mCipher.init(opmode, key, random);
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index cdc1085..acc0005 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -16,6 +16,8 @@
 
 package android.security.keystore2;
 
+import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MGF1_DIGEST;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityThread;
@@ -908,6 +910,26 @@
             params.add(KeyStore2ParameterUtils.makeEnum(
                     KeymasterDefs.KM_TAG_PADDING, padding
             ));
+            if (padding == KeymasterDefs.KM_PAD_RSA_OAEP) {
+                final boolean[] hasDefaultMgf1DigestBeenAdded = {false};
+                ArrayUtils.forEach(mKeymasterDigests, (digest) -> {
+                    params.add(KeyStore2ParameterUtils.makeEnum(
+                            KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, digest
+                    ));
+                    hasDefaultMgf1DigestBeenAdded[0] |=
+                            digest.equals(KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST));
+                });
+                /* Because of default MGF1 digest is SHA-1. It has to be added in Key
+                 * characteristics. Otherwise, crypto operations will fail with Incompatible
+                 * MGF1 digest.
+                 */
+                if (!hasDefaultMgf1DigestBeenAdded[0]) {
+                    params.add(KeyStore2ParameterUtils.makeEnum(
+                            KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST,
+                            KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST)
+                    ));
+                }
+            }
         });
         ArrayUtils.forEach(mKeymasterSignaturePaddings, (padding) -> {
             params.add(KeyStore2ParameterUtils.makeEnum(
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
index 5848247..e9b66aa 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
@@ -161,10 +161,11 @@
      */
     abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi {
 
-        private static final String MGF_ALGORITGM_MGF1 = "MGF1";
+        private static final String MGF_ALGORITHM_MGF1 = "MGF1";
 
         private int mKeymasterDigest = -1;
         private int mDigestOutputSizeBytes;
+        private int mKeymasterMgf1Digest = KeymasterDefs.KM_DIGEST_SHA1; // Default MGF1 digest
 
         OAEPWithMGF1Padding(int keymasterDigest) {
             super(KeymasterDefs.KM_PAD_RSA_OAEP);
@@ -189,10 +190,10 @@
                         + ". Only OAEPParameterSpec supported");
             }
             OAEPParameterSpec spec = (OAEPParameterSpec) params;
-            if (!MGF_ALGORITGM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) {
+            if (!MGF_ALGORITHM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) {
                 throw new InvalidAlgorithmParameterException(
                         "Unsupported MGF: " + spec.getMGFAlgorithm()
-                        + ". Only " + MGF_ALGORITGM_MGF1 + " supported");
+                        + ". Only " + MGF_ALGORITHM_MGF1 + " supported");
             }
             String jcaDigest = spec.getDigestAlgorithm();
             int keymasterDigest;
@@ -225,11 +226,6 @@
             }
             MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) mgfParams;
             String mgf1JcaDigest = mgfSpec.getDigestAlgorithm();
-            if (!KeyProperties.DIGEST_SHA1.equalsIgnoreCase(mgf1JcaDigest)) {
-                throw new InvalidAlgorithmParameterException(
-                        "Unsupported MGF1 digest: " + mgf1JcaDigest
-                        + ". Only " + KeyProperties.DIGEST_SHA1 + " supported");
-            }
             PSource pSource = spec.getPSource();
             if (!(pSource instanceof PSource.PSpecified)) {
                 throw new InvalidAlgorithmParameterException(
@@ -244,6 +240,7 @@
                         + ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported");
             }
             mKeymasterDigest = keymasterDigest;
+            mKeymasterMgf1Digest = KeyProperties.Digest.toKeymaster(mgf1JcaDigest);
             mDigestOutputSizeBytes =
                     (KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8;
         }
@@ -273,10 +270,10 @@
         protected final AlgorithmParameters engineGetParameters() {
             OAEPParameterSpec spec =
                     new OAEPParameterSpec(
-                            KeyProperties.Digest.fromKeymaster(mKeymasterDigest),
-                            MGF_ALGORITGM_MGF1,
-                            MGF1ParameterSpec.SHA1,
-                            PSource.PSpecified.DEFAULT);
+                        KeyProperties.Digest.fromKeymaster(mKeymasterDigest),
+                        MGF_ALGORITHM_MGF1,
+                        KeyProperties.Digest.fromKeymasterToMGF1ParameterSpec(mKeymasterMgf1Digest),
+                        PSource.PSpecified.DEFAULT);
             try {
                 AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP");
                 params.init(spec);
@@ -298,6 +295,9 @@
             parameters.add(KeyStore2ParameterUtils.makeEnum(
                     KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest
             ));
+            parameters.add(KeyStore2ParameterUtils.makeEnum(
+                    KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mKeymasterMgf1Digest
+            ));
         }
 
         @Override
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index dfda356..94bf122 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -16,6 +16,8 @@
 
 package android.security.keystore2;
 
+import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MGF1_DIGEST;
+
 import android.annotation.NonNull;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.security.keymint.HardwareAuthenticatorType;
@@ -511,6 +513,28 @@
                         KeymasterDefs.KM_TAG_PADDING,
                         padding
                 ));
+                if (padding == KeymasterDefs.KM_PAD_RSA_OAEP) {
+                    if (spec.isDigestsSpecified()) {
+                        boolean hasDefaultMgf1DigestBeenAdded = false;
+                        for (String digest : spec.getDigests()) {
+                            importArgs.add(KeyStore2ParameterUtils.makeEnum(
+                                    KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST,
+                                    KeyProperties.Digest.toKeymaster(digest)
+                            ));
+                            hasDefaultMgf1DigestBeenAdded |= digest.equals(DEFAULT_MGF1_DIGEST);
+                        }
+                        /* Because of default MGF1 digest is SHA-1. It has to be added in Key
+                         * characteristics. Otherwise, crypto operations will fail with Incompatible
+                         * MGF1 digest.
+                         */
+                        if (!hasDefaultMgf1DigestBeenAdded) {
+                            importArgs.add(KeyStore2ParameterUtils.makeEnum(
+                                    KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST,
+                                    KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST)
+                            ));
+                        }
+                    }
+                }
             }
             for (String padding : spec.getSignaturePaddings()) {
                 importArgs.add(KeyStore2ParameterUtils.makeEnum(
diff --git a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
index dcdd7de..54955c6 100644
--- a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
+++ b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
@@ -78,6 +78,7 @@
                 kp.value = KeyParameterValue.blockMode(v);
                 break;
             case Tag.DIGEST:
+            case Tag.RSA_OAEP_MGF_DIGEST:
                 kp.value = KeyParameterValue.digest(v);
                 break;
             case Tag.EC_CURVE:
diff --git a/libs/WindowManager/Shell/res/values-ro/strings_tv.xml b/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
index 56dadb2..36df286 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
@@ -19,16 +19,16 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Picture-in-picture"</string>
     <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Program fără titlu)"</string>
-    <string name="pip_close" msgid="2955969519031223530">"Închideți"</string>
+    <string name="pip_close" msgid="2955969519031223530">"Închide"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Ecran complet"</string>
-    <string name="pip_move" msgid="158770205886688553">"Mutați"</string>
-    <string name="pip_expand" msgid="1051966011679297308">"Extindeți"</string>
-    <string name="pip_collapse" msgid="3903295106641385962">"Restrângeți"</string>
-    <string name="pip_edu_text" msgid="3672999496647508701">" Apăsați de două ori "<annotation icon="home_icon">"butonul ecran de pornire"</annotation>" pentru comenzi"</string>
+    <string name="pip_move" msgid="158770205886688553">"Mută"</string>
+    <string name="pip_expand" msgid="1051966011679297308">"Extinde"</string>
+    <string name="pip_collapse" msgid="3903295106641385962">"Restrânge"</string>
+    <string name="pip_edu_text" msgid="3672999496647508701">" Apasă de două ori "<annotation icon="home_icon">"butonul ecran de pornire"</annotation>" pentru comenzi"</string>
     <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Meniu picture-in-picture."</string>
-    <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mutați spre stânga"</string>
-    <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mutați spre dreapta"</string>
-    <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mutați în sus"</string>
-    <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mutați în jos"</string>
+    <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mută spre stânga"</string>
+    <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mută spre dreapta"</string>
+    <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mută în sus"</string>
+    <string name="a11y_action_pip_move_down" msgid="3858802832725159740">"Mută în jos"</string>
     <string name="a11y_action_pip_move_done" msgid="1486845365134416210">"Gata"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
index 9230c22..ca977ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
@@ -179,6 +179,14 @@
     }
 
     /**
+     * Returns the {@link DisplayAreaInfo} of the {@link DisplayAreaInfo#displayId}.
+     */
+    @Nullable
+    public DisplayAreaInfo getDisplayAreaInfo(int displayId) {
+        return mDisplayAreasInfo.get(displayId);
+    }
+
+    /**
      * Applies the {@link DisplayAreaInfo} to the {@link DisplayAreaContext} specified by
      * {@link DisplayAreaInfo#displayId}.
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 4367936..dec1e38 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -44,6 +44,7 @@
 import android.util.SparseArray;
 import android.view.SurfaceControl;
 import android.window.ITaskOrganizerController;
+import android.window.ScreenCapture;
 import android.window.StartingWindowInfo;
 import android.window.StartingWindowRemovalInfo;
 import android.window.TaskAppearedInfo;
@@ -474,7 +475,7 @@
      * Take a screenshot of a task.
      */
     public void screenshotTask(RunningTaskInfo taskInfo, Rect crop,
-            Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) {
+            Consumer<ScreenCapture.ScreenshotHardwareBuffer> consumer) {
         final TaskAppearedInfo info = mTasks.get(taskInfo.taskId);
         if (info == null) {
             return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
index a8764e0..d76ad3d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
@@ -517,7 +517,9 @@
         getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
     }
 
-    ActivityManager.RunningTaskInfo getTaskInfo() {
+    /** Returns the task info for the task in the TaskView. */
+    @Nullable
+    public ActivityManager.RunningTaskInfo getTaskInfo() {
         return mTaskInfo;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
index e0004fc..521a65c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
@@ -16,7 +16,8 @@
 
 package com.android.wm.shell.activityembedding;
 
-import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;
+import static android.window.TransitionInfo.FLAG_FILLS_TASK;
+import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
 
 import static java.util.Objects.requireNonNull;
 
@@ -84,12 +85,23 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        // TODO(b/207070762) Handle AE animation as a part of other transitions.
-        // Only handle the transition if all containers are embedded.
+        boolean containsEmbeddingSplit = false;
         for (TransitionInfo.Change change : info.getChanges()) {
-            if (!isEmbedded(change)) {
+            if (!change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)) {
+                // Only animate the transition if all changes are in a Task with ActivityEmbedding.
                 return false;
             }
+            if (!containsEmbeddingSplit && !change.hasFlags(FLAG_FILLS_TASK)) {
+                // Whether the Task contains any ActivityEmbedding split before or after the
+                // transition.
+                containsEmbeddingSplit = true;
+            }
+        }
+        if (!containsEmbeddingSplit) {
+            // Let the system to play the default animation if there is no ActivityEmbedding split
+            // window. This allows to play the app customized animation when there is no embedding,
+            // such as the device is in a folded state.
+            return false;
         }
 
         // Start ActivityEmbedding animation.
@@ -119,8 +131,4 @@
         }
         callback.onTransitionFinished(null /* wct */, null /* wctCB */);
     }
-
-    private static boolean isEmbedded(@NonNull TransitionInfo.Change change) {
-        return (change.getFlags() & FLAG_IS_EMBEDDED) != 0;
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index cfbe1b3..54c91dd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -53,13 +53,13 @@
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
-import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
+import android.window.ScreenCapture;
 
 import androidx.annotation.Nullable;
 
@@ -508,7 +508,7 @@
 
     /** Return a GraphicBuffer with the contents of the task view surface. */
     @Nullable
-    SurfaceControl.ScreenshotHardwareBuffer snapshotActivitySurface() {
+    ScreenCapture.ScreenshotHardwareBuffer snapshotActivitySurface() {
         if (mIsOverflow) {
             // For now, just snapshot the view and return it as a hw buffer so that the animation
             // code for both the tasks and overflow can be the same
@@ -517,7 +517,7 @@
                     p.beginRecording(mOverflowView.getWidth(), mOverflowView.getHeight()));
             p.endRecording();
             Bitmap snapshot = Bitmap.createBitmap(p);
-            return new SurfaceControl.ScreenshotHardwareBuffer(
+            return new ScreenCapture.ScreenshotHardwareBuffer(
                     snapshot.getHardwareBuffer(),
                     snapshot.getColorSpace(),
                     false /* containsSecureLayers */,
@@ -526,7 +526,7 @@
         if (mTaskView == null || mTaskView.getSurfaceControl() == null) {
             return null;
         }
-        return SurfaceControl.captureLayers(
+        return ScreenCapture.captureLayers(
                 mTaskView.getSurfaceControl(),
                 new Rect(0, 0, mTaskView.getWidth(), mTaskView.getHeight()),
                 1 /* scale */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index aeaf6ed..2d9c2a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -51,7 +51,6 @@
 import android.view.Choreographer;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
-import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
@@ -64,6 +63,7 @@
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
+import android.window.ScreenCapture;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -244,7 +244,7 @@
      * Buffer containing a screenshot of the animating-out bubble. This is drawn into the
      * SurfaceView during animations.
      */
-    private SurfaceControl.ScreenshotHardwareBuffer mAnimatingOutBubbleBuffer;
+    private ScreenCapture.ScreenshotHardwareBuffer mAnimatingOutBubbleBuffer;
 
     private BubbleFlyoutView mFlyout;
     /** Runnable that fades out the flyout and then sets it to GONE. */
@@ -1270,7 +1270,7 @@
         }
         final boolean seen = getPrefBoolean(ManageEducationViewKt.PREF_MANAGED_EDUCATION);
         final boolean shouldShow = (!seen || BubbleDebugConfig.forceShowUserEducation(mContext))
-                && mExpandedBubble != null;
+                && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null;
         if (BubbleDebugConfig.DEBUG_USER_EDUCATION) {
             Log.d(TAG, "Show manage edu: " + shouldShow);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
index 063dac3..ab194df 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
@@ -24,8 +24,8 @@
 import android.view.Gravity
 import android.view.View
 import android.view.ViewGroup
-import android.view.WindowManager
 import android.view.WindowInsets
+import android.view.WindowManager
 import android.widget.FrameLayout
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY
@@ -41,6 +41,7 @@
 
     var circle = DismissCircleView(context)
     var isShowing = false
+    var targetSizeResId: Int
 
     private val animator = PhysicsAnimator.getInstance(circle)
     private val spring = PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_LOW_BOUNCY)
@@ -70,7 +71,8 @@
         setVisibility(View.INVISIBLE)
         setBackgroundDrawable(gradientDrawable)
 
-        val targetSize: Int = resources.getDimensionPixelSize(R.dimen.dismiss_circle_size)
+        targetSizeResId = R.dimen.dismiss_circle_size
+        val targetSize: Int = resources.getDimensionPixelSize(targetSizeResId)
         addView(circle, LayoutParams(targetSize, targetSize,
                 Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL))
         // start with circle offscreen so it's animated up
@@ -126,7 +128,7 @@
         layoutParams.height = resources.getDimensionPixelSize(
                 R.dimen.floating_dismiss_gradient_height)
 
-        val targetSize: Int = resources.getDimensionPixelSize(R.dimen.dismiss_circle_size)
+        val targetSize = resources.getDimensionPixelSize(targetSizeResId)
         circle.layoutParams.width = targetSize
         circle.layoutParams.height = targetSize
         circle.requestLayout()
@@ -153,4 +155,4 @@
         setPadding(0, 0, 0, navInset.bottom +
                 resources.getDimensionPixelSize(R.dimen.floating_dismiss_bottom_margin))
     }
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java
index 2a1bf0e..fad3dee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java
@@ -19,6 +19,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.view.SurfaceControl;
+import android.window.ScreenCapture;
 
 import java.util.function.Consumer;
 
@@ -35,9 +36,9 @@
      * @param consumer Consumer for the captured buffer
      */
     public static void captureLayer(SurfaceControl sc, Rect crop,
-            Consumer<SurfaceControl.ScreenshotHardwareBuffer> consumer) {
-        consumer.accept(SurfaceControl.captureLayers(
-                new SurfaceControl.LayerCaptureArgs.Builder(sc)
+            Consumer<ScreenCapture.ScreenshotHardwareBuffer> consumer) {
+        consumer.accept(ScreenCapture.captureLayers(
+                new ScreenCapture.LayerCaptureArgs.Builder(sc)
                     .setSourceCrop(crop)
                     .setCaptureSecureLayers(true)
                     .setAllowProtected(true)
@@ -45,7 +46,7 @@
     }
 
     private static class BufferConsumer implements
-            Consumer<SurfaceControl.ScreenshotHardwareBuffer> {
+            Consumer<ScreenCapture.ScreenshotHardwareBuffer> {
         SurfaceControl mScreenshot = null;
         SurfaceControl.Transaction mTransaction;
         SurfaceControl mSurfaceControl;
@@ -61,7 +62,7 @@
         }
 
         @Override
-        public void accept(SurfaceControl.ScreenshotHardwareBuffer buffer) {
+        public void accept(ScreenCapture.ScreenshotHardwareBuffer buffer) {
             if (buffer == null || buffer.getHardwareBuffer() == null) {
                 return;
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index c39602032..7c3c14e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -55,6 +55,8 @@
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
 import com.android.wm.shell.compatui.CompatUIController;
+import com.android.wm.shell.desktopmode.DesktopMode;
+import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelperController;
 import com.android.wm.shell.draganddrop.DragAndDropController;
@@ -477,11 +479,12 @@
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
             TaskStackListenerImpl taskStackListener,
+            Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
             @ShellMainThread ShellExecutor mainExecutor
     ) {
         return Optional.ofNullable(
                 RecentTasksController.create(context, shellInit, shellCommandHandler,
-                        taskStackListener, mainExecutor));
+                        taskStackListener, desktopModeTaskRepository, mainExecutor));
     }
 
     //
@@ -666,6 +669,24 @@
     }
 
     //
+    // Desktop mode (optional feature)
+    //
+
+    @BindsOptionalOf
+    @DynamicOverride
+    abstract DesktopModeTaskRepository optionalDesktopModeTaskRepository();
+
+    @WMSingleton
+    @Provides
+    static Optional<DesktopModeTaskRepository> providesDesktopModeTaskRepository(
+            @DynamicOverride Optional<DesktopModeTaskRepository> desktopModeTaskRepository) {
+        if (DesktopMode.IS_SUPPORTED) {
+            return desktopModeTaskRepository;
+        }
+        return Optional.empty();
+    }
+
+    //
     // Misc
     //
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 18ce364..35e88e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -27,7 +27,6 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.launcher3.icons.IconProvider;
-import com.android.wm.shell.RootDisplayAreaOrganizer;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.TaskViewTransitions;
@@ -51,6 +50,7 @@
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.desktopmode.DesktopMode;
 import com.android.wm.shell.desktopmode.DesktopModeController;
+import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.freeform.FreeformComponents;
 import com.android.wm.shell.freeform.FreeformTaskListener;
@@ -220,14 +220,14 @@
             Context context,
             ShellInit shellInit,
             ShellTaskOrganizer shellTaskOrganizer,
-            Optional<RecentTasksController> recentTasksController,
+            Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
             WindowDecorViewModel<?> windowDecorViewModel) {
         // TODO(b/238217847): Temporarily add this check here until we can remove the dynamic
         //                    override for this controller from the base module
         ShellInit init = FreeformComponents.isFreeformEnabled(context)
                 ? shellInit
                 : null;
-        return new FreeformTaskListener<>(init, shellTaskOrganizer, recentTasksController,
+        return new FreeformTaskListener<>(init, shellTaskOrganizer, desktopModeTaskRepository,
                 windowDecorViewModel);
     }
 
@@ -598,18 +598,25 @@
     static Optional<DesktopModeController> provideDesktopModeController(
             Context context, ShellInit shellInit,
             ShellTaskOrganizer shellTaskOrganizer,
-            RootDisplayAreaOrganizer rootDisplayAreaOrganizer,
-            @ShellMainThread Handler mainHandler
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+            @ShellMainThread Handler mainHandler,
+            Transitions transitions
     ) {
         if (DesktopMode.IS_SUPPORTED) {
             return Optional.of(new DesktopModeController(context, shellInit, shellTaskOrganizer,
-                    rootDisplayAreaOrganizer,
-                    mainHandler));
+                    rootTaskDisplayAreaOrganizer, mainHandler, transitions));
         } else {
             return Optional.empty();
         }
     }
 
+    @WMSingleton
+    @Provides
+    @DynamicOverride
+    static DesktopModeTaskRepository provideDesktopModeTaskRepository() {
+        return new DesktopModeTaskRepository();
+    }
+
     //
     // Misc
     //
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
index 7d34ea4..6e44d58 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
@@ -18,25 +18,29 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_CHANGE;
 
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
 
+import android.app.WindowConfiguration;
 import android.content.Context;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.window.DisplayAreaInfo;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
-import com.android.wm.shell.RootDisplayAreaOrganizer;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.Transitions;
 
 /**
  * Handles windowing changes when desktop mode system setting changes
@@ -45,17 +49,20 @@
 
     private final Context mContext;
     private final ShellTaskOrganizer mShellTaskOrganizer;
-    private final RootDisplayAreaOrganizer mRootDisplayAreaOrganizer;
+    private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
     private final SettingsObserver mSettingsObserver;
+    private final Transitions mTransitions;
 
     public DesktopModeController(Context context, ShellInit shellInit,
             ShellTaskOrganizer shellTaskOrganizer,
-            RootDisplayAreaOrganizer rootDisplayAreaOrganizer,
-            @ShellMainThread Handler mainHandler) {
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+            @ShellMainThread Handler mainHandler,
+            Transitions transitions) {
         mContext = context;
         mShellTaskOrganizer = shellTaskOrganizer;
-        mRootDisplayAreaOrganizer = rootDisplayAreaOrganizer;
+        mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
         mSettingsObserver = new SettingsObserver(mContext, mainHandler);
+        mTransitions = transitions;
         shellInit.addInitCallback(this::onInit, this);
     }
 
@@ -87,9 +94,30 @@
             wct.merge(mShellTaskOrganizer.prepareClearBoundsForStandardTasks(displayId),
                     true /* transfer */);
         }
-        wct.merge(mRootDisplayAreaOrganizer.prepareWindowingModeChange(displayId,
-                targetWindowingMode), true /* transfer */);
-        mRootDisplayAreaOrganizer.applyTransaction(wct);
+        prepareWindowingModeChange(wct, displayId, targetWindowingMode);
+        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+            mTransitions.startTransition(TRANSIT_CHANGE, wct, null);
+        } else {
+            mRootTaskDisplayAreaOrganizer.applyTransaction(wct);
+        }
+    }
+
+    private void prepareWindowingModeChange(WindowContainerTransaction wct,
+            int displayId, @WindowConfiguration.WindowingMode int windowingMode) {
+        DisplayAreaInfo displayAreaInfo = mRootTaskDisplayAreaOrganizer
+                .getDisplayAreaInfo(displayId);
+        if (displayAreaInfo == null) {
+            ProtoLog.e(WM_SHELL_DESKTOP_MODE,
+                    "unable to update windowing mode for display %d display not found", displayId);
+            return;
+        }
+
+        ProtoLog.d(WM_SHELL_DESKTOP_MODE,
+                "setWindowingMode: displayId=%d current wmMode=%d new wmMode=%d", displayId,
+                displayAreaInfo.configuration.windowConfiguration.getWindowingMode(),
+                windowingMode);
+
+        wct.setWindowingMode(displayAreaInfo.token, windowingMode);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
new file mode 100644
index 0000000..988601c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode
+
+import android.util.ArraySet
+
+/**
+ * Keeps track of task data related to desktop mode.
+ */
+class DesktopModeTaskRepository {
+
+    /**
+     * Set of task ids that are marked as active in desktop mode.
+     * Active tasks in desktop mode are freeform tasks that are visible or have been visible after
+     * desktop mode was activated.
+     * Task gets removed from this list when it vanishes. Or when desktop mode is turned off.
+     */
+    private val activeTasks = ArraySet<Int>()
+    private val listeners = ArraySet<Listener>()
+
+    /**
+     * Add a [Listener] to be notified of updates to the repository.
+     */
+    fun addListener(listener: Listener) {
+        listeners.add(listener)
+    }
+
+    /**
+     * Remove a previously registered [Listener]
+     */
+    fun removeListener(listener: Listener) {
+        listeners.remove(listener)
+    }
+
+    /**
+     * Mark a task with given [taskId] as active.
+     */
+    fun addActiveTask(taskId: Int) {
+        val added = activeTasks.add(taskId)
+        if (added) {
+            listeners.onEach { it.onActiveTasksChanged() }
+        }
+    }
+
+    /**
+     * Remove task with given [taskId] from active tasks.
+     */
+    fun removeActiveTask(taskId: Int) {
+        val removed = activeTasks.remove(taskId)
+        if (removed) {
+            listeners.onEach { it.onActiveTasksChanged() }
+        }
+    }
+
+    /**
+     * Check if a task with the given [taskId] was marked as an active task
+     */
+    fun isActiveTask(taskId: Int): Boolean {
+        return activeTasks.contains(taskId)
+    }
+
+    /**
+     * Get a set of the active tasks
+     */
+    fun getActiveTasks(): ArraySet<Int> {
+        return ArraySet(activeTasks)
+    }
+
+    /**
+     * Defines interface for classes that can listen to changes in repository state.
+     */
+    interface Listener {
+        fun onActiveTasksChanged()
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index 435d8ea..62bf517 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -17,6 +17,8 @@
 package com.android.wm.shell.draganddrop;
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED;
+import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -263,6 +265,9 @@
             mStarter.startShortcut(packageName, id, position, opts, user);
         } else {
             final PendingIntent launchIntent = intent.getParcelableExtra(EXTRA_PENDING_INTENT);
+            // Put BAL flags to avoid activity start aborted.
+            opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);
+            opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, true);
             mStarter.startIntent(launchIntent, null /* fillIntent */, position, opts);
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 1baac71..f58719b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -29,8 +29,8 @@
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.desktopmode.DesktopMode;
+import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
@@ -49,7 +49,7 @@
     private static final String TAG = "FreeformTaskListener";
 
     private final ShellTaskOrganizer mShellTaskOrganizer;
-    private final Optional<RecentTasksController> mRecentTasksOptional;
+    private final Optional<DesktopModeTaskRepository> mDesktopModeTaskRepository;
     private final WindowDecorViewModel<T> mWindowDecorationViewModel;
 
     private final SparseArray<State<T>> mTasks = new SparseArray<>();
@@ -64,11 +64,11 @@
     public FreeformTaskListener(
             ShellInit shellInit,
             ShellTaskOrganizer shellTaskOrganizer,
-            Optional<RecentTasksController> recentTasksController,
+            Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
             WindowDecorViewModel<T> windowDecorationViewModel) {
         mShellTaskOrganizer = shellTaskOrganizer;
         mWindowDecorationViewModel = windowDecorationViewModel;
-        mRecentTasksOptional = recentTasksController;
+        mDesktopModeTaskRepository = desktopModeTaskRepository;
         if (shellInit != null) {
             shellInit.addInitCallback(this::onInit, this);
         }
@@ -93,7 +93,7 @@
         if (DesktopMode.IS_SUPPORTED && taskInfo.isVisible) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                     "Adding active freeform task: #%d", taskInfo.taskId);
-            mRecentTasksOptional.ifPresent(rt -> rt.addActiveFreeformTask(taskInfo.taskId));
+            mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId));
         }
     }
 
@@ -126,7 +126,7 @@
         if (DesktopMode.IS_SUPPORTED) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                     "Removing active freeform task: #%d", taskInfo.taskId);
-            mRecentTasksOptional.ifPresent(rt -> rt.removeActiveFreeformTask(taskInfo.taskId));
+            mDesktopModeTaskRepository.ifPresent(it -> it.removeActiveTask(taskInfo.taskId));
         }
 
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
@@ -154,7 +154,7 @@
             if (taskInfo.isVisible) {
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                         "Adding active freeform task: #%d", taskInfo.taskId);
-                mRecentTasksOptional.ifPresent(rt -> rt.addActiveFreeformTask(taskInfo.taskId));
+                mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTask(taskInfo.taskId));
             }
         }
     }
@@ -191,15 +191,19 @@
      *
      * @param change the change of this task transition that needs to have the task layer as the
      *               leash
-     * @return {@code true} if it adopts the window decoration; {@code false} otherwise
+     * @return {@code true} if it creates the window decoration; {@code false} otherwise
      */
-    void createWindowDecoration(
+    boolean createWindowDecoration(
             TransitionInfo.Change change,
             SurfaceControl.Transaction startT,
             SurfaceControl.Transaction finishT) {
         final State<T> state = createOrUpdateTaskState(change.getTaskInfo(), change.getLeash());
+        if (state.mWindowDecoration != null) {
+            return false;
+        }
         state.mWindowDecoration = mWindowDecorationViewModel.createWindowDecoration(
                 state.mTaskInfo, state.mLeash, startT, finishT);
+        return true;
     }
 
     /**
@@ -222,6 +226,9 @@
             windowDecor =
                     mWindowDecorOfVanishedTasks.removeReturnOld(taskInfo.taskId);
         }
+        if (windowDecor == null) {
+            return null;
+        }
         mWindowDecorationViewModel.setupWindowDecorationForTransition(
                 taskInfo, startT, finishT, windowDecor);
         return windowDecor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
index a780ec1..17d6067 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
@@ -26,6 +26,7 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.window.TransitionInfo;
+import android.window.WindowContainerToken;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
@@ -80,6 +81,7 @@
             @NonNull SurfaceControl.Transaction startT,
             @NonNull SurfaceControl.Transaction finishT) {
         final ArrayList<AutoCloseable> windowDecors = new ArrayList<>();
+        final ArrayList<WindowContainerToken> taskParents = new ArrayList<>();
         for (TransitionInfo.Change change : info.getChanges()) {
             if ((change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0) {
                 continue;
@@ -89,9 +91,22 @@
             if (taskInfo == null || taskInfo.taskId == -1) {
                 continue;
             }
+            // Filter out non-leaf tasks. Freeform/fullscreen don't nest tasks, but split-screen
+            // does, so this prevents adding duplicate captions in that scenario.
+            if (change.getParent() != null
+                    && info.getChange(change.getParent()).getTaskInfo() != null) {
+                // This logic relies on 2 assumptions: 1 is that child tasks will be visited before
+                // parents (due to how z-order works). 2 is that no non-tasks are interleaved
+                // between tasks (hierarchically).
+                taskParents.add(change.getContainer());
+            }
+            if (taskParents.contains(change.getContainer())) {
+                continue;
+            }
 
             switch (change.getMode()) {
                 case WindowManager.TRANSIT_OPEN:
+                case WindowManager.TRANSIT_TO_FRONT:
                     onOpenTransitionReady(change, startT, finishT);
                     break;
                 case WindowManager.TRANSIT_CLOSE: {
@@ -154,20 +169,28 @@
 
         boolean adopted = false;
         final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
-        if (type == Transitions.TRANSIT_MAXIMIZE
-                && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+        if (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
             windowDecor = mFreeformTaskListener.giveWindowDecoration(
                     change.getTaskInfo(), startT, finishT);
-            adopted = mFullscreenTaskListener.adoptWindowDecoration(
-                    change, startT, finishT, windowDecor);
+            if (windowDecor != null) {
+                adopted = mFullscreenTaskListener.adoptWindowDecoration(
+                        change, startT, finishT, windowDecor);
+            } else {
+                // will return false if it already has the window decor.
+                adopted = mFullscreenTaskListener.createWindowDecoration(change, startT, finishT);
+            }
         }
 
-        if (type == Transitions.TRANSIT_RESTORE_FROM_MAXIMIZE
-                && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+        if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
             windowDecor = mFullscreenTaskListener.giveWindowDecoration(
                     change.getTaskInfo(), startT, finishT);
-            adopted = mFreeformTaskListener.adoptWindowDecoration(
-                    change, startT, finishT, windowDecor);
+            if (windowDecor != null) {
+                adopted = mFreeformTaskListener.adoptWindowDecoration(
+                        change, startT, finishT, windowDecor);
+            } else {
+                // will return false if it already has the window decor.
+                adopted = mFreeformTaskListener.createWindowDecoration(change, startT, finishT);
+            }
         }
 
         if (!adopted) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index e9f9bb5..76e296b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -16,8 +16,6 @@
 
 package com.android.wm.shell.fullscreen;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
 import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;
 
@@ -107,13 +105,14 @@
 
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
         updateRecentsForVisibleFullscreenTask(taskInfo);
-        if (shouldShowWindowDecor(taskInfo) && mWindowDecorViewModelOptional.isPresent()) {
+        if (mWindowDecorViewModelOptional.isPresent()) {
             SurfaceControl.Transaction t = new SurfaceControl.Transaction();
             state.mWindowDecoration =
                     mWindowDecorViewModelOptional.get().createWindowDecoration(taskInfo,
                             leash, t, t);
             t.apply();
-        } else {
+        }
+        if (state.mWindowDecoration == null) {
             mSyncQueue.runInSync(t -> {
                 // Reset several properties back to fullscreen (PiP, for example, leaves all these
                 // properties in a bad state).
@@ -174,17 +173,23 @@
      *
      * @param change the change of this task transition that needs to have the task layer as the
      *               leash
+     * @return {@code true} if a decoration was actually created.
      */
-    public void createWindowDecoration(TransitionInfo.Change change,
+    public boolean createWindowDecoration(TransitionInfo.Change change,
             SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) {
         final State<T> state = createOrUpdateTaskState(change.getTaskInfo(), change.getLeash());
-        if (!mWindowDecorViewModelOptional.isPresent()
-                || !shouldShowWindowDecor(state.mTaskInfo)) {
-            return;
+        if (!mWindowDecorViewModelOptional.isPresent()) return false;
+        if (state.mWindowDecoration != null) {
+            // Already has a decoration.
+            return false;
         }
-
-        state.mWindowDecoration = mWindowDecorViewModelOptional.get().createWindowDecoration(
+        T newWindowDecor = mWindowDecorViewModelOptional.get().createWindowDecoration(
                 state.mTaskInfo, state.mLeash, startT, finishT);
+        if (newWindowDecor != null) {
+            state.mWindowDecoration = newWindowDecor;
+            return true;
+        }
+        return false;
     }
 
     /**
@@ -202,8 +207,7 @@
             SurfaceControl.Transaction startT,
             SurfaceControl.Transaction finishT,
             @Nullable AutoCloseable windowDecor) {
-        if (!mWindowDecorViewModelOptional.isPresent()
-                || !shouldShowWindowDecor(change.getTaskInfo())) {
+        if (!mWindowDecorViewModelOptional.isPresent()) {
             return false;
         }
         final State<T> state = createOrUpdateTaskState(change.getTaskInfo(), change.getLeash());
@@ -214,8 +218,11 @@
                     state.mTaskInfo, startT, finishT, state.mWindowDecoration);
             return true;
         } else {
-            state.mWindowDecoration = mWindowDecorViewModelOptional.get().createWindowDecoration(
+            T newWindowDecor = mWindowDecorViewModelOptional.get().createWindowDecoration(
                     state.mTaskInfo, state.mLeash, startT, finishT);
+            if (newWindowDecor != null) {
+                state.mWindowDecoration = newWindowDecor;
+            }
             return false;
         }
     }
@@ -256,7 +263,7 @@
             windowDecor =
                     mWindowDecorOfVanishedTasks.removeReturnOld(taskInfo.taskId);
         }
-        if (mWindowDecorViewModelOptional.isPresent()) {
+        if (mWindowDecorViewModelOptional.isPresent() && windowDecor != null) {
             mWindowDecorViewModelOptional.get().setupWindowDecorationForTransition(
                     taskInfo, startT, finishT, windowDecor);
         }
@@ -336,10 +343,5 @@
         return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN);
     }
 
-    private static boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
-        return taskInfo.getConfiguration().windowConfiguration.getDisplayWindowingMode()
-                == WINDOWING_MODE_FREEFORM;
-    }
-
 
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index f170e77..1a52d8c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -324,6 +324,19 @@
         return mPipTransitionController;
     }
 
+    /**
+     * Returns true if the PiP window is currently being animated.
+     */
+    public boolean isAnimating() {
+        // TODO(b/183746978) move this to PipAnimationController, and inject that in PipController
+        PipAnimationController.PipTransitionAnimator animator =
+                mPipAnimationController.getCurrentAnimator();
+        if (animator != null && animator.isRunning()) {
+            return true;
+        }
+        return false;
+    }
+
     public Rect getCurrentOrAnimatingBounds() {
         PipAnimationController.PipTransitionAnimator animator =
                 mPipAnimationController.getCurrentAnimator();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
index 6dd02e4..84071e0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
@@ -54,13 +54,8 @@
                 ? pipBoundsAlgorithm.getEntryDestinationBoundsIgnoringKeepClearAreas()
                 : pipBoundsState.getBounds();
         float snapFraction = pipBoundsAlgorithm.getSnapFraction(startingBounds);
-        int verticalGravity;
+        int verticalGravity = Gravity.BOTTOM;
         int horizontalGravity;
-        if (snapFraction < 1.5f || snapFraction >= 3.5f) {
-            verticalGravity = Gravity.NO_GRAVITY;
-        } else {
-            verticalGravity = Gravity.BOTTOM;
-        }
         if (snapFraction >= 0.5f && snapFraction < 2.5f) {
             horizontalGravity = Gravity.RIGHT;
         } else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 3d879b6..bc8191d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -149,7 +149,42 @@
     private final Rect mTmpInsetBounds = new Rect();
     private final int mEnterAnimationDuration;
 
-    private final Runnable mMovePipInResponseToKeepClearAreasChangeCallback;
+    private final Runnable mMovePipInResponseToKeepClearAreasChangeCallback =
+            this::onKeepClearAreasChangedCallback;
+
+    private void onKeepClearAreasChangedCallback() {
+        if (!mEnablePipKeepClearAlgorithm) {
+            // early bail out if the keep clear areas feature is disabled
+            return;
+        }
+        // if there is another animation ongoing, wait for it to finish and try again
+        if (mPipTaskOrganizer.isAnimating()) {
+            mMainExecutor.removeCallbacks(
+                    mMovePipInResponseToKeepClearAreasChangeCallback);
+            mMainExecutor.executeDelayed(
+                    mMovePipInResponseToKeepClearAreasChangeCallback,
+                    PIP_KEEP_CLEAR_AREAS_DELAY);
+            return;
+        }
+        updatePipPositionForKeepClearAreas();
+    }
+
+    private void updatePipPositionForKeepClearAreas() {
+        if (!mEnablePipKeepClearAlgorithm) {
+            // early bail out if the keep clear areas feature is disabled
+            return;
+        }
+        // only move if already in pip, other transitions account for keep clear areas
+        if (mPipTransitionState.hasEnteredPip()) {
+            Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState,
+                    mPipBoundsAlgorithm);
+            // only move if the bounds are actually different
+            if (destBounds != mPipBoundsState.getBounds()) {
+                mPipTaskOrganizer.scheduleAnimateResizePip(destBounds,
+                        mEnterAnimationDuration, null);
+            }
+        }
+    }
 
     private boolean mIsInFixedRotation;
     private PipAnimationListener mPinnedStackAnimationRecentsCallback;
@@ -302,6 +337,9 @@
         public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
             mPipBoundsState.setImeVisibility(imeVisible, imeHeight);
             mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
+            if (imeVisible) {
+                updatePipPositionForKeepClearAreas();
+            }
         }
 
         @Override
@@ -414,15 +452,6 @@
 
         mEnterAnimationDuration = mContext.getResources()
                 .getInteger(R.integer.config_pipEnterAnimationDuration);
-        mMovePipInResponseToKeepClearAreasChangeCallback = () -> {
-            // only move if already in pip, other transitions account for keep clear areas
-            if (mPipTransitionState.hasEnteredPip()) {
-                Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState,
-                        mPipBoundsAlgorithm);
-                mPipTaskOrganizer.scheduleAnimateResizePip(destBounds,
-                        mEnterAnimationDuration, null);
-            }
-        };
         mPipParamsChangedForwarder = pipParamsChangedForwarder;
         mDisplayInsetsController = displayInsetsController;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 84d9217..1f3f31e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -34,6 +34,7 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.os.SystemProperties;
 import android.provider.DeviceConfig;
 import android.util.Size;
 import android.view.DisplayCutout;
@@ -70,6 +71,9 @@
     private static final String TAG = "PipTouchHandler";
     private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f;
 
+    private static final boolean ENABLE_PIP_KEEP_CLEAR_ALGORITHM =
+            SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", false);
+
     // Allow PIP to resize to a slightly bigger state upon touch
     private boolean mEnableResize;
     private final Context mContext;
@@ -426,6 +430,9 @@
             if (mTouchState.isUserInteracting()) {
                 // Defer the update of the current movement bounds until after the user finishes
                 // touching the screen
+            } else if (ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
+                // Ignore moving PiP if keep clear algorithm is enabled, since IME and shelf height
+                // now are accounted for in the keep clear algorithm calculations
             } else {
                 final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu();
                 final Rect toMovementBounds = new Rect();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 27bc1a1..ff4b2ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -44,6 +44,7 @@
 import com.android.wm.shell.common.annotations.ExternalThread;
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.desktopmode.DesktopMode;
+import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellInit;
@@ -53,19 +54,20 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 /**
  * Manages the recent task list from the system, caching it as necessary.
  */
 public class RecentTasksController implements TaskStackListenerCallback,
-        RemoteCallable<RecentTasksController> {
+        RemoteCallable<RecentTasksController>, DesktopModeTaskRepository.Listener {
     private static final String TAG = RecentTasksController.class.getSimpleName();
 
     private final Context mContext;
     private final ShellCommandHandler mShellCommandHandler;
+    private final Optional<DesktopModeTaskRepository> mDesktopModeTaskRepository;
     private final ShellExecutor mMainExecutor;
     private final TaskStackListenerImpl mTaskStackListener;
     private final RecentTasks mImpl = new RecentTasksImpl();
@@ -84,15 +86,6 @@
     private final Map<Integer, SplitBounds> mTaskSplitBoundsMap = new HashMap<>();
 
     /**
-     * Set of taskId's that have been launched in freeform mode.
-     * This includes tasks that are currently running, visible and in freeform mode. And also
-     * includes tasks that are running in the background, are no longer visible, but at some point
-     * were visible to the user.
-     * This is used to decide which freeform apps belong to the user's desktop.
-     */
-    private final HashSet<Integer> mActiveFreeformTasks = new HashSet<>();
-
-    /**
      * Creates {@link RecentTasksController}, returns {@code null} if the feature is not
      * supported.
      */
@@ -102,24 +95,27 @@
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
             TaskStackListenerImpl taskStackListener,
+            Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
             @ShellMainThread ShellExecutor mainExecutor
     ) {
         if (!context.getResources().getBoolean(com.android.internal.R.bool.config_hasRecents)) {
             return null;
         }
         return new RecentTasksController(context, shellInit, shellCommandHandler, taskStackListener,
-                mainExecutor);
+                desktopModeTaskRepository, mainExecutor);
     }
 
     RecentTasksController(Context context,
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
             TaskStackListenerImpl taskStackListener,
+            Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
             ShellExecutor mainExecutor) {
         mContext = context;
         mShellCommandHandler = shellCommandHandler;
         mIsDesktopMode = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
         mTaskStackListener = taskStackListener;
+        mDesktopModeTaskRepository = desktopModeTaskRepository;
         mMainExecutor = mainExecutor;
         shellInit.addInitCallback(this::onInit, this);
     }
@@ -131,6 +127,7 @@
     private void onInit() {
         mShellCommandHandler.addDumpCallback(this::dump, this);
         mTaskStackListener.addListener(this);
+        mDesktopModeTaskRepository.ifPresent(it -> it.addListener(this));
     }
 
     /**
@@ -217,19 +214,8 @@
         notifyRecentTasksChanged();
     }
 
-    /**
-     * Mark a task with given {@code taskId} as active in freeform
-     */
-    public void addActiveFreeformTask(int taskId) {
-        mActiveFreeformTasks.add(taskId);
-        notifyRecentTasksChanged();
-    }
-
-    /**
-     * Remove task with given {@code taskId} from active freeform tasks
-     */
-    public void removeActiveFreeformTask(int taskId) {
-        mActiveFreeformTasks.remove(taskId);
+    @Override
+    public void onActiveTasksChanged() {
         notifyRecentTasksChanged();
     }
 
@@ -312,7 +298,8 @@
                 continue;
             }
 
-            if (desktopModeActive && mActiveFreeformTasks.contains(taskInfo.taskId)) {
+            if (desktopModeActive && mDesktopModeTaskRepository.isPresent()
+                    && mDesktopModeTaskRepository.get().isActiveTask(taskInfo.taskId)) {
                 // Freeform tasks will be added as a separate entry
                 freeformTasks.add(taskInfo);
                 continue;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index b0080b2..e7ec15e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -45,11 +45,6 @@
                 iconProvider);
     }
 
-    @Override
-    void dismiss(WindowContainerTransaction wct, boolean toTop) {
-        deactivate(wct, toTop);
-    }
-
     boolean isActive() {
         return mIsActive;
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index 86efbe0..8639b36 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -42,11 +42,6 @@
                 iconProvider);
     }
 
-    @Override
-    void dismiss(WindowContainerTransaction wct, boolean toTop) {
-        removeAllTasks(wct, toTop);
-    }
-
     boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
         if (mChildrenTaskInfo.size() == 0) return false;
         wct.reparentTasks(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 025e559..991f136 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -133,6 +133,20 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface ExitReason{}
 
+    public static final int ENTER_REASON_UNKNOWN = 0;
+    public static final int ENTER_REASON_MULTI_INSTANCE = 1;
+    public static final int ENTER_REASON_DRAG = 2;
+    public static final int ENTER_REASON_LAUNCHER = 3;
+    /** Acts as a mapping to the actual EnterReasons as defined in the logging proto */
+    @IntDef(value = {
+            ENTER_REASON_MULTI_INSTANCE,
+            ENTER_REASON_DRAG,
+            ENTER_REASON_LAUNCHER,
+            ENTER_REASON_UNKNOWN
+    })
+    public @interface SplitEnterReason {
+    }
+
     private final ShellCommandHandler mShellCommandHandler;
     private final ShellController mShellController;
     private final ShellTaskOrganizer mTaskOrganizer;
@@ -154,7 +168,8 @@
     private StageCoordinator mStageCoordinator;
     // Only used for the legacy recents animation from splitscreen to allow the tasks to be animated
     // outside the bounds of the roots by being reparented into a higher level fullscreen container
-    private SurfaceControl mSplitTasksContainerLayer;
+    private SurfaceControl mGoingToRecentsTasksLayer;
+    private SurfaceControl mStartingSplitTasksLayer;
 
     public SplitScreenController(Context context,
             ShellInit shellInit,
@@ -393,7 +408,7 @@
      */
     public void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
             @Nullable Bundle options, UserHandle user, @NonNull InstanceId instanceId) {
-        mStageCoordinator.getLogger().enterRequested(instanceId);
+        mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER);
         startShortcut(packageName, shortcutId, position, options, user);
     }
 
@@ -441,7 +456,7 @@
      */
     public void startIntent(PendingIntent intent, @Nullable Intent fillInIntent,
             @SplitPosition int position, @Nullable Bundle options, @NonNull InstanceId instanceId) {
-        mStageCoordinator.getLogger().enterRequested(instanceId);
+        mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER);
         startIntent(intent, fillInIntent, position, options);
     }
 
@@ -509,19 +524,53 @@
     }
 
     RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
+        if (ENABLE_SHELL_TRANSITIONS) return null;
+
         if (isSplitScreenVisible()) {
             // Evict child tasks except the top visible one under split root to ensure it could be
             // launched as full screen when switching to it on recents.
             final WindowContainerTransaction wct = new WindowContainerTransaction();
             mStageCoordinator.prepareEvictInvisibleChildTasks(wct);
             mSyncQueue.queue(wct);
+        } else {
+            return null;
         }
-        return reparentSplitTasksForAnimation(apps, false /* enterSplitScreen */);
+
+        SurfaceControl.Transaction t = mTransactionPool.acquire();
+        if (mGoingToRecentsTasksLayer != null) {
+            t.remove(mGoingToRecentsTasksLayer);
+        }
+        mGoingToRecentsTasksLayer = reparentSplitTasksForAnimation(apps, t,
+                "SplitScreenController#onGoingToRecentsLegacy" /* callsite */);
+        t.apply();
+        mTransactionPool.release(t);
+
+        return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
     }
 
     RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
+        if (ENABLE_SHELL_TRANSITIONS) return null;
+
+        int openingApps = 0;
+        for (int i = 0; i < apps.length; ++i) {
+            if (apps[i].mode == MODE_OPENING) openingApps++;
+        }
+        if (openingApps < 2) {
+            // Not having enough apps to enter split screen
+            return null;
+        }
+
+        SurfaceControl.Transaction t = mTransactionPool.acquire();
+        if (mStartingSplitTasksLayer != null) {
+            t.remove(mStartingSplitTasksLayer);
+        }
+        mStartingSplitTasksLayer = reparentSplitTasksForAnimation(apps, t,
+                "SplitScreenController#onStartingSplitLegacy" /* callsite */);
+        t.apply();
+        mTransactionPool.release(t);
+
         try {
-            return reparentSplitTasksForAnimation(apps, true /* enterSplitScreen */);
+            return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
         } finally {
             for (RemoteAnimationTarget appTarget : apps) {
                 if (appTarget.leash != null) {
@@ -531,45 +580,23 @@
         }
     }
 
-    private RemoteAnimationTarget[] reparentSplitTasksForAnimation(RemoteAnimationTarget[] apps,
-            boolean enterSplitScreen) {
-        if (ENABLE_SHELL_TRANSITIONS) return null;
-
-        if (enterSplitScreen) {
-            int openingApps = 0;
-            for (int i = 0; i < apps.length; ++i) {
-                if (apps[i].mode == MODE_OPENING) openingApps++;
-            }
-            if (openingApps < 2) {
-                // Not having enough apps to enter split screen
-                return null;
-            }
-        } else if (!isSplitScreenVisible()) {
-            return null;
-        }
-
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-        if (mSplitTasksContainerLayer != null) {
-            // Remove the previous layer before recreating
-            transaction.remove(mSplitTasksContainerLayer);
-        }
+    private SurfaceControl reparentSplitTasksForAnimation(RemoteAnimationTarget[] apps,
+            SurfaceControl.Transaction t, String callsite) {
         final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession())
                 .setContainerLayer()
                 .setName("RecentsAnimationSplitTasks")
                 .setHidden(false)
-                .setCallsite("SplitScreenController#onGoingtoRecentsLegacy");
+                .setCallsite(callsite);
         mRootTDAOrganizer.attachToDisplayArea(DEFAULT_DISPLAY, builder);
-        mSplitTasksContainerLayer = builder.build();
+        final SurfaceControl splitTasksLayer = builder.build();
 
         for (int i = 0; i < apps.length; ++i) {
             final RemoteAnimationTarget appTarget = apps[i];
-            transaction.reparent(appTarget.leash, mSplitTasksContainerLayer);
-            transaction.setPosition(appTarget.leash, appTarget.screenSpaceBounds.left,
+            t.reparent(appTarget.leash, splitTasksLayer);
+            t.setPosition(appTarget.leash, appTarget.screenSpaceBounds.left,
                     appTarget.screenSpaceBounds.top);
         }
-        transaction.apply();
-        mTransactionPool.release(transaction);
-        return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
+        return splitTasksLayer;
     }
     /**
      * Sets drag info to be logged when splitscreen is entered.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
index 626ccb1..033d743 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java
@@ -17,6 +17,8 @@
 package com.android.wm.shell.splitscreen;
 
 import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__LAUNCHER;
+import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__MULTI_INSTANCE;
+import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__UNKNOWN_ENTER;
 import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW;
 import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED;
 import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED;
@@ -28,6 +30,10 @@
 import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__UNKNOWN_EXIT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
+import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_DRAG;
+import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_LAUNCHER;
+import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_MULTI_INSTANCE;
+import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_UNKNOWN;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED;
@@ -38,6 +44,7 @@
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_UNKNOWN;
 
+import android.annotation.Nullable;
 import android.util.Slog;
 
 import com.android.internal.logging.InstanceId;
@@ -59,7 +66,7 @@
 
     // Drag info
     private @SplitPosition int mDragEnterPosition;
-    private InstanceId mEnterSessionId;
+    private @Nullable InstanceId mEnterSessionId;
 
     // For deduping async events
     private int mLastMainStagePosition = -1;
@@ -67,6 +74,7 @@
     private int mLastSideStagePosition = -1;
     private int mLastSideStageUid = -1;
     private float mLastSplitRatio = -1f;
+    private @SplitScreenController.SplitEnterReason int mEnterReason = ENTER_REASON_UNKNOWN;
 
     public SplitscreenEventLogger() {
         mIdSequence = new InstanceIdSequence(Integer.MAX_VALUE);
@@ -84,15 +92,26 @@
      */
     public void enterRequestedByDrag(@SplitPosition int position, InstanceId enterSessionId) {
         mDragEnterPosition = position;
-        enterRequested(enterSessionId);
+        enterRequested(enterSessionId, ENTER_REASON_DRAG);
     }
 
     /**
      * May be called before logEnter() to indicate that the session was started from launcher.
      * This specifically is for all the scenarios where split started without a drag interaction
      */
-    public void enterRequested(InstanceId enterSessionId) {
+    public void enterRequested(@Nullable InstanceId enterSessionId,
+            @SplitScreenController.SplitEnterReason int enterReason) {
         mEnterSessionId = enterSessionId;
+        mEnterReason = enterReason;
+    }
+
+    /**
+     * @return if an enterSessionId has been set via either
+     *         {@link #enterRequested(InstanceId, int)} or
+     *         {@link #enterRequestedByDrag(int, InstanceId)}
+     */
+    public boolean hasValidEnterSessionId() {
+        return mEnterSessionId != null;
     }
 
     /**
@@ -103,9 +122,7 @@
             @SplitPosition int sideStagePosition, int sideStageUid,
             boolean isLandscape) {
         mLoggerSessionId = mIdSequence.newInstanceId();
-        int enterReason = mDragEnterPosition != SPLIT_POSITION_UNDEFINED
-                ? getDragEnterReasonFromSplitPosition(mDragEnterPosition, isLandscape)
-                : SPLITSCREEN_UICHANGED__ENTER_REASON__LAUNCHER;
+        int enterReason = getLoggerEnterReason(isLandscape);
         updateMainStageState(getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape),
                 mainStageUid);
         updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
@@ -124,6 +141,20 @@
                 mLoggerSessionId.getId());
     }
 
+    private int getLoggerEnterReason(boolean isLandscape) {
+        switch (mEnterReason) {
+            case ENTER_REASON_MULTI_INSTANCE:
+                return SPLITSCREEN_UICHANGED__ENTER_REASON__MULTI_INSTANCE;
+            case ENTER_REASON_LAUNCHER:
+                return SPLITSCREEN_UICHANGED__ENTER_REASON__LAUNCHER;
+            case ENTER_REASON_DRAG:
+                return getDragEnterReasonFromSplitPosition(mDragEnterPosition, isLandscape);
+            case ENTER_REASON_UNKNOWN:
+            default:
+                return SPLITSCREEN_UICHANGED__ENTER_REASON__UNKNOWN_ENTER;
+        }
+    }
+
     /**
      * Returns the framework logging constant given a splitscreen exit reason.
      */
@@ -189,6 +220,7 @@
         mLastMainStageUid = -1;
         mLastSideStagePosition = -1;
         mLastSideStageUid = -1;
+        mEnterReason = ENTER_REASON_UNKNOWN;
     }
 
     /**
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 946dfde..c8dcf4a 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
@@ -18,8 +18,6 @@
 
 import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED;
-import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -46,6 +44,8 @@
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
+import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_LAUNCHER;
+import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_MULTI_INSTANCE;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP;
@@ -123,6 +123,7 @@
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.splitscreen.SplitScreen.StageType;
 import com.android.wm.shell.splitscreen.SplitScreenController.ExitReason;
+import com.android.wm.shell.transition.DefaultMixedHandler;
 import com.android.wm.shell.transition.LegacyTransitions;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.util.SplitBounds;
@@ -203,6 +204,8 @@
     @StageType
     private int mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
 
+    private DefaultMixedHandler mMixedHandler;
+
     private final SplitWindowManager.ParentContainerCallbacks mParentContainerCallbacks =
             new SplitWindowManager.ParentContainerCallbacks() {
                 @Override
@@ -326,6 +329,10 @@
         transitions.addHandler(this);
     }
 
+    public void setMixedHandler(DefaultMixedHandler mixedHandler) {
+        mMixedHandler = mixedHandler;
+    }
+
     @VisibleForTesting
     SplitScreenTransitions getSplitTransitions() {
         return mSplitTransitions;
@@ -664,7 +671,7 @@
 
     private void setEnterInstanceId(InstanceId instanceId) {
         if (instanceId != null) {
-            mLogger.enterRequested(instanceId);
+            mLogger.enterRequested(instanceId, ENTER_REASON_LAUNCHER);
         }
     }
 
@@ -927,13 +934,10 @@
             // Expand to top side split as full screen for fading out decor animation and dismiss
             // another side split(Moving its children to bottom).
             mIsExiting = true;
-            final StageTaskListener tempFullStage = childrenToTop;
-            final StageTaskListener dismissStage = mMainStage == childrenToTop
-                    ? mSideStage : mMainStage;
-            tempFullStage.resetBounds(wct);
-            wct.setSmallestScreenWidthDp(tempFullStage.mRootTaskInfo.token,
+            childrenToTop.resetBounds(wct);
+            wct.reorder(childrenToTop.mRootTaskInfo.token, true);
+            wct.setSmallestScreenWidthDp(childrenToTop.mRootTaskInfo.token,
                     SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
-            dismissStage.dismiss(wct, false /* toTop */);
         }
         mSyncQueue.queue(wct);
         mSyncQueue.runInSync(t -> {
@@ -950,7 +954,8 @@
                 childrenToTop.fadeOutDecor(() -> {
                     WindowContainerTransaction finishedWCT = new WindowContainerTransaction();
                     mIsExiting = false;
-                    childrenToTop.dismiss(finishedWCT, true /* toTop */);
+                    mMainStage.deactivate(finishedWCT, childrenToTop == mMainStage /* toTop */);
+                    mSideStage.removeAllTasks(finishedWCT, childrenToTop == mSideStage /* toTop */);
                     finishedWCT.reorder(mRootTaskInfo.token, false /* toTop */);
                     finishedWCT.setForceTranslucent(mRootTaskInfo.token, true);
                     finishedWCT.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
@@ -1104,9 +1109,6 @@
 
     private void addActivityOptions(Bundle opts, StageTaskListener stage) {
         opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, stage.mRootTaskInfo.token);
-        // Put BAL flags to avoid activity start aborted.
-        opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);
-        opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, true);
     }
 
     void updateActivityOptions(Bundle opts, @SplitPosition int position) {
@@ -1472,6 +1474,9 @@
             updateRecentTasksSplitPair();
 
             if (!mLogger.hasStartedSession()) {
+                if (!mLogger.hasValidEnterSessionId()) {
+                    mLogger.enterRequested(null /*enterSessionId*/, ENTER_REASON_MULTI_INSTANCE);
+                }
                 mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
                         getMainStagePosition(), mMainStage.getTopChildTaskUid(),
                         getSideStagePosition(), mSideStage.getTopChildTaskUid(),
@@ -1879,8 +1884,25 @@
 
             // Use normal animations.
             return false;
+        } else if (mMixedHandler != null && hasDisplayChange(info)) {
+            // A display-change has been un-expectedly inserted into the transition. Redirect
+            // handling to the mixed-handler to deal with splitting it up.
+            if (mMixedHandler.animatePendingSplitWithDisplayChange(transition, info,
+                    startTransaction, finishTransaction, finishCallback)) {
+                return true;
+            }
         }
 
+        return startPendingAnimation(transition, info, startTransaction, finishTransaction,
+                finishCallback);
+    }
+
+    /** Starts the pending transition animation. */
+    public boolean startPendingAnimation(@NonNull IBinder transition,
+            @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
         boolean shouldAnimate = true;
         if (mSplitTransitions.isPendingEnter(transition)) {
             shouldAnimate = startPendingEnterAnimation(
@@ -1899,6 +1921,15 @@
         return true;
     }
 
+    private boolean hasDisplayChange(TransitionInfo info) {
+        boolean has = false;
+        for (int iC = 0; iC < info.getChanges().size() && !has; ++iC) {
+            final TransitionInfo.Change change = info.getChanges().get(iC);
+            has = change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0;
+        }
+        return has;
+    }
+
     /** Called to clean-up state and do house-keeping after the animation is done. */
     public void onTransitionAnimationComplete() {
         // If still playing, let it finish.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 1af9415..6b90eab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -106,11 +106,6 @@
         taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
     }
 
-    /**
-     * General function for dismiss this stage.
-     */
-    void dismiss(WindowContainerTransaction wct, boolean toTop) {}
-
     int getChildCount() {
         return mChildrenTaskInfo.size();
     }
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 bcf4fbd..3cba929 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
@@ -17,6 +17,7 @@
 package com.android.wm.shell.transition;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 
@@ -57,6 +58,9 @@
     private static class MixedTransition {
         static final int TYPE_ENTER_PIP_FROM_SPLIT = 1;
 
+        /** Both the display and split-state (enter/exit) is changing */
+        static final int TYPE_DISPLAY_AND_SPLIT_CHANGE = 2;
+
         /** The default animation for this mixed transition. */
         static final int ANIM_TYPE_DEFAULT = 0;
 
@@ -69,6 +73,7 @@
 
         Transitions.TransitionFinishCallback mFinishCallback = null;
         Transitions.TransitionHandler mLeftoversHandler = null;
+        WindowContainerTransaction mFinishWCT = null;
 
         /**
          * Mixed transitions are made up of multiple "parts". This keeps track of how many
@@ -95,6 +100,9 @@
                 mPipHandler = pipTouchHandlerOptional.get().getTransitionHandler();
                 mSplitHandler = splitScreenControllerOptional.get().getTransitionHandler();
                 mPlayer.addHandler(this);
+                if (mSplitHandler != null) {
+                    mSplitHandler.setMixedHandler(this);
+                }
             }, this);
         }
     }
@@ -122,10 +130,12 @@
     }
 
     private TransitionInfo subCopy(@NonNull TransitionInfo info,
-            @WindowManager.TransitionType int newType) {
-        final TransitionInfo out = new TransitionInfo(newType, info.getFlags());
-        for (int i = 0; i < info.getChanges().size(); ++i) {
-            out.getChanges().add(info.getChanges().get(i));
+            @WindowManager.TransitionType int newType, boolean withChanges) {
+        final TransitionInfo out = new TransitionInfo(newType, withChanges ? info.getFlags() : 0);
+        if (withChanges) {
+            for (int i = 0; i < info.getChanges().size(); ++i) {
+                out.getChanges().add(info.getChanges().get(i));
+            }
         }
         out.setRootLeash(info.getRootLeash(), info.getRootOffset().x, info.getRootOffset().y);
         out.setAnimationOptions(info.getAnimationOptions());
@@ -157,6 +167,8 @@
         if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
             return animateEnterPipFromSplit(mixed, info, startTransaction, finishTransaction,
                     finishCallback);
+        } else if (mixed.mType == MixedTransition.TYPE_DISPLAY_AND_SPLIT_CHANGE) {
+            return false;
         } else {
             mActiveTransitions.remove(mixed);
             throw new IllegalStateException("Starting mixed animation without a known mixed type? "
@@ -173,7 +185,7 @@
                 + "entering PIP while Split-Screen is active.");
         TransitionInfo.Change pipChange = null;
         TransitionInfo.Change wallpaper = null;
-        final TransitionInfo everythingElse = subCopy(info, TRANSIT_TO_BACK);
+        final TransitionInfo everythingElse = subCopy(info, TRANSIT_TO_BACK, true /* changes */);
         boolean homeIsOpening = false;
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             TransitionInfo.Change change = info.getChanges().get(i);
@@ -254,6 +266,87 @@
         return true;
     }
 
+    private void unlinkMissingParents(TransitionInfo from) {
+        for (int i = 0; i < from.getChanges().size(); ++i) {
+            final TransitionInfo.Change chg = from.getChanges().get(i);
+            if (chg.getParent() == null) continue;
+            if (from.getChange(chg.getParent()) == null) {
+                from.getChanges().get(i).setParent(null);
+            }
+        }
+    }
+
+    private boolean isWithinTask(TransitionInfo info, TransitionInfo.Change chg) {
+        TransitionInfo.Change curr = chg;
+        while (curr != null) {
+            if (curr.getTaskInfo() != null) return true;
+            if (curr.getParent() == null) break;
+            curr = info.getChange(curr.getParent());
+        }
+        return false;
+    }
+
+    /**
+     * This is intended to be called by SplitCoordinator as a helper to mix an already-pending
+     * split transition with a display-change. The use-case for this is when a display
+     * change/rotation gets collected into a split-screen enter/exit transition which has already
+     * been claimed by StageCoordinator.handleRequest . This happens during launcher tests.
+     */
+    public boolean animatePendingSplitWithDisplayChange(@NonNull IBinder transition,
+            @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startT,
+            @NonNull SurfaceControl.Transaction finishT,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        final TransitionInfo everythingElse = subCopy(info, info.getType(), true /* withChanges */);
+        final TransitionInfo displayPart = subCopy(info, TRANSIT_CHANGE, false /* withChanges */);
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            TransitionInfo.Change change = info.getChanges().get(i);
+            if (isWithinTask(info, change)) continue;
+            displayPart.addChange(change);
+            everythingElse.getChanges().remove(i);
+        }
+        if (displayPart.getChanges().isEmpty()) return false;
+        unlinkMissingParents(everythingElse);
+        final MixedTransition mixed = new MixedTransition(
+                MixedTransition.TYPE_DISPLAY_AND_SPLIT_CHANGE, transition);
+        mixed.mFinishCallback = finishCallback;
+        mActiveTransitions.add(mixed);
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animation is a mix of display change "
+                + "and split change.");
+        // We need to split the transition into 2 parts: the split part and the display part.
+        mixed.mInFlightSubAnimations = 2;
+
+        Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+            --mixed.mInFlightSubAnimations;
+            if (wctCB != null) {
+                throw new IllegalArgumentException("Can't mix transitions that require finish"
+                        + " sync callback");
+            }
+            if (wct != null) {
+                if (mixed.mFinishWCT == null) {
+                    mixed.mFinishWCT = wct;
+                } else {
+                    mixed.mFinishWCT.merge(wct, true /* transfer */);
+                }
+            }
+            if (mixed.mInFlightSubAnimations > 0) return;
+            mActiveTransitions.remove(mixed);
+            mixed.mFinishCallback.onTransitionFinished(mixed.mFinishWCT, null /* wctCB */);
+        };
+
+        // Dispatch the display change. This will most-likely be taken by the default handler.
+        // Do this first since the first handler used will apply the startT; the display change
+        // needs to take a screenshot before that happens so we need it to be the first handler.
+        mixed.mLeftoversHandler = mPlayer.dispatchTransition(mixed.mTransition, displayPart,
+                startT, finishT, finishCB, mSplitHandler);
+
+        // Note: at this point, startT has probably already been applied, so we are basically
+        // giving splitHandler an empty startT. This is currently OK because display-change will
+        // grab a screenshot and paste it on top anyways.
+        mSplitHandler.startPendingAnimation(
+                transition, everythingElse, startT, finishT, finishCB);
+        return true;
+    }
+
     @Override
     public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@@ -279,6 +372,8 @@
                 } else {
                     mPipHandler.end();
                 }
+            } else if (mixed.mType == MixedTransition.TYPE_DISPLAY_AND_SPLIT_CHANGE) {
+                // queue
             } else {
                 throw new IllegalStateException("Playing a mixed transition with unknown type? "
                         + mixed.mType);
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 4c927b6..1ae779e 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
@@ -96,6 +96,7 @@
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.Transformation;
+import android.window.ScreenCapture;
 import android.window.TransitionInfo;
 import android.window.TransitionMetrics;
 import android.window.TransitionRequestInfo;
@@ -630,16 +631,16 @@
                 .setBufferSize(extensionRect.width(), extensionRect.height())
                 .build();
 
-        SurfaceControl.LayerCaptureArgs captureArgs =
-                new SurfaceControl.LayerCaptureArgs.Builder(surfaceToExtend)
+        ScreenCapture.LayerCaptureArgs captureArgs =
+                new ScreenCapture.LayerCaptureArgs.Builder(surfaceToExtend)
                         .setSourceCrop(edgeBounds)
                         .setFrameScale(1)
                         .setPixelFormat(PixelFormat.RGBA_8888)
                         .setChildrenOnly(true)
                         .setAllowProtected(true)
                         .build();
-        final SurfaceControl.ScreenshotHardwareBuffer edgeBuffer =
-                SurfaceControl.captureLayers(captureArgs);
+        final ScreenCapture.ScreenshotHardwareBuffer edgeBuffer =
+                ScreenCapture.captureLayers(captureArgs);
 
         if (edgeBuffer == null) {
             ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
index b647f43..2b27bae 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
@@ -46,6 +46,7 @@
 import android.view.SurfaceSession;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
+import android.window.ScreenCapture;
 import android.window.TransitionInfo;
 
 import com.android.internal.R;
@@ -144,14 +145,14 @@
                 t.reparent(mScreenshotLayer, mAnimLeash);
                 mStartLuma = change.getSnapshotLuma();
             } else {
-                SurfaceControl.LayerCaptureArgs args =
-                        new SurfaceControl.LayerCaptureArgs.Builder(mSurfaceControl)
+                ScreenCapture.LayerCaptureArgs args =
+                        new ScreenCapture.LayerCaptureArgs.Builder(mSurfaceControl)
                                 .setCaptureSecureLayers(true)
                                 .setAllowProtected(true)
                                 .setSourceCrop(new Rect(0, 0, mStartWidth, mStartHeight))
                                 .build();
-                SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                        SurfaceControl.captureLayers(args);
+                ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                        ScreenCapture.captureLayers(args);
                 if (screenshotBuffer == null) {
                     Slog.w(TAG, "Unable to take screenshot of display");
                     return;
@@ -481,8 +482,8 @@
         }
 
         Rect crop = new Rect(0, 0, bounds.width(), bounds.height());
-        SurfaceControl.ScreenshotHardwareBuffer buffer =
-                SurfaceControl.captureLayers(surfaceControl, crop, 1);
+        ScreenCapture.ScreenshotHardwareBuffer buffer =
+                ScreenCapture.captureLayers(surfaceControl, crop, 1);
         if (buffer == null) {
             return 0;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 83aa539..e8a2cb160 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -36,6 +36,7 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.desktopmode.DesktopMode;
 import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
 import com.android.wm.shell.transition.Transitions;
 
@@ -80,6 +81,7 @@
             SurfaceControl taskSurface,
             SurfaceControl.Transaction startT,
             SurfaceControl.Transaction finishT) {
+        if (!shouldShowWindowDecor(taskInfo)) return null;
         final CaptionWindowDecoration windowDecoration = new CaptionWindowDecoration(
                 mContext,
                 mDisplayController,
@@ -101,9 +103,12 @@
 
     @Override
     public CaptionWindowDecoration adoptWindowDecoration(AutoCloseable windowDecor) {
-        return (windowDecor instanceof CaptionWindowDecoration)
-                ? (CaptionWindowDecoration) windowDecor
-                : null;
+        if (!(windowDecor instanceof CaptionWindowDecoration)) return null;
+        final CaptionWindowDecoration captionWindowDecor = (CaptionWindowDecoration) windowDecor;
+        if (!shouldShowWindowDecor(captionWindowDecor.mTaskInfo)) {
+            return null;
+        }
+        return captionWindowDecor;
     }
 
     @Override
@@ -231,4 +236,11 @@
             }
         }
     }
+
+    private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
+        if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true;
+        return DesktopMode.IS_SUPPORTED
+                && mDisplayController.getDisplayContext(taskInfo.displayId)
+                .getResources().getConfiguration().smallestScreenWidthDp >= 600;
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
index c234949..d9697d2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
@@ -42,6 +42,7 @@
 
     /**
      * Creates a window decoration for the given task.
+     * Can be {@code null} for Fullscreen tasks but not Freeform ones.
      *
      * @param taskInfo the initial task info of the task
      * @param taskSurface the surface of the task
@@ -49,7 +50,7 @@
      * @param finishT the finish transaction to restore states after the transition
      * @return the window decoration object
      */
-    T createWindowDecoration(
+    @Nullable T createWindowDecoration(
             ActivityManager.RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             SurfaceControl.Transaction startT,
@@ -57,11 +58,12 @@
 
     /**
      * Adopts the window decoration if possible.
+     * May be {@code null} if a window decor is not needed or the given one is incompatible.
      *
      * @param windowDecor the potential window decoration to adopt
      * @return the window decoration if it can be adopted, or {@code null} otherwise.
      */
-    T adoptWindowDecoration(@Nullable AutoCloseable windowDecor);
+    @Nullable T adoptWindowDecoration(@Nullable AutoCloseable windowDecor);
 
     /**
      * Notifies a task info update on the given task, with the window decoration created previously
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
index 06361f9..53dd8b0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -24,3 +24,7 @@
 val DOCKED_STACK_DIVIDER_COMPONENT = ComponentNameMatcher("", "DockedStackDivider#")
 val SPLIT_SCREEN_DIVIDER_COMPONENT = ComponentNameMatcher("", "StageCoordinatorSplitDivider#")
 val SPLIT_DECOR_MANAGER = ComponentNameMatcher("", "SplitDecorManager#")
+
+enum class Direction {
+    UP, DOWN, LEFT, RIGHT
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
index 0f7d8a9..39be89d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
@@ -30,7 +30,7 @@
  */
 abstract class ExitPipTransition(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = true) {
+        get() = buildTransition {
             setup {
                 this.setRotation(testSpec.startRotation)
             }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
index 53450de..c2fd0d7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
@@ -62,7 +62,7 @@
      * Defines the transition used to run the test
      */
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = true) {
+        get() = buildTransition {
             setup {
                 // launch an app behind the pip one
                 testApp.launchViaIntent(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 75018d1..0d75e02 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -62,7 +62,7 @@
      * Defines the transition used to run the test
      */
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = true) {
+        get() = buildTransition {
             setup {
                 // launch an app behind the pip one
                 testApp.launchViaIntent(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index 4d39ec5..513ce95 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -56,7 +56,7 @@
 @Group3
 class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = true) {
+        get() = buildTransition {
             transitions {
                 pipApp.doubleClickPipWindow(wmHelper)
             }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
index de8c0093..746ce91 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
@@ -16,28 +16,30 @@
 
 package com.android.wm.shell.flicker.pip
 
+import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresDevice
 import android.view.Surface
-import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group3
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.traces.region.RegionSubject
+import com.android.wm.shell.flicker.Direction
 import org.junit.FixMethodOrder
+import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
 
 /**
- * Test Pip movement with Launcher shelf height change (decrease).
+ * Test Pip movement with Launcher shelf height change (increase).
  *
- * To run this test: `atest WMShellFlickerTests:MovePipDownShelfHeightChangeTest`
+ * To run this test: `atest WMShellFlickerTests:MovePipUpShelfHeightChangeTest`
  *
  * Actions:
  *     Launch [pipApp] in pip mode
- *     Launch [testApp]
  *     Press home
+ *     Launch [testApp]
  *     Check if pip window moves down (visually)
  *
  * Notes:
@@ -53,26 +55,41 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group3
-open class MovePipDownShelfHeightChangeTest(
+class MovePipDownShelfHeightChangeTest(
     testSpec: FlickerTestParameter
 ) : MovePipShelfHeightTransition(testSpec) {
+//    @Before
+//    fun before() {
+//        Assume.assumeFalse(isShellTransitionsEnabled)
+//    }
+
     /**
      * Defines the transition used to run the test
      */
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = false) {
+        get() = buildTransition {
             teardown {
-                testApp.launchViaIntent(wmHelper)
+                tapl.pressHome()
                 testApp.exit(wmHelper)
             }
             transitions {
-                tapl.pressHome()
+                testApp.launchViaIntent(wmHelper)
             }
         }
 
-    override fun assertRegionMovement(previous: RegionSubject, current: RegionSubject) {
-        current.isHigherOrEqual(previous.region)
-    }
+    /**
+     * Checks that the visible region of [pipApp] window always moves down during the animation.
+     */
+    @Presubmit
+    @Test
+    fun pipWindowMovesDown() = pipWindowMoves(Direction.DOWN)
+
+    /**
+     * Checks that the visible region of [pipApp] layer always moves down during the animation.
+     */
+    @Presubmit
+    @Test
+    fun pipLayerMovesDown() = pipLayerMoves(Direction.DOWN)
 
     companion object {
         /**
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
index 9fb941e..19bdca5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
@@ -19,6 +19,7 @@
 import android.platform.test.annotations.Presubmit
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.traces.region.RegionSubject
+import com.android.wm.shell.flicker.Direction
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
 import org.junit.Test
 
@@ -31,11 +32,6 @@
     protected val testApp = FixedAppHelper(instrumentation)
 
     /**
-     * Checks if the window movement direction is valid
-     */
-    protected abstract fun assertRegionMovement(previous: RegionSubject, current: RegionSubject)
-
-    /**
      * Checks [pipApp] window remains visible throughout the animation
      */
     @Presubmit
@@ -82,31 +78,46 @@
     }
 
     /**
-     * Checks that the visible region of [pipApp] always moves in the correct direction
+     * Checks that the visible region of [pipApp] window always moves in the specified direction
      * during the animation.
      */
-    @Presubmit
-    @Test
-    open fun pipWindowMoves() {
+    protected fun pipWindowMoves(direction: Direction) {
         testSpec.assertWm {
-            val pipWindowList = this.windowStates { pipApp.windowMatchesAnyOf(it) && it.isVisible }
-            pipWindowList.zipWithNext { previous, current ->
-                assertRegionMovement(previous.frame, current.frame)
+            val pipWindowFrameList = this.windowStates {
+                pipApp.windowMatchesAnyOf(it) && it.isVisible
+            }.map { it.frame }
+            when (direction) {
+                Direction.UP -> assertRegionMovementUp(pipWindowFrameList)
+                Direction.DOWN -> assertRegionMovementDown(pipWindowFrameList)
+                else -> error("Unhandled direction")
             }
         }
     }
 
     /**
-     * Checks that the visible region of [pipApp] always moves up during the animation
+     * Checks that the visible region of [pipApp] layer always moves in the specified direction
+     * during the animation.
      */
-    @Presubmit
-    @Test
-    open fun pipLayerMoves() {
+    protected fun pipLayerMoves(direction: Direction) {
         testSpec.assertLayers {
-            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
-            pipLayerList.zipWithNext { previous, current ->
-                assertRegionMovement(previous.visibleRegion, current.visibleRegion)
+            val pipLayerRegionList = this.layers {
+                pipApp.layerMatchesAnyOf(it) && it.isVisible
+            }.map { it.visibleRegion }
+            when (direction) {
+                Direction.UP -> assertRegionMovementUp(pipLayerRegionList)
+                Direction.DOWN -> assertRegionMovementDown(pipLayerRegionList)
+                else -> error("Unhandled direction")
             }
         }
     }
+
+    private fun assertRegionMovementDown(regions: List<RegionSubject>) {
+        regions.zipWithNext { previous, current -> current.isLowerOrEqual(previous) }
+        regions.last().isLower(regions.first())
+    }
+
+    private fun assertRegionMovementUp(regions: List<RegionSubject>) {
+        regions.zipWithNext { previous, current -> current.isHigherOrEqual(previous.region) }
+        regions.last().isHigher(regions.first())
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
index 3e08bfb..93e7d5c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
@@ -16,31 +16,30 @@
 
 package com.android.wm.shell.flicker.pip
 
-import android.platform.test.annotations.RequiresDevice
+import android.platform.test.annotations.Presubmit
 import android.view.Surface
+import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group3
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import com.android.server.wm.flicker.traces.region.RegionSubject
-import org.junit.Assume
-import org.junit.Before
+import com.android.wm.shell.flicker.Direction
 import org.junit.FixMethodOrder
+import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
 
 /**
- * Test Pip movement with Launcher shelf height change (increase).
+ * Test Pip movement with Launcher shelf height change (decrease).
  *
- * To run this test: `atest WMShellFlickerTests:MovePipUpShelfHeightChangeTest`
+ * To run this test: `atest WMShellFlickerTests:MovePipDownShelfHeightChangeTest`
  *
  * Actions:
  *     Launch [pipApp] in pip mode
- *     Press home
  *     Launch [testApp]
+ *     Press home
  *     Check if pip window moves up (visually)
  *
  * Notes:
@@ -56,31 +55,38 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group3
-class MovePipUpShelfHeightChangeTest(
+open class MovePipUpShelfHeightChangeTest(
     testSpec: FlickerTestParameter
 ) : MovePipShelfHeightTransition(testSpec) {
-    @Before
-    fun before() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
-    }
-
     /**
      * Defines the transition used to run the test
      */
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = false) {
-            teardown {
-                tapl.pressHome()
-                testApp.exit(wmHelper)
+        get() = buildTransition() {
+            setup {
+                testApp.launchViaIntent(wmHelper)
             }
             transitions {
-                testApp.launchViaIntent(wmHelper)
+                tapl.pressHome()
+            }
+            teardown {
+                testApp.exit(wmHelper)
             }
         }
 
-    override fun assertRegionMovement(previous: RegionSubject, current: RegionSubject) {
-        current.isLowerOrEqual(previous.region)
-    }
+    /**
+     * Checks that the visible region of [pipApp] window always moves up during the animation.
+     */
+    @Presubmit
+    @Test
+    fun pipWindowMovesUp() = pipWindowMoves(Direction.UP)
+
+    /**
+     * Checks that the visible region of [pipApp] layer always moves up during the animation.
+     */
+    @Presubmit
+    @Test
+    fun pipLayerMovesUp() = pipLayerMoves(Direction.UP)
 
     companion object {
         /**
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
index 27fc2ed..3d3b53d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -56,7 +56,7 @@
 
     /** {@inheritDoc}  */
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = false) {
+        get() = buildTransition {
             setup {
                 imeApp.launchViaIntent(wmHelper)
                 setRotation(testSpec.startRotation)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index fd5ff29..f13698f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -72,7 +72,7 @@
     }
 
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = false) {
+        get() = buildTransition {
             setup {
                 fixedApp.launchViaIntent(wmHelper)
                 setRotation(testSpec.startRotation)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index faf6afc..b67cf77 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -65,7 +65,6 @@
      */
     @JvmOverloads
     protected open fun buildTransition(
-        eachRun: Boolean,
         stringExtras: Map<String, String> = mapOf(Components.PipActivity.EXTRA_ENTER_PIP to "true"),
         extraSpec: FlickerBuilder.() -> Unit = {}
     ): FlickerBuilder.() -> Unit {
@@ -73,25 +72,12 @@
             setup {
                 setRotation(Surface.ROTATION_0)
                 removeAllTasksButHome()
-
-                if (!eachRun) {
-                    pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
-                }
-                if (eachRun) {
-                    pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
-                }
+                pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
             }
             teardown {
                 setRotation(Surface.ROTATION_0)
                 removeAllTasksButHome()
                 pipApp.exit(wmHelper)
-
-                if (eachRun) {
-                    pipApp.exit(wmHelper)
-                }
-                if (!eachRun) {
-                    pipApp.exit(wmHelper)
-                }
             }
 
             extraSpec(this)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index 4e8773f..2db3009 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.splitscreen
 
+import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
@@ -75,13 +76,13 @@
     @Test
     fun primaryAppLayerBecomesInvisible() = testSpec.layerBecomesInvisible(primaryApp)
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
+    // TODO(b/245472831): Move back to presubmit after shell transitions landing.
+    @FlakyTest(bugId = 245472831)
     @Test
     fun secondaryAppLayerBecomesInvisible() = testSpec.layerBecomesInvisible(primaryApp)
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
+    // TODO(b/245472831): Move back to presubmit after shell transitions landing.
+    @FlakyTest(bugId = 245472831)
     @Test
     fun primaryAppBoundsBecomesInvisible() = testSpec.splitAppLayerBoundsBecomesInvisible(
         primaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
index e174f5e..2d5d2b7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker.splitscreen
 
+import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
@@ -85,8 +86,9 @@
     fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
         primaryApp, landscapePosLeft = !tapl.isTablet, portraitPosTop = true)
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
+    // TODO(b/246490534): Move back to presubmit after withAppTransitionIdle is robust enough to
+    // get the correct end state.
+    @FlakyTest(bugId = 246490534)
     @Test
     fun secondaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
         secondaryApp, landscapePosLeft = tapl.isTablet, portraitPosTop = false)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
index b2e45a6..a7234c1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
@@ -17,7 +17,7 @@
 package com.android.wm.shell.activityembedding;
 
 import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;
+import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
@@ -57,7 +57,7 @@
     public void testStartAnimation() {
         final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
         final TransitionInfo.Change embeddingChange = createChange();
-        embeddingChange.setFlags(FLAG_IS_EMBEDDED);
+        embeddingChange.setFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
         info.addChange(embeddingChange);
         doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any());
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
index 84befdd..3792e83 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
@@ -16,6 +16,9 @@
 
 package com.android.wm.shell.activityembedding;
 
+import static android.window.TransitionInfo.FLAG_FILLS_TASK;
+import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
+
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 
 import static org.junit.Assert.assertNotNull;
@@ -24,6 +27,8 @@
 
 import android.animation.Animator;
 import android.annotation.CallSuper;
+import android.annotation.NonNull;
+import android.graphics.Rect;
 import android.os.IBinder;
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
@@ -80,4 +85,23 @@
         return new TransitionInfo.Change(mock(WindowContainerToken.class),
                 mock(SurfaceControl.class));
     }
+
+    /**
+     * Creates a mock {@link TransitionInfo.Change} with
+     * {@link TransitionInfo#FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY} flag.
+     */
+    static TransitionInfo.Change createEmbeddedChange(@NonNull Rect startBounds,
+            @NonNull Rect endBounds, @NonNull Rect taskBounds) {
+        final TransitionInfo.Change change = createChange();
+        change.setFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
+        change.setStartAbsBounds(startBounds);
+        change.setEndAbsBounds(endBounds);
+        if (taskBounds.width() == startBounds.width()
+                && taskBounds.height() == startBounds.height()
+                && taskBounds.width() == endBounds.width()
+                && taskBounds.height() == endBounds.height()) {
+            change.setFlags(FLAG_FILLS_TASK);
+        }
+        return change;
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
index cf43b00..baecf6f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
@@ -17,7 +17,6 @@
 package com.android.wm.shell.activityembedding;
 
 import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 
@@ -29,6 +28,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
+import android.graphics.Rect;
 import android.window.TransitionInfo;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -48,6 +48,10 @@
 @RunWith(AndroidJUnit4.class)
 public class ActivityEmbeddingControllerTests extends ActivityEmbeddingAnimationTestBase {
 
+    private static final Rect TASK_BOUNDS = new Rect(0, 0, 1000, 500);
+    private static final Rect EMBEDDED_LEFT_BOUNDS = new Rect(0, 0, 500, 500);
+    private static final Rect EMBEDDED_RIGHT_BOUNDS = new Rect(500, 0, 1000, 500);
+
     @Before
     public void setup() {
         super.setUp();
@@ -77,13 +81,13 @@
     @Test
     public void testStartAnimation_containsNonActivityEmbeddingChange() {
         final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createChange();
-        embeddingChange.setFlags(FLAG_IS_EMBEDDED);
+        final TransitionInfo.Change embeddingChange = createEmbeddedChange(EMBEDDED_LEFT_BOUNDS,
+                EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS);
         final TransitionInfo.Change nonEmbeddingChange = createChange();
         info.addChange(embeddingChange);
         info.addChange(nonEmbeddingChange);
 
-        // No-op
+        // No-op because it contains non-embedded change.
         assertFalse(mController.startAnimation(mTransition, info, mStartTransaction,
                 mFinishTransaction, mFinishCallback));
         verify(mAnimRunner, never()).startAnimation(any(), any(), any(), any());
@@ -93,13 +97,65 @@
     }
 
     @Test
-    public void testStartAnimation_onlyActivityEmbeddingChange() {
+    public void testStartAnimation_containsOnlyFillTaskActivityEmbeddingChange() {
         final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createChange();
-        embeddingChange.setFlags(FLAG_IS_EMBEDDED);
+        final TransitionInfo.Change embeddingChange = createEmbeddedChange(TASK_BOUNDS, TASK_BOUNDS,
+                TASK_BOUNDS);
         info.addChange(embeddingChange);
 
-        // No-op
+        // No-op because it only contains embedded change that fills the Task. We will let the
+        // default handler to animate such transition.
+        assertFalse(mController.startAnimation(mTransition, info, mStartTransaction,
+                mFinishTransaction, mFinishCallback));
+        verify(mAnimRunner, never()).startAnimation(any(), any(), any(), any());
+        verifyNoMoreInteractions(mStartTransaction);
+        verifyNoMoreInteractions(mFinishTransaction);
+        verifyNoMoreInteractions(mFinishCallback);
+    }
+
+    @Test
+    public void testStartAnimation_containsActivityEmbeddingSplitChange() {
+        // Change that occupies only part of the Task.
+        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
+        final TransitionInfo.Change embeddingChange = createEmbeddedChange(EMBEDDED_LEFT_BOUNDS,
+                EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS);
+        info.addChange(embeddingChange);
+
+        // ActivityEmbeddingController will handle such transition.
+        assertTrue(mController.startAnimation(mTransition, info, mStartTransaction,
+                mFinishTransaction, mFinishCallback));
+        verify(mAnimRunner).startAnimation(mTransition, info, mStartTransaction,
+                mFinishTransaction);
+        verify(mStartTransaction).apply();
+        verifyNoMoreInteractions(mFinishTransaction);
+    }
+
+    @Test
+    public void testStartAnimation_containsChangeEnterActivityEmbeddingSplit() {
+        // Change that is entering ActivityEmbedding split.
+        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
+        final TransitionInfo.Change embeddingChange = createEmbeddedChange(TASK_BOUNDS,
+                EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS);
+        info.addChange(embeddingChange);
+
+        // ActivityEmbeddingController will handle such transition.
+        assertTrue(mController.startAnimation(mTransition, info, mStartTransaction,
+                mFinishTransaction, mFinishCallback));
+        verify(mAnimRunner).startAnimation(mTransition, info, mStartTransaction,
+                mFinishTransaction);
+        verify(mStartTransaction).apply();
+        verifyNoMoreInteractions(mFinishTransaction);
+    }
+
+    @Test
+    public void testStartAnimation_containsChangeExitActivityEmbeddingSplit() {
+        // Change that is exiting ActivityEmbedding split.
+        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
+        final TransitionInfo.Change embeddingChange = createEmbeddedChange(EMBEDDED_RIGHT_BOUNDS,
+                TASK_BOUNDS, TASK_BOUNDS);
+        info.addChange(embeddingChange);
+
+        // ActivityEmbeddingController will handle such transition.
         assertTrue(mController.startAnimation(mTransition, info, mStartTransaction,
                 mFinishTransaction, mFinishCallback));
         verify(mAnimRunner).startAnimation(mTransition, info, mStartTransaction,
@@ -115,8 +171,8 @@
                 () -> mController.onAnimationFinished(mTransition));
 
         final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createChange();
-        embeddingChange.setFlags(FLAG_IS_EMBEDDED);
+        final TransitionInfo.Change embeddingChange = createEmbeddedChange(EMBEDDED_LEFT_BOUNDS,
+                EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS);
         info.addChange(embeddingChange);
         mController.startAnimation(mTransition, info, mStartTransaction,
                 mFinishTransaction, mFinishCallback);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index ef532e4..c628f399 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -32,17 +32,19 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.testing.AndroidTestingRunner;
+import android.window.DisplayAreaInfo;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 import android.window.WindowContainerTransaction.Change;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.wm.shell.RootDisplayAreaOrganizer;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.Transitions;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,11 +60,13 @@
     @Mock
     private ShellTaskOrganizer mShellTaskOrganizer;
     @Mock
-    private RootDisplayAreaOrganizer mRootDisplayAreaOrganizer;
+    private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
     @Mock
     private ShellExecutor mTestExecutor;
     @Mock
     private Handler mMockHandler;
+    @Mock
+    private Transitions mMockTransitions;
 
     private DesktopModeController mController;
     private ShellInit mShellInit;
@@ -72,7 +76,7 @@
         mShellInit = Mockito.spy(new ShellInit(mTestExecutor));
 
         mController = new DesktopModeController(mContext, mShellInit, mShellTaskOrganizer,
-                mRootDisplayAreaOrganizer, mMockHandler);
+                mRootTaskDisplayAreaOrganizer, mMockHandler, mMockTransitions);
 
         mShellInit.init();
     }
@@ -91,19 +95,19 @@
         when(mShellTaskOrganizer.prepareClearFreeformForStandardTasks(
                 mContext.getDisplayId())).thenReturn(taskWct);
 
-        // Create a fake WCT to simulate setting display windowing mode to freeform
-        WindowContainerTransaction displayWct = new WindowContainerTransaction();
+        // Create a fake DisplayAreaInfo to check if windowing mode change is set correctly
         MockToken displayMockToken = new MockToken();
-        displayWct.setWindowingMode(displayMockToken.token(), WINDOWING_MODE_FREEFORM);
-        when(mRootDisplayAreaOrganizer.prepareWindowingModeChange(mContext.getDisplayId(),
-                WINDOWING_MODE_FREEFORM)).thenReturn(displayWct);
+        DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(displayMockToken.mToken,
+                mContext.getDisplayId(), 0);
+        when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId()))
+                .thenReturn(displayAreaInfo);
 
         // The test
         mController.updateDesktopModeActive(true);
 
         ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass(
                 WindowContainerTransaction.class);
-        verify(mRootDisplayAreaOrganizer).applyTransaction(arg.capture());
+        verify(mRootTaskDisplayAreaOrganizer).applyTransaction(arg.capture());
 
         // WCT should have 2 changes - clear task wm mode and set display wm mode
         WindowContainerTransaction wct = arg.getValue();
@@ -115,7 +119,7 @@
         assertThat(taskWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED);
 
         // Verify executed WCT has a change for setting display windowing mode to freeform
-        Change displayWmModeChange = wct.getChanges().get(displayMockToken.binder());
+        Change displayWmModeChange = wct.getChanges().get(displayAreaInfo.token.asBinder());
         assertThat(displayWmModeChange).isNotNull();
         assertThat(displayWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_FREEFORM);
     }
@@ -136,19 +140,19 @@
         when(mShellTaskOrganizer.prepareClearBoundsForStandardTasks(
                 mContext.getDisplayId())).thenReturn(taskBoundsWct);
 
-        // Create a fake WCT to simulate setting display windowing mode to fullscreen
-        WindowContainerTransaction displayWct = new WindowContainerTransaction();
+        // Create a fake DisplayAreaInfo to check if windowing mode change is set correctly
         MockToken displayMockToken = new MockToken();
-        displayWct.setWindowingMode(displayMockToken.token(), WINDOWING_MODE_FULLSCREEN);
-        when(mRootDisplayAreaOrganizer.prepareWindowingModeChange(mContext.getDisplayId(),
-                WINDOWING_MODE_FULLSCREEN)).thenReturn(displayWct);
+        DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(displayMockToken.mToken,
+                mContext.getDisplayId(), 0);
+        when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId()))
+                .thenReturn(displayAreaInfo);
 
         // The test
         mController.updateDesktopModeActive(false);
 
         ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass(
                 WindowContainerTransaction.class);
-        verify(mRootDisplayAreaOrganizer).applyTransaction(arg.capture());
+        verify(mRootTaskDisplayAreaOrganizer).applyTransaction(arg.capture());
 
         // WCT should have 3 changes - clear task wm mode and bounds and set display wm mode
         WindowContainerTransaction wct = arg.getValue();
@@ -168,7 +172,7 @@
                 .isTrue();
 
         // Verify executed WCT has a change for setting display windowing mode to fullscreen
-        Change displayWmModeChange = wct.getChanges().get(displayMockToken.binder());
+        Change displayWmModeChange = wct.getChanges().get(displayAreaInfo.token.asBinder());
         assertThat(displayWmModeChange).isNotNull();
         assertThat(displayWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_FULLSCREEN);
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
new file mode 100644
index 0000000..9b28d11
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DesktopModeTaskRepositoryTest : ShellTestCase() {
+
+    private lateinit var repo: DesktopModeTaskRepository
+
+    @Before
+    fun setUp() {
+        repo = DesktopModeTaskRepository()
+    }
+
+    @Test
+    fun addActiveTask_listenerNotifiedAndTaskIsActive() {
+        val listener = TestListener()
+        repo.addListener(listener)
+
+        repo.addActiveTask(1)
+        assertThat(listener.activeTaskChangedCalls).isEqualTo(1)
+        assertThat(repo.isActiveTask(1)).isTrue()
+    }
+
+    @Test
+    fun addActiveTask_sameTaskDoesNotNotify() {
+        val listener = TestListener()
+        repo.addListener(listener)
+
+        repo.addActiveTask(1)
+        repo.addActiveTask(1)
+        assertThat(listener.activeTaskChangedCalls).isEqualTo(1)
+    }
+
+    @Test
+    fun addActiveTask_multipleTasksAddedNotifiesForEach() {
+        val listener = TestListener()
+        repo.addListener(listener)
+
+        repo.addActiveTask(1)
+        repo.addActiveTask(2)
+        assertThat(listener.activeTaskChangedCalls).isEqualTo(2)
+    }
+
+    @Test
+    fun removeActiveTask_listenerNotifiedAndTaskNotActive() {
+        val listener = TestListener()
+        repo.addListener(listener)
+
+        repo.addActiveTask(1)
+        repo.removeActiveTask(1)
+        // Notify once for add and once for remove
+        assertThat(listener.activeTaskChangedCalls).isEqualTo(2)
+        assertThat(repo.isActiveTask(1)).isFalse()
+    }
+
+    @Test
+    fun removeActiveTask_removeNotExistingTaskDoesNotNotify() {
+        val listener = TestListener()
+        repo.addListener(listener)
+        repo.removeActiveTask(99)
+        assertThat(listener.activeTaskChangedCalls).isEqualTo(0)
+    }
+
+    @Test
+    fun isActiveTask_notExistingTaskReturnsFalse() {
+        assertThat(repo.isActiveTask(99)).isFalse()
+    }
+
+    class TestListener : DesktopModeTaskRepository.Listener {
+        var activeTaskChangedCalls = 0
+        override fun onActiveTasksChanged() {
+            activeTaskChangedCalls++
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index e9a1e25..cadfeb0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -55,6 +55,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.desktopmode.DesktopMode;
+import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.util.GroupedRecentTaskInfo;
@@ -82,6 +83,8 @@
     private TaskStackListenerImpl mTaskStackListener;
     @Mock
     private ShellCommandHandler mShellCommandHandler;
+    @Mock
+    private DesktopModeTaskRepository mDesktopModeTaskRepository;
 
     private ShellTaskOrganizer mShellTaskOrganizer;
     private RecentTasksController mRecentTasksController;
@@ -94,7 +97,8 @@
         when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
         mShellInit = spy(new ShellInit(mMainExecutor));
         mRecentTasksController = spy(new RecentTasksController(mContext, mShellInit,
-                mShellCommandHandler, mTaskStackListener, mMainExecutor));
+                mShellCommandHandler, mTaskStackListener, Optional.of(mDesktopModeTaskRepository),
+                mMainExecutor));
         mShellTaskOrganizer = new ShellTaskOrganizer(mShellInit, mShellCommandHandler,
                 null /* sizeCompatUI */, Optional.empty(), Optional.of(mRecentTasksController),
                 mMainExecutor);
@@ -195,8 +199,8 @@
         ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4);
         setRawList(t1, t2, t3, t4);
 
-        mRecentTasksController.addActiveFreeformTask(1);
-        mRecentTasksController.addActiveFreeformTask(3);
+        when(mDesktopModeTaskRepository.isActiveTask(1)).thenReturn(true);
+        when(mDesktopModeTaskRepository.isActiveTask(3)).thenReturn(true);
 
         ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
                 MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index ea9390e..9240abf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -225,7 +225,6 @@
         mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
         verify(mMainStage).reorderChild(eq(testTaskId), eq(true),
                 any(WindowContainerTransaction.class));
-        verify(mSideStage).dismiss(any(WindowContainerTransaction.class), eq(false));
         verify(mMainStage).resetBounds(any(WindowContainerTransaction.class));
     }
 
@@ -239,7 +238,6 @@
         verify(mSideStage).reorderChild(eq(testTaskId), eq(true),
                 any(WindowContainerTransaction.class));
         verify(mSideStage).resetBounds(any(WindowContainerTransaction.class));
-        verify(mMainStage).dismiss(any(WindowContainerTransaction.class), eq(false));
     }
 
     @Test
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 779c4b7..eb8d26a 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -71,6 +71,7 @@
         "misc.cpp",
         "ObbFile.cpp",
         "PosixUtils.cpp",
+        "ResourceTimer.cpp",
         "ResourceTypes.cpp",
         "ResourceUtils.cpp",
         "StreamingZipInflater.cpp",
@@ -173,6 +174,7 @@
         "tests/Idmap_test.cpp",
         "tests/LoadedArsc_test.cpp",
         "tests/Locale_test.cpp",
+        "tests/ResourceTimer_test.cpp",
         "tests/ResourceUtils_test.cpp",
         "tests/ResTable_test.cpp",
         "tests/Split_test.cpp",
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 39c7d19..235700b 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -601,10 +601,6 @@
     return base::unexpected(result.error());
   }
 
-  if (type_idx == 0x1c) {
-    LOG(ERROR) << base::StringPrintf("foobar first result %s", result->package_name->c_str());
-  }
-
   bool overlaid = false;
   if (!stop_at_first_match && !ignore_configuration && !apk_assets_[result->cookie]->IsLoader()) {
     for (const auto& id_map : package_group.overlays_) {
@@ -615,7 +611,21 @@
       }
       if (overlay_entry.IsInlineValue()) {
         // The target resource is overlaid by an inline value not represented by a resource.
-        result->entry = overlay_entry.GetInlineValue();
+        ConfigDescription best_frro_config;
+        Res_value best_frro_value;
+        bool frro_found = false;
+        for( const auto& [config, value] : overlay_entry.GetInlineValue()) {
+          if ((!frro_found || config.isBetterThan(best_frro_config, desired_config))
+              && config.match(*desired_config)) {
+            frro_found = true;
+            best_frro_config = config;
+            best_frro_value = value;
+          }
+        }
+        if (!frro_found) {
+          continue;
+        }
+        result->entry = best_frro_value;
         result->dynamic_ref_table = id_map.overlay_res_maps_.GetOverlayDynamicRefTable();
         result->cookie = id_map.cookie;
 
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index efd1f6a..e122d48 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -56,6 +56,8 @@
 struct Idmap_data_header {
   uint32_t target_entry_count;
   uint32_t target_inline_entry_count;
+  uint32_t target_inline_entry_value_count;
+  uint32_t configuration_count;
   uint32_t overlay_entry_count;
 
   uint32_t string_pool_index_offset;
@@ -68,6 +70,12 @@
 
 struct Idmap_target_entry_inline {
   uint32_t target_id;
+  uint32_t start_value_index;
+  uint32_t value_count;
+};
+
+struct Idmap_target_entry_inline_value {
+  uint32_t config_index;
   Res_value value;
 };
 
@@ -138,11 +146,15 @@
 IdmapResMap::IdmapResMap(const Idmap_data_header* data_header,
                          const Idmap_target_entry* entries,
                          const Idmap_target_entry_inline* inline_entries,
+                         const Idmap_target_entry_inline_value* inline_entry_values,
+                         const ConfigDescription* configs,
                          uint8_t target_assigned_package_id,
                          const OverlayDynamicRefTable* overlay_ref_table)
     : data_header_(data_header),
       entries_(entries),
       inline_entries_(inline_entries),
+      inline_entry_values_(inline_entry_values),
+      configurations_(configs),
       target_assigned_package_id_(target_assigned_package_id),
       overlay_ref_table_(overlay_ref_table) { }
 
@@ -183,7 +195,13 @@
 
   if (inline_entry != end_inline_entry &&
       (0x00FFFFFFU & dtohl(inline_entry->target_id)) == target_res_id) {
-    return Result(inline_entry->value);
+    std::map<ConfigDescription, Res_value> values_map;
+    for (int i = 0; i < inline_entry->value_count; i++) {
+      const auto& value = inline_entry_values_[inline_entry->start_value_index + i];
+      const auto& config = configurations_[value.config_index];
+      values_map[config] = value.value;
+    }
+    return Result(values_map);
   }
   return {};
 }
@@ -237,6 +255,8 @@
                          const Idmap_data_header* data_header,
                          const Idmap_target_entry* target_entries,
                          const Idmap_target_entry_inline* target_inline_entries,
+                         const Idmap_target_entry_inline_value* inline_entry_values,
+                         const ConfigDescription* configs,
                          const Idmap_overlay_entry* overlay_entries,
                          std::unique_ptr<ResStringPool>&& string_pool,
                          std::string_view overlay_apk_path,
@@ -245,6 +265,8 @@
        data_header_(data_header),
        target_entries_(target_entries),
        target_inline_entries_(target_inline_entries),
+       inline_entry_values_(inline_entry_values),
+       configurations_(configs),
        overlay_entries_(overlay_entries),
        string_pool_(std::move(string_pool)),
        idmap_path_(std::move(idmap_path)),
@@ -303,6 +325,21 @@
   if (target_inline_entries == nullptr) {
     return {};
   }
+
+  auto target_inline_entry_values = ReadType<Idmap_target_entry_inline_value>(
+      &data_ptr, &data_size, "target inline values",
+      dtohl(data_header->target_inline_entry_value_count));
+  if (target_inline_entry_values == nullptr) {
+    return {};
+  }
+
+  auto configurations = ReadType<ConfigDescription>(
+      &data_ptr, &data_size, "configurations",
+      dtohl(data_header->configuration_count));
+  if (configurations == nullptr) {
+    return {};
+  }
+
   auto overlay_entries = ReadType<Idmap_overlay_entry>(&data_ptr, &data_size, "target inline",
                                                        dtohl(data_header->overlay_entry_count));
   if (overlay_entries == nullptr) {
@@ -329,8 +366,8 @@
   // Can't use make_unique because LoadedIdmap constructor is private.
   return std::unique_ptr<LoadedIdmap>(
       new LoadedIdmap(idmap_path.to_string(), header, data_header, target_entries,
-                      target_inline_entries, overlay_entries, std::move(idmap_string_pool),
-                      *target_path, *overlay_path));
+                      target_inline_entries, target_inline_entry_values, configurations,
+                      overlay_entries, std::move(idmap_string_pool), *target_path, *overlay_path));
 }
 
 bool LoadedIdmap::IsUpToDate() const {
diff --git a/libs/androidfw/ResourceTimer.cpp b/libs/androidfw/ResourceTimer.cpp
new file mode 100644
index 0000000..44128d9
--- /dev/null
+++ b/libs/androidfw/ResourceTimer.cpp
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+#include <string.h>
+
+#include <map>
+#include <atomic>
+
+#include <utils/Log.h>
+#include <androidfw/ResourceTimer.h>
+
+// The following block allows compilation on windows, which does not have getuid().
+#ifdef _WIN32
+#ifdef ERROR
+#undef ERROR
+#endif
+#define getuid() (getUidWindows_)
+#endif
+
+namespace android {
+
+namespace {
+
+#ifdef _WIN32
+// A temporary to confuse lint into thinking that getuid() on windows might return something other
+// than zero.
+int getUidWindows_ = 0;
+#endif
+
+// The number of nanoseconds in a microsecond.
+static const unsigned int US = 1000;
+// The number of nanoseconds in a second.
+static const unsigned int S = 1000 * 1000 * 1000;
+
+// Return the difference between two timespec values.  The difference is in nanoseconds.  If the
+// return value would exceed 2s (2^31 nanoseconds) then UINT_MAX is returned.
+unsigned int diffInNs(timespec const &a, timespec const &b) {
+  timespec r = { 0, 0 };
+  r.tv_nsec = a.tv_nsec - b.tv_nsec;
+  if (r.tv_nsec < 0) {
+    r.tv_sec = -1;
+    r.tv_nsec += S;
+  }
+  r.tv_sec = r.tv_sec + (a.tv_sec - b.tv_sec);
+  if (r.tv_sec > 2) return UINT_MAX;
+  unsigned int result = (r.tv_sec * S) + r.tv_nsec;
+  if (result > 2 * S) return UINT_MAX;
+  return result;
+}
+
+}
+
+ResourceTimer::ResourceTimer(Counter api)
+    : active_(enabled_.load()),
+      api_(api) {
+  if (active_) {
+    clock_gettime(CLOCK_MONOTONIC, &start_);
+  }
+}
+
+ResourceTimer::~ResourceTimer() {
+  record();
+}
+
+void ResourceTimer::enable() {
+  if (!enabled_.load()) counter_ = new GuardedTimer[ResourceTimer::counterSize];
+  enabled_.store(true);
+}
+
+void ResourceTimer::cancel() {
+  active_ = false;
+}
+
+void ResourceTimer::record() {
+  if (!active_) return;
+
+  struct timespec end;
+  clock_gettime(CLOCK_MONOTONIC, &end);
+  // Get the difference in microseconds.
+  const unsigned int ticks = diffInNs(end, start_);
+  ScopedTimer t(counter_[toIndex(api_)]);
+  t->record(ticks);
+  active_ = false;
+}
+
+bool ResourceTimer::copy(int counter, Timer &dst, bool reset) {
+  ScopedTimer t(counter_[counter]);
+  if (t->count == 0) {
+    dst.reset();
+    if (reset) t->reset();
+    return false;
+  }
+  Timer::copy(dst, *t, reset);
+  return true;
+}
+
+void ResourceTimer::reset() {
+  for (int i = 0; i < counterSize; i++) {
+    ScopedTimer t(counter_[i]);
+    t->reset();
+  }
+}
+
+ResourceTimer::Timer::Timer() {
+  // Ensure newly-created objects are zeroed.
+  memset(buckets, 0, sizeof(buckets));
+  reset();
+}
+
+ResourceTimer::Timer::~Timer() {
+  for (int d = 0; d < MaxDimension; d++) {
+    delete[] buckets[d];
+  }
+}
+
+void ResourceTimer::Timer::freeBuckets() {
+  for (int d = 0; d < MaxDimension; d++) {
+    delete[] buckets[d];
+    buckets[d] = 0;
+  }
+}
+
+void ResourceTimer::Timer::reset() {
+  count = total = mintime = maxtime = 0;
+  memset(largest, 0, sizeof(largest));
+  memset(&pvalues, 0, sizeof(pvalues));
+  // Zero the histogram, keeping any allocated dimensions.
+  for (int d = 0; d < MaxDimension; d++) {
+    if (buckets[d] != 0) memset(buckets[d], 0, sizeof(int) * MaxBuckets);
+  }
+}
+
+void ResourceTimer::Timer::copy(Timer &dst, Timer &src, bool reset) {
+  dst.freeBuckets();
+  dst = src;
+  // Clean up the histograms.
+  if (reset) {
+    // Do NOT free the src buckets because they being used by dst.
+    memset(src.buckets, 0, sizeof(src.buckets));
+    src.reset();
+  } else {
+    for (int d = 0; d < MaxDimension; d++) {
+      if (src.buckets[d] != nullptr) {
+        dst.buckets[d] = new int[MaxBuckets];
+        memcpy(dst.buckets[d], src.buckets[d], sizeof(int) * MaxBuckets);
+      }
+    }
+  }
+}
+
+void ResourceTimer::Timer::record(int ticks) {
+  // Record that the event happened.
+  count++;
+
+  total += ticks;
+  if (mintime == 0 || ticks < mintime) mintime = ticks;
+  if (ticks > maxtime) maxtime = ticks;
+
+  // Do not add oversized events to the histogram.
+  if (ticks != UINT_MAX) {
+    for (int d = 0; d < MaxDimension; d++) {
+      if (ticks < range[d]) {
+        if (buckets[d] == 0) {
+          buckets[d] = new int[MaxBuckets];
+          memset(buckets[d], 0, sizeof(int) * MaxBuckets);
+        }
+        if (ticks < width[d]) {
+          // Special case: never write to bucket 0 because it complicates the percentile logic.
+          // However, this is always the smallest possible value to it is very unlikely to ever
+          // affect any of the percentile results.
+          buckets[d][1]++;
+        } else {
+          buckets[d][ticks / width[d]]++;
+        }
+        break;
+      }
+    }
+  }
+
+  // The list of largest times is sorted with the biggest value at index 0 and the smallest at
+  // index MaxLargest-1.  The incoming tick count should be added to the array only if it is
+  // larger than the current value at MaxLargest-1.
+  if (ticks > largest[Timer::MaxLargest-1]) {
+    for (size_t i = 0; i < Timer::MaxLargest; i++) {
+      if (ticks > largest[i]) {
+        if (i < Timer::MaxLargest-1) {
+          for (size_t j = Timer::MaxLargest - 1; j > i; j--) {
+            largest[j] = largest[j-1];
+          }
+        }
+        largest[i] = ticks;
+        break;
+      }
+    }
+  }
+}
+
+void ResourceTimer::Timer::Percentile::compute(
+    int cumulative, int current, int count, int width, int time) {
+  nominal = time;
+  nominal_actual = (cumulative * 100) / count;
+  floor = nominal - width;
+  floor_actual = ((cumulative - current) * 100) / count;
+}
+
+void ResourceTimer::Timer::compute() {
+  memset(&pvalues, 0, sizeof(pvalues));
+
+  float l50 = count / 2.0;
+  float l90 = (count * 9.0) / 10.0;
+  float l95 = (count * 95.0) / 100.0;
+  float l99 = (count * 99.0) / 100.0;
+
+  int sum = 0;
+  for (int d = 0; d < MaxDimension; d++) {
+    if (buckets[d] == 0) continue;
+    for (int j = 0; j < MaxBuckets && sum < count; j++) {
+      // Empty buckets don't contribute to the answers.  Skip them.
+      if (buckets[d][j] == 0) continue;
+      sum += buckets[d][j];
+      // A word on indexing.  j is never zero in the following lines.  buckets[0][0] corresponds
+      // to a delay of 0us, which cannot happen.  buckets[n][0], for n > 0 overlaps a value in
+      // buckets[n-1], and the code would have stopped there.
+      if (sum >= l50 && pvalues.p50.nominal == 0) {
+        pvalues.p50.compute(sum, buckets[d][j], count, width[d], j * width[d]);
+      }
+      if (sum >= l90 && pvalues.p90.nominal == 0) {
+        pvalues.p90.compute(sum, buckets[d][j], count, width[d], j * width[d]);
+      }
+      if (sum >= l95 && pvalues.p95.nominal == 0) {
+        pvalues.p95.compute(sum, buckets[d][j], count, width[d], j * width[d]);
+      }
+      if (sum >= l99 && pvalues.p99.nominal == 0) {
+        pvalues.p99.compute(sum, buckets[d][j], count, width[d], j * width[d]);
+      }
+    }
+  }
+}
+
+char const *ResourceTimer::toString(ResourceTimer::Counter counter) {
+  switch (counter) {
+    case Counter::GetResourceValue:
+      return "GetResourceValue";
+    case Counter::RetrieveAttributes:
+      return "RetrieveAttributes";
+  };
+  return "Unknown";
+}
+
+std::atomic<bool> ResourceTimer::enabled_(false);
+std::atomic<ResourceTimer::GuardedTimer *> ResourceTimer::counter_(nullptr);
+
+const int ResourceTimer::Timer::range[] = { 100 * US, 1000 * US, 10*1000 * US, 100*1000 * US };
+const int ResourceTimer::Timer::width[] = {   1 * US,   10 * US,     100 * US,     1000 * US };
+
+
+}  // namespace android
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
index 6804472..a1cbbbf 100644
--- a/libs/androidfw/include/androidfw/Idmap.h
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -23,6 +23,7 @@
 #include <variant>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 #include "androidfw/ResourceTypes.h"
 #include "utils/ByteOrder.h"
@@ -35,6 +36,7 @@
 struct Idmap_data_header;
 struct Idmap_target_entry;
 struct Idmap_target_entry_inline;
+struct Idmap_target_entry_inline_value;
 struct Idmap_overlay_entry;
 
 // A string pool for overlay apk assets. The string pool holds the strings of the overlay resources
@@ -91,7 +93,8 @@
    public:
     Result() = default;
     explicit Result(uint32_t value) : data_(value) {};
-    explicit Result(const Res_value& value) : data_(value) { };
+    explicit Result(const std::map<ConfigDescription, Res_value> &value)
+        : data_(value) { };
 
     // Returns `true` if the resource is overlaid.
     explicit operator bool() const {
@@ -107,15 +110,16 @@
     }
 
     bool IsInlineValue() const {
-      return std::get_if<Res_value>(&data_) != nullptr;
+      return std::get_if<2>(&data_) != nullptr;
     }
 
-    const Res_value& GetInlineValue() const {
-      return std::get<Res_value>(data_);
+    const std::map<ConfigDescription, Res_value>& GetInlineValue() const {
+      return std::get<2>(data_);
     }
 
    private:
-      std::variant<std::monostate, uint32_t, Res_value> data_;
+      std::variant<std::monostate, uint32_t,
+          std::map<ConfigDescription, Res_value> > data_;
   };
 
   // Looks up the value that overlays the target resource id.
@@ -129,12 +133,16 @@
   explicit IdmapResMap(const Idmap_data_header* data_header,
                        const Idmap_target_entry* entries,
                        const Idmap_target_entry_inline* inline_entries,
+                       const Idmap_target_entry_inline_value* inline_entry_values,
+                       const ConfigDescription* configs,
                        uint8_t target_assigned_package_id,
                        const OverlayDynamicRefTable* overlay_ref_table);
 
   const Idmap_data_header* data_header_;
   const Idmap_target_entry* entries_;
   const Idmap_target_entry_inline* inline_entries_;
+  const Idmap_target_entry_inline_value* inline_entry_values_;
+  const ConfigDescription* configurations_;
   const uint8_t target_assigned_package_id_;
   const OverlayDynamicRefTable* overlay_ref_table_;
 
@@ -170,8 +178,8 @@
   // Returns a mapping from target resource ids to overlay values.
   const IdmapResMap GetTargetResourcesMap(uint8_t target_assigned_package_id,
                                           const OverlayDynamicRefTable* overlay_ref_table) const {
-    return IdmapResMap(data_header_, target_entries_, target_inline_entries_,
-                       target_assigned_package_id, overlay_ref_table);
+    return IdmapResMap(data_header_, target_entries_, target_inline_entries_, inline_entry_values_,
+                       configurations_, target_assigned_package_id, overlay_ref_table);
   }
 
   // Returns a dynamic reference table for a loaded overlay package.
@@ -191,6 +199,8 @@
   const Idmap_data_header* data_header_;
   const Idmap_target_entry* target_entries_;
   const Idmap_target_entry_inline* target_inline_entries_;
+  const Idmap_target_entry_inline_value* inline_entry_values_;
+  const ConfigDescription* configurations_;
   const Idmap_overlay_entry* overlay_entries_;
   const std::unique_ptr<ResStringPool> string_pool_;
 
@@ -207,6 +217,8 @@
                        const Idmap_data_header* data_header,
                        const Idmap_target_entry* target_entries,
                        const Idmap_target_entry_inline* target_inline_entries,
+                       const Idmap_target_entry_inline_value* inline_entry_values_,
+                       const ConfigDescription* configs,
                        const Idmap_overlay_entry* overlay_entries,
                        std::unique_ptr<ResStringPool>&& string_pool,
                        std::string_view overlay_apk_path,
diff --git a/libs/androidfw/include/androidfw/ResourceTimer.h b/libs/androidfw/include/androidfw/ResourceTimer.h
new file mode 100644
index 0000000..7461351
--- /dev/null
+++ b/libs/androidfw/include/androidfw/ResourceTimer.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROIDFW_RESOURCETIMER_H_
+#define ANDROIDFW_RESOURCETIMER_H_
+
+#include <time.h>
+#include <atomic>
+#include <vector>
+
+#include <utils/Mutex.h>
+#include <android-base/macros.h>
+#include <androidfw/Util.h>
+
+namespace android {
+
+// ResourceTimer captures the duration of short functions.  Durations are accumulated in registers
+// and statistics are pulled back to the Java layer as needed.
+// To monitor an API, first add it to the Counter enumeration.  Then, inside the API, create an
+// instance of ResourceTimer with the appropriate enumeral.  The corresponding counter will be
+// updated when the ResourceTimer destructor is called, normally at the end of the enclosing block.
+class ResourceTimer {
+ public:
+  enum class Counter {
+    GetResourceValue,
+    RetrieveAttributes,
+
+    LastCounter = RetrieveAttributes,
+  };
+  static const int counterSize = static_cast<int>(Counter::LastCounter) + 1;
+  static char const *toString(Counter);
+
+  // Start a timer for the specified counter.
+  ResourceTimer(Counter);
+  // The block is exiting.  If the timer is active, record it.
+  ~ResourceTimer();
+  // This records the elapsed time and disables further recording.  Use this if the containing
+  // block includes extra processing that should not be included in the timer.  The method is
+  // destructive in that the timer is no longer valid and further calls to record() will be
+  // ignored.
+  void record();
+  // This cancels a timer.  Elapsed time will neither be computed nor recorded.
+  void cancel();
+
+  // A single timer contains the count of events and the cumulative time spent handling the
+  // events.  It also includes the smallest value seen and 10 largest values seen.  Finally, it
+  // includes a histogram of values that approximates a semi-log.
+
+  // The timer can compute percentiles of recorded events.  For example, the p50 value is a time
+  // such that 50% of the readings are below the value and 50% are above the value.  The
+  // granularity in the readings means that a percentile cannot always be computed.  In this case,
+  // the percentile is reported as zero.  (The simplest example is when there is a single
+  // reading.)  Even if the value can be computed, it will not be exact.  Therefore, a percentile
+  // is actually reported as two values: the lowest time at which it might be valid and the
+  // highest time at which it might be valid.
+  struct Timer {
+    static const size_t MaxLargest = 5;
+
+    // The construct zeros all the fields.  The destructor releases memory allocated to the
+    // buckets.
+    Timer();
+    ~Timer();
+
+    // The following summary values are set to zero on a reset.  All times are in ns.
+
+    // The total number of events recorded.
+    int count;
+    // The total duration of events.
+    int64_t total;
+    // The smallest event duration seen.  This is guaranteed to be non-zero if count is greater
+    // than 0.
+    int mintime;
+    // The largest event duration seen.
+    int maxtime;
+
+    // The largest values seen.  Element 0 is the largest value seen (and is the same as maxtime,
+    // above).  Element 1 is the next largest, and so on.  If count is less than MaxLargest,
+    // unused elements will be zero.
+    int largest[MaxLargest];
+
+    // The p50 value is a time such that 50% of the readings are below that time and 50% of the
+    // readings.
+
+    // A single percentile is defined by the lowest value supported by the readings and the
+    // highest value supported by the readings.
+    struct Percentile {
+      // The nominal time (in ns) of the percentile.  The true percentile is guaranteed to be less
+      // than or equal to this time.
+      int nominal;
+      // The actual percentile of the nominal time.
+      int nominal_actual;
+      // The time of the next lower bin.  The true percentile is guaranteed to be greater than
+      // this time.
+      int floor;
+      // The actual percentile of the floor time.
+      int floor_actual;
+
+      // Fill in a percentile given the cumulative to the bin, the count in the current bin, the
+      // total count, the width of the bin, and the time of the bin.
+      void compute(int cumulative, int current, int count, int width, int time);
+    };
+
+    // The structure that holds the percentiles.
+    struct {
+      Percentile p50;
+      Percentile p90;
+      Percentile p95;
+      Percentile p99;
+    } pvalues;
+
+    // Set all counters to zero.
+    void reset();
+    // Record an event.  The input time is in ns.
+    void record(int);
+    // Compute the percentiles.  Percentiles are computed on demand, as the computation is too
+    // expensive to be done inline.
+    void compute();
+
+    // Copy one timer to another.  If reset is true then the src is reset immediately after the
+    // copy.  The reset flag is exploited to make the copy faster.  Any data in dst is lost.
+    static void copy(Timer &dst, Timer &src, bool reset);
+
+   private:
+    // Free any buckets.
+    void freeBuckets();
+
+    // Readings are placed in bins, which are orgzanized into decades.  The decade 0 covers
+    // [0,100) in steps of 1us.  Decade 1 covers [0,1000) in steps of 10us.  Decade 2 covers
+    // [0,10000) in steps of 100us.  And so on.
+
+    // An event is placed in the first bin that can hold it.  This means that events in the range
+    // of [0,100) are placed in the first decade, events in the range of [0,1000) are placed in
+    // the second decade, and so on.  This also means that the first 10% of the bins are unused
+    // in each decade after the first.
+
+    // The design provides at least two significant digits across the range of [0,10000).
+
+    static const size_t MaxDimension = 4;
+    static const size_t MaxBuckets = 100;
+
+    // The range of each dimension.  The lower value is always zero.
+    static const int range[MaxDimension];
+    // The width of each bin, by dimension
+    static const int width[MaxDimension];
+
+    // A histogram of the values seen. Centuries are allocated as needed, to minimize the memory
+    // impact.
+    int *buckets[MaxDimension];
+  };
+
+  // Fetch one Timer.  The function has a short-circuit behavior: if the count is zero then
+  // destination count is set to zero and the function returns false.  Otherwise, the destination
+  // is a copy of the source and the function returns true.  This behavior lowers the cost of
+  // handling unused timers.
+  static bool copy(int src, Timer &dst, bool reset);
+
+  // Enable the timers.  Timers are initially disabled.  Enabling timers allocates memory for the
+  // counters.  Timers cannot be disabled.
+  static void enable();
+
+ private:
+  // An internal reset method.  This does not take a lock.
+  static void reset();
+
+  // Helper method to convert a counter into an enum.  Presumably, this will be inlined into zero
+  // actual cpu instructions.
+  static inline std::vector<unsigned int>::size_type toIndex(Counter c) {
+    return static_cast<std::vector<unsigned int>::size_type>(c);
+  }
+
+  // Every counter has an associated lock.  The lock has been factored into a separate class to
+  // keep the Timer class a POD.
+  struct GuardedTimer {
+    Mutex lock_;
+    Timer timer_;
+  };
+
+  // Scoped timer
+  struct ScopedTimer {
+    AutoMutex _l;
+    Timer &t;
+    ScopedTimer(GuardedTimer &g) :
+        _l(g.lock_), t(g.timer_) {
+    }
+    Timer *operator->() {
+      return &t;
+    }
+    Timer& operator*() {
+      return t;
+    }
+  };
+
+  // An individual timer is active (or not), is tracking a specific API, and has a start time.
+  // The api and the start time are undefined if the timer is not active.
+  bool active_;
+  Counter api_;
+  struct timespec start_;
+
+  // The global enable flag.  This is initially false and may be set true by the java runtime.
+  static std::atomic<bool> enabled_;
+
+  // The global timers.  The memory for the timers is not allocated until the timers are enabled.
+  static std::atomic<GuardedTimer *> counter_;
+};
+
+}  // namespace android
+
+#endif /* ANDROIDFW_RESOURCETIMER_H_ */
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 8c614bc..9309091 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -45,7 +45,7 @@
 namespace android {
 
 constexpr const uint32_t kIdmapMagic = 0x504D4449u;
-constexpr const uint32_t kIdmapCurrentVersion = 0x00000008u;
+constexpr const uint32_t kIdmapCurrentVersion = 0x00000009u;
 
 // This must never change.
 constexpr const uint32_t kFabricatedOverlayMagic = 0x4f525246; // FRRO (big endian)
@@ -1098,7 +1098,7 @@
         SDKVERSION_ANY = 0
     };
     
-  enum {
+    enum {
         MINORVERSION_ANY = 0
     };
     
diff --git a/libs/androidfw/tests/ResourceTimer_test.cpp b/libs/androidfw/tests/ResourceTimer_test.cpp
new file mode 100644
index 0000000..4a1e973
--- /dev/null
+++ b/libs/androidfw/tests/ResourceTimer_test.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <android-base/file.h>
+#include <android-base/test_utils.h>
+#include <androidfw/Util.h>
+
+#include "TestHelpers.h"
+
+#include <androidfw/ResourceTimer.h>
+
+namespace android {
+
+namespace {
+
+// Create a reading in us.  This is a convenience function to avoid multiplying by 1000
+// everywhere.
+unsigned int US(int us) {
+  return us * 1000;
+}
+
+}
+
+TEST(ResourceTimerTest, TimerBasic) {
+  ResourceTimer::Timer timer;
+  ASSERT_THAT(timer.count, 0);
+  ASSERT_THAT(timer.total, 0);
+
+  for (int i = 1; i <= 100; i++) {
+    timer.record(US(i));
+  }
+  ASSERT_THAT(timer.count, 100);
+  ASSERT_THAT(timer.total, US((101 * 100)/2));
+  ASSERT_THAT(timer.mintime, US(1));
+  ASSERT_THAT(timer.maxtime, US(100));
+  ASSERT_THAT(timer.pvalues.p50.floor, 0);
+  ASSERT_THAT(timer.pvalues.p50.nominal, 0);
+  ASSERT_THAT(timer.largest[0], US(100));
+  ASSERT_THAT(timer.largest[1], US(99));
+  ASSERT_THAT(timer.largest[2], US(98));
+  ASSERT_THAT(timer.largest[3], US(97));
+  ASSERT_THAT(timer.largest[4], US(96));
+  timer.compute();
+  ASSERT_THAT(timer.pvalues.p50.floor, US(49));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
+  ASSERT_THAT(timer.pvalues.p90.floor, US(89));
+  ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
+  ASSERT_THAT(timer.pvalues.p95.floor, US(94));
+  ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
+  ASSERT_THAT(timer.pvalues.p99.floor, US(98));
+  ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
+
+  // Test reset functionality.  All values should be zero after the reset.  Computing pvalues
+  // after the result should also yield zeros.
+  timer.reset();
+  ASSERT_THAT(timer.count, 0);
+  ASSERT_THAT(timer.total, 0);
+  ASSERT_THAT(timer.mintime, US(0));
+  ASSERT_THAT(timer.maxtime, US(0));
+  ASSERT_THAT(timer.pvalues.p50.floor, US(0));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(0));
+  ASSERT_THAT(timer.largest[0], US(0));
+  ASSERT_THAT(timer.largest[1], US(0));
+  ASSERT_THAT(timer.largest[2], US(0));
+  ASSERT_THAT(timer.largest[3], US(0));
+  ASSERT_THAT(timer.largest[4], US(0));
+  timer.compute();
+  ASSERT_THAT(timer.pvalues.p50.floor, US(0));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(0));
+  ASSERT_THAT(timer.pvalues.p90.floor, US(0));
+  ASSERT_THAT(timer.pvalues.p90.nominal, US(0));
+  ASSERT_THAT(timer.pvalues.p95.floor, US(0));
+  ASSERT_THAT(timer.pvalues.p95.nominal, US(0));
+  ASSERT_THAT(timer.pvalues.p99.floor, US(0));
+  ASSERT_THAT(timer.pvalues.p99.nominal, US(0));
+
+  // Test again, adding elements in reverse.
+  for (int i = 100; i >= 1; i--) {
+    timer.record(US(i));
+  }
+  ASSERT_THAT(timer.count, 100);
+  ASSERT_THAT(timer.total, US((101 * 100)/2));
+  ASSERT_THAT(timer.mintime, US(1));
+  ASSERT_THAT(timer.maxtime, US(100));
+  ASSERT_THAT(timer.pvalues.p50.floor, 0);
+  ASSERT_THAT(timer.pvalues.p50.nominal, 0);
+  timer.compute();
+  ASSERT_THAT(timer.pvalues.p50.floor, US(49));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
+  ASSERT_THAT(timer.pvalues.p90.floor, US(89));
+  ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
+  ASSERT_THAT(timer.pvalues.p95.floor, US(94));
+  ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
+  ASSERT_THAT(timer.pvalues.p99.floor, US(98));
+  ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
+  ASSERT_THAT(timer.largest[0], US(100));
+  ASSERT_THAT(timer.largest[1], US(99));
+  ASSERT_THAT(timer.largest[2], US(98));
+  ASSERT_THAT(timer.largest[3], US(97));
+  ASSERT_THAT(timer.largest[4], US(96));
+}
+
+TEST(ResourceTimerTest, TimerLimit) {
+  ResourceTimer::Timer timer;
+
+  // Event truncation means that a time of 1050us will be stored in the 1000us
+  // bucket.  Since there is a single event, all p-values lie in the same range.
+  timer.record(US(1050));
+  timer.compute();
+  ASSERT_THAT(timer.pvalues.p50.floor, US(900));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(1000));
+  ASSERT_THAT(timer.pvalues.p90.floor, US(900));
+  ASSERT_THAT(timer.pvalues.p90.nominal, US(1000));
+  ASSERT_THAT(timer.pvalues.p95.floor, US(900));
+  ASSERT_THAT(timer.pvalues.p95.nominal, US(1000));
+  ASSERT_THAT(timer.pvalues.p99.floor, US(900));
+  ASSERT_THAT(timer.pvalues.p99.nominal, US(1000));
+}
+
+TEST(ResourceTimerTest, TimerCopy) {
+  ResourceTimer::Timer source;
+  for (int i = 1; i <= 100; i++) {
+    source.record(US(i));
+  }
+  ResourceTimer::Timer timer;
+  ResourceTimer::Timer::copy(timer, source, true);
+  ASSERT_THAT(source.count, 0);
+  ASSERT_THAT(source.total, 0);
+  // compute() is not normally be called on a reset timer, but it should work and it should return
+  // all zeros.
+  source.compute();
+  ASSERT_THAT(source.pvalues.p50.floor, US(0));
+  ASSERT_THAT(source.pvalues.p50.nominal, US(0));
+  ASSERT_THAT(source.pvalues.p90.floor, US(0));
+  ASSERT_THAT(source.pvalues.p90.nominal, US(0));
+  ASSERT_THAT(source.pvalues.p95.floor, US(0));
+  ASSERT_THAT(source.pvalues.p95.nominal, US(0));
+  ASSERT_THAT(source.pvalues.p99.floor, US(0));
+  ASSERT_THAT(source.pvalues.p99.nominal, US(0));
+  ASSERT_THAT(source.largest[0], US(0));
+  ASSERT_THAT(source.largest[1], US(0));
+  ASSERT_THAT(source.largest[2], US(0));
+  ASSERT_THAT(source.largest[3], US(0));
+  ASSERT_THAT(source.largest[4], US(0));
+
+  timer.compute();
+  ASSERT_THAT(timer.pvalues.p50.floor, US(49));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
+  ASSERT_THAT(timer.pvalues.p90.floor, US(89));
+  ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
+  ASSERT_THAT(timer.pvalues.p95.floor, US(94));
+  ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
+  ASSERT_THAT(timer.pvalues.p99.floor, US(98));
+  ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
+  ASSERT_THAT(timer.largest[0], US(100));
+  ASSERT_THAT(timer.largest[1], US(99));
+  ASSERT_THAT(timer.largest[2], US(98));
+  ASSERT_THAT(timer.largest[3], US(97));
+  ASSERT_THAT(timer.largest[4], US(96));
+
+  // Call compute a second time.  The values must be the same.
+  timer.compute();
+  ASSERT_THAT(timer.pvalues.p50.floor, US(49));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
+  ASSERT_THAT(timer.pvalues.p90.floor, US(89));
+  ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
+  ASSERT_THAT(timer.pvalues.p95.floor, US(94));
+  ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
+  ASSERT_THAT(timer.pvalues.p99.floor, US(98));
+  ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
+  ASSERT_THAT(timer.largest[0], US(100));
+  ASSERT_THAT(timer.largest[1], US(99));
+  ASSERT_THAT(timer.largest[2], US(98));
+  ASSERT_THAT(timer.largest[3], US(97));
+  ASSERT_THAT(timer.largest[4], US(96));
+
+  // Modify the source.  If timer and source share histogram arrays, this will introduce an
+  // error.
+  for (int i = 1; i <= 100; i++) {
+    source.record(US(i));
+  }
+  // Call compute a third time.  The values must be the same.
+  timer.compute();
+  ASSERT_THAT(timer.pvalues.p50.floor, US(49));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
+  ASSERT_THAT(timer.pvalues.p90.floor, US(89));
+  ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
+  ASSERT_THAT(timer.pvalues.p95.floor, US(94));
+  ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
+  ASSERT_THAT(timer.pvalues.p99.floor, US(98));
+  ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
+  ASSERT_THAT(timer.largest[0], US(100));
+  ASSERT_THAT(timer.largest[1], US(99));
+  ASSERT_THAT(timer.largest[2], US(98));
+  ASSERT_THAT(timer.largest[3], US(97));
+  ASSERT_THAT(timer.largest[4], US(96));
+}
+
+// Verify that if too many oversize entries are reported, the percentile values cannot be computed
+// and are set to zero.
+TEST(ResourceTimerTest, TimerOversize) {
+  static const int oversize = US(2 * 1000 * 1000);
+
+  ResourceTimer::Timer timer;
+  for (int i = 1; i <= 100; i++) {
+    timer.record(US(i));
+  }
+
+  // Insert enough oversize values to invalidate the p90, p95, and p99 percentiles.  The p50 is
+  // still computable.
+  for (int i = 1; i <= 50; i++) {
+    timer.record(oversize);
+  }
+  ASSERT_THAT(timer.largest[0], oversize);
+  ASSERT_THAT(timer.largest[1], oversize);
+  ASSERT_THAT(timer.largest[2], oversize);
+  ASSERT_THAT(timer.largest[3], oversize);
+  ASSERT_THAT(timer.largest[4], oversize);
+  timer.compute();
+  ASSERT_THAT(timer.pvalues.p50.floor, US(74));
+  ASSERT_THAT(timer.pvalues.p50.nominal, US(75));
+  ASSERT_THAT(timer.pvalues.p90.floor, 0);
+  ASSERT_THAT(timer.pvalues.p90.nominal, 0);
+  ASSERT_THAT(timer.pvalues.p95.floor, 0);
+  ASSERT_THAT(timer.pvalues.p95.nominal, 0);
+  ASSERT_THAT(timer.pvalues.p99.floor, 0);
+  ASSERT_THAT(timer.pvalues.p99.nominal, 0);
+}
+
+
+}  // namespace android
diff --git a/libs/androidfw/tests/data/overlay/overlay.idmap b/libs/androidfw/tests/data/overlay/overlay.idmap
index 88eadcc..8e847e8 100644
--- a/libs/androidfw/tests/data/overlay/overlay.idmap
+++ b/libs/androidfw/tests/data/overlay/overlay.idmap
Binary files differ
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 397975d..473afbd 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -18,6 +18,7 @@
 
 #include "CanvasProperty.h"
 #include "NinePatchUtils.h"
+#include "SkBlendMode.h"
 #include "VectorDrawable.h"
 #include "hwui/Bitmap.h"
 #include "hwui/MinikinUtils.h"
@@ -251,10 +252,11 @@
     return (rec && rec->saveCount == currentSaveCount) ? rec : nullptr;
 }
 
-void SkiaCanvas::punchHole(const SkRRect& rect) {
+void SkiaCanvas::punchHole(const SkRRect& rect, float alpha) {
     SkPaint paint = SkPaint();
-    paint.setColor(0);
-    paint.setBlendMode(SkBlendMode::kClear);
+    paint.setColor(SkColors::kBlack);
+    paint.setAlphaf(alpha);
+    paint.setBlendMode(SkBlendMode::kDstOut);
     mCanvas->drawRRect(rect, paint);
 }
 
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index c6313f6..51007c5 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -65,7 +65,7 @@
         LOG_ALWAYS_FATAL("SkiaCanvas does not support enableZ");
     }
 
-    virtual void punchHole(const SkRRect& rect) override;
+    virtual void punchHole(const SkRRect& rect, float alpha) override;
 
     virtual void setBitmap(const SkBitmap& bitmap) override;
 
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 7378351..82d23b5 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -152,7 +152,7 @@
         LOG_ALWAYS_FATAL("Not supported");
     }
 
-    virtual void punchHole(const SkRRect& rect) = 0;
+    virtual void punchHole(const SkRRect& rect, float alpha) = 0;
 
     // ----------------------------------------------------------------------------
     // Canvas state operations
diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp
index fb7d5f7..0513447 100644
--- a/libs/hwui/jni/android_graphics_Canvas.cpp
+++ b/libs/hwui/jni/android_graphics_Canvas.cpp
@@ -713,9 +713,10 @@
 }
 
 static void punchHole(JNIEnv* env, jobject, jlong canvasPtr, jfloat left, jfloat top, jfloat right,
-        jfloat bottom, jfloat rx, jfloat ry) {
+        jfloat bottom, jfloat rx, jfloat ry, jfloat alpha) {
     auto canvas = reinterpret_cast<Canvas*>(canvasPtr);
-    canvas->punchHole(SkRRect::MakeRectXY(SkRect::MakeLTRB(left, top, right, bottom), rx, ry));
+    canvas->punchHole(SkRRect::MakeRectXY(SkRect::MakeLTRB(left, top, right, bottom), rx, ry),
+                      alpha);
 }
 
 }; // namespace CanvasJNI
@@ -790,7 +791,7 @@
     {"nDrawTextRun","(JLjava/lang/String;IIIIFFZJ)V", (void*) CanvasJNI::drawTextRunString},
     {"nDrawTextOnPath","(J[CIIJFFIJ)V", (void*) CanvasJNI::drawTextOnPathChars},
     {"nDrawTextOnPath","(JLjava/lang/String;JFFIJ)V", (void*) CanvasJNI::drawTextOnPathString},
-    {"nPunchHole", "(JFFFFFF)V", (void*) CanvasJNI::punchHole}
+    {"nPunchHole", "(JFFFFFFF)V", (void*) CanvasJNI::punchHole}
 };
 
 int register_android_graphics_Canvas(JNIEnv* env) {
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 3bf2b2e..f2282e66 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -201,6 +201,7 @@
         paint.setAlpha((uint8_t)paint.getAlpha() * mAlpha);
         return true;
     }
+
     void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
         // We unroll the drawable using "this" canvas, so that draw calls contained inside will
         // get their alpha applied. The default SkPaintFilterCanvas::onDrawDrawable does not unroll.
@@ -292,7 +293,7 @@
                 // with the same canvas transformation + clip into the target
                 // canvas then draw the layer on top
                 if (renderNode->hasHolePunches()) {
-                    TransformCanvas transformCanvas(canvas, SkBlendMode::kClear);
+                    TransformCanvas transformCanvas(canvas, SkBlendMode::kDstOut);
                     displayList->draw(&transformCanvas);
                 }
                 canvas->drawImageRect(snapshotImage, SkRect::Make(srcBounds),
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 5c6117d..1f87865 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -69,20 +69,22 @@
     mDisplayList->setHasHolePunches(false);
 }
 
-void SkiaRecordingCanvas::punchHole(const SkRRect& rect) {
-    // Add the marker annotation to allow HWUI to determine where the current
-    // clip/transformation should be applied
+void SkiaRecordingCanvas::punchHole(const SkRRect& rect, float alpha) {
+    // Add the marker annotation to allow HWUI to determine the current
+    // clip/transformation and alpha should be applied
     SkVector vector = rect.getSimpleRadii();
-    float data[2];
+    float data[3];
     data[0] = vector.x();
     data[1] = vector.y();
+    data[2] = alpha;
     mRecorder.drawAnnotation(rect.rect(), HOLE_PUNCH_ANNOTATION.c_str(),
-                             SkData::MakeWithCopy(data, 2 * sizeof(float)));
+                             SkData::MakeWithCopy(data, sizeof(data)));
 
     // Clear the current rect within the layer itself
     SkPaint paint = SkPaint();
-    paint.setColor(0);
-    paint.setBlendMode(SkBlendMode::kClear);
+    paint.setColor(SkColors::kBlack);
+    paint.setAlphaf(alpha);
+    paint.setBlendMode(SkBlendMode::kDstOut);
     mRecorder.drawRRect(rect, paint);
 
     mDisplayList->setHasHolePunches(true);
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 89e3a2c..7844e2c 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -50,7 +50,7 @@
         initDisplayList(renderNode, width, height);
     }
 
-    virtual void punchHole(const SkRRect& rect) override;
+    virtual void punchHole(const SkRRect& rect, float alpha) override;
 
     virtual void finishRecording(uirenderer::RenderNode* destination) override;
     std::unique_ptr<SkiaDisplayList> finishRecording();
diff --git a/libs/hwui/pipeline/skia/TransformCanvas.cpp b/libs/hwui/pipeline/skia/TransformCanvas.cpp
index 33160d0..c320df0 100644
--- a/libs/hwui/pipeline/skia/TransformCanvas.cpp
+++ b/libs/hwui/pipeline/skia/TransformCanvas.cpp
@@ -29,13 +29,15 @@
 void TransformCanvas::onDrawAnnotation(const SkRect& rect, const char* key, SkData* value) {
     if (HOLE_PUNCH_ANNOTATION == key) {
         auto* rectParams = reinterpret_cast<const float*>(value->data());
-        float radiusX = rectParams[0];
-        float radiusY = rectParams[1];
+        const float radiusX = rectParams[0];
+        const float radiusY = rectParams[1];
+        const float alpha = rectParams[2];
         SkRRect roundRect = SkRRect::MakeRectXY(rect, radiusX, radiusY);
 
         SkPaint paint;
         paint.setColor(SkColors::kBlack);
         paint.setBlendMode(mHolePunchBlendMode);
+        paint.setAlphaf(alpha);
         mWrappedCanvas->drawRRect(roundRect, paint);
     }
 }
diff --git a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
index 59230a7..7d3ca96 100644
--- a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
@@ -138,7 +138,7 @@
         roundRectPaint.setColor(Color::White);
         if (addHolePunch) {
             // Punch a hole but then cover it up, we don't want to actually see it
-            canvas.punchHole(SkRRect::MakeRect(SkRect::MakeWH(itemWidth, itemHeight)));
+            canvas.punchHole(SkRRect::MakeRect(SkRect::MakeWH(itemWidth, itemHeight)), 1.f);
         }
         canvas.drawRoundRect(0, 0, itemWidth, itemHeight, dp(6), dp(6), roundRectPaint);
 
@@ -235,4 +235,4 @@
     StretchEffectBehavior stretchBehavior() override { return StretchEffectBehavior::UniformScale; }
     bool haveHolePunch() override { return true; }
     bool forceLayer() override { return true; }
-};
\ No newline at end of file
+};
diff --git a/location/java/android/location/LocationTime.java b/location/java/android/location/LocationTime.java
index e5535d1..2f03508 100644
--- a/location/java/android/location/LocationTime.java
+++ b/location/java/android/location/LocationTime.java
@@ -20,28 +20,32 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.time.Duration;
+import java.time.Instant;
+
 /**
- * Data class for passing location derived time.
+ * Data class for passing GNSS-derived time.
  * @hide
  */
 public final class LocationTime implements Parcelable {
 
-    private final long mTime;
+    private final long mUnixEpochTimeMillis;
     private final long mElapsedRealtimeNanos;
 
-    public LocationTime(long time, long elapsedRealtimeNanos) {
-        mTime = time;
+    public LocationTime(long unixEpochTimeMillis, long elapsedRealtimeNanos) {
+        mUnixEpochTimeMillis = unixEpochTimeMillis;
         mElapsedRealtimeNanos = elapsedRealtimeNanos;
     }
 
     /**
-     * The current time, according to the Gnss location provider. */
-    public long getTime() {
-        return mTime;
+     * The Unix epoch time in millis, according to the Gnss location provider.
+     */
+    public long getUnixEpochTimeMillis() {
+        return mUnixEpochTimeMillis;
     }
 
     /**
-     * The elapsed nanos since boot {@link #getTime} was computed at.
+     * The elapsed nanos since boot when {@link #getUnixEpochTimeMillis} was the current time.
      */
     public long getElapsedRealtimeNanos() {
         return mElapsedRealtimeNanos;
@@ -49,7 +53,7 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeLong(mTime);
+        out.writeLong(mUnixEpochTimeMillis);
         out.writeLong(mElapsedRealtimeNanos);
     }
 
@@ -58,8 +62,18 @@
         return 0;
     }
 
+    @Override
+    public String toString() {
+        return "LocationTime{"
+                + "mUnixEpochTimeMillis=" + Instant.ofEpochMilli(mUnixEpochTimeMillis)
+                + "(" + mUnixEpochTimeMillis + ")"
+                + ", mElapsedRealtimeNanos=" + Duration.ofNanos(mElapsedRealtimeNanos)
+                + "(" + mElapsedRealtimeNanos + ")"
+                + '}';
+    }
+
     public static final @NonNull Parcelable.Creator<LocationTime> CREATOR =
-            new Parcelable.Creator<LocationTime>() {
+            new Parcelable.Creator<>() {
                 public LocationTime createFromParcel(Parcel in) {
                     long time = in.readLong();
                     long elapsedRealtimeNanos = in.readLong();
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 546f0c6..dea6097 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -1433,6 +1433,8 @@
         return new String("AudioAttributes:"
                 + " usage=" + usageToString()
                 + " content=" + contentTypeToString()
+                + (mSource != MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID
+                    ? " source=" + MediaRecorder.toLogFriendlyAudioSource(mSource) : "")
                 + " flags=0x" + Integer.toHexString(mFlags).toUpperCase()
                 + " tags=" + mFormattedTags
                 + " bundle=" + (mBundle == null ? "null" : mBundle.toString()));
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 6317320..aeb81c1 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -696,6 +696,13 @@
         baseRegisterPlayer(sessionId);
     }
 
+    private Parcel createPlayerIIdParcel() {
+        Parcel parcel = newRequest();
+        parcel.writeInt(INVOKE_ID_SET_PLAYER_IID);
+        parcel.writeInt(mPlayerIId);
+        return parcel;
+    }
+
     /*
      * Update the MediaPlayer SurfaceTexture.
      * Call after setting a new display surface.
@@ -712,6 +719,7 @@
     private static final int INVOKE_ID_DESELECT_TRACK = 5;
     private static final int INVOKE_ID_SET_VIDEO_SCALE_MODE = 6;
     private static final int INVOKE_ID_GET_SELECTED_TRACK = 7;
+    private static final int INVOKE_ID_SET_PLAYER_IID = 8;
 
     /**
      * Create a request parcel which can be routed to the native media
@@ -1309,16 +1317,26 @@
      * @throws IllegalStateException if it is called in an invalid state
      */
     public void prepare() throws IOException, IllegalStateException {
-        _prepare();
+        Parcel piidParcel = createPlayerIIdParcel();
+        try {
+            int retCode = _prepare(piidParcel);
+            if (retCode != 0) {
+                Log.w(TAG, "prepare(): could not set piid " + mPlayerIId);
+            }
+        } finally {
+            piidParcel.recycle();
+        }
         scanInternalSubtitleTracks();
 
         // DrmInfo, if any, has been resolved by now.
         synchronized (mDrmLock) {
             mDrmInfoResolved = true;
         }
+
     }
 
-    private native void _prepare() throws IOException, IllegalStateException;
+    /** Returns the result of sending the {@code piidParcel} to the MediaPlayerService. */
+    private native int _prepare(Parcel piidParcel) throws IOException, IllegalStateException;
 
     /**
      * Prepares the player for playback, asynchronously.
@@ -1330,7 +1348,20 @@
      *
      * @throws IllegalStateException if it is called in an invalid state
      */
-    public native void prepareAsync() throws IllegalStateException;
+    public void prepareAsync() throws IllegalStateException {
+        Parcel piidParcel = createPlayerIIdParcel();
+        try {
+            int retCode = _prepareAsync(piidParcel);
+            if (retCode != 0) {
+                Log.w(TAG, "prepareAsync(): could not set piid " + mPlayerIId);
+            }
+        } finally {
+            piidParcel.recycle();
+        }
+    }
+
+    /** Returns the result of sending the {@code piidParcel} to the MediaPlayerService. */
+    private native int _prepareAsync(Parcel piidParcel) throws IllegalStateException;
 
     /**
      * Starts or resumes playback. If playback had previously been paused,
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategy.java b/media/java/android/media/audiopolicy/AudioProductStrategy.java
index f957498..98819a3 100644
--- a/media/java/android/media/audiopolicy/AudioProductStrategy.java
+++ b/media/java/android/media/audiopolicy/AudioProductStrategy.java
@@ -22,7 +22,6 @@
 import android.annotation.TestApi;
 import android.media.AudioAttributes;
 import android.media.AudioSystem;
-import android.media.MediaRecorder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -130,9 +129,7 @@
                 return aa;
             }
         }
-        return new AudioAttributes.Builder()
-            .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
-            .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
+        return DEFAULT_ATTRIBUTES;
     }
 
     /**
@@ -217,7 +214,7 @@
     @SystemApi
     public @NonNull AudioAttributes getAudioAttributes() {
         // We need a choice, so take the first one
-        return mAudioAttributesGroups.length == 0 ? (new AudioAttributes.Builder().build())
+        return mAudioAttributesGroups.length == 0 ? DEFAULT_ATTRIBUTES
                 : mAudioAttributesGroups[0].getAudioAttributes();
     }
 
@@ -358,8 +355,7 @@
      * Default attributes, with default source to be aligned with native.
      */
     private static final @NonNull AudioAttributes DEFAULT_ATTRIBUTES =
-            new AudioAttributes.Builder().setCapturePreset(MediaRecorder.AudioSource.DEFAULT)
-                                         .build();
+            new AudioAttributes.Builder().build();
 
     /**
      * @hide
@@ -429,8 +425,7 @@
 
         public @NonNull AudioAttributes getAudioAttributes() {
             // We need a choice, so take the first one
-            return mAudioAttributes.length == 0 ? (new AudioAttributes.Builder().build())
-                    : mAudioAttributes[0];
+            return mAudioAttributes.length == 0 ? DEFAULT_ATTRIBUTES : mAudioAttributes[0];
         }
 
         /**
diff --git a/media/java/android/media/projection/MediaProjectionGlobal.java b/media/java/android/media/projection/MediaProjectionGlobal.java
new file mode 100644
index 0000000..4374a05
--- /dev/null
+++ b/media/java/android/media/projection/MediaProjectionGlobal.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.projection;
+
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.hardware.display.DisplayManagerGlobal;
+import android.hardware.display.IDisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.hardware.display.VirtualDisplayConfig;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.view.Surface;
+
+/**
+ * This is a helper for MediaProjection when requests are made from outside an application. This
+ * should only be used by processes running as shell as a way to capture recordings without being
+ * an application. The requests will fail if coming from any process that's not Shell.
+ * @hide
+ */
+@SystemApi
+public class MediaProjectionGlobal {
+    private static final Object sLock = new Object();
+    private static MediaProjectionGlobal sInstance;
+
+    /**
+     * @return The instance of {@link MediaProjectionGlobal}
+     */
+    @NonNull
+    public static MediaProjectionGlobal getInstance() {
+        synchronized (sLock) {
+            if (sInstance == null) {
+                final IBinder displayBinder = ServiceManager.getService(Context.DISPLAY_SERVICE);
+                final IBinder packageBinder = ServiceManager.getService("package");
+                if (displayBinder != null && packageBinder != null) {
+                    sInstance = new MediaProjectionGlobal(
+                                    IDisplayManager.Stub.asInterface(displayBinder),
+                                    IPackageManager.Stub.asInterface(packageBinder));
+                }
+            }
+            return sInstance;
+        }
+    }
+
+    private final IDisplayManager mDm;
+    private final IPackageManager mPackageManager;
+
+    private MediaProjectionGlobal(IDisplayManager dm, IPackageManager packageManager) {
+        mDm = dm;
+        mPackageManager = packageManager;
+    }
+
+    /**
+     * Creates a VirtualDisplay that will mirror the content of displayIdToMirror
+     * @param name The name for the virtual display
+     * @param width The initial width for the virtual display
+     * @param height The initial height for the virtual display
+     * @param displayIdToMirror The displayId that will be mirrored into the virtual display.
+     * @return VirtualDisplay that can be used to update properties.
+     */
+    @Nullable
+    public VirtualDisplay createVirtualDisplay(@NonNull String name, int width, int height,
+            int displayIdToMirror, @Nullable Surface surface) {
+
+        // Density doesn't matter since this virtual display is only used for mirroring.
+        VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
+                height, 1 /* densityDpi */)
+                .setFlags(VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR)
+                .setDisplayIdToMirror(displayIdToMirror);
+        if (surface != null) {
+            builder.setSurface(surface);
+        }
+        VirtualDisplayConfig virtualDisplayConfig = builder.build();
+
+        String[] packages;
+        try {
+            packages = mPackageManager.getPackagesForUid(Process.myUid());
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+
+        // Just use the first one since it just needs to match the package when looking it up by
+        // calling UID in system server.
+        // The call may come from a rooted device, in that case the requesting uid will be root so
+        // it will not have any package name
+        String packageName = packages == null ? null : packages[0];
+        DisplayManagerGlobal.VirtualDisplayCallback
+                callbackWrapper = new DisplayManagerGlobal.VirtualDisplayCallback(null, null);
+        int displayId;
+        try {
+            displayId = mDm.createVirtualDisplay(virtualDisplayConfig, callbackWrapper, null,
+                    packageName);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+        return DisplayManagerGlobal.getInstance().createVirtualDisplayWrapper(virtualDisplayConfig,
+                null, callbackWrapper, displayId);
+    }
+}
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index a548a47..da920bb 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -369,13 +369,13 @@
     setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);
 }
 
-static void
-android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
+static jint
+android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz, jobject piidParcel)
 {
     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
+    if (mp == nullptr) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
+        return UNKNOWN_ERROR;
     }
 
     // Handle the case where the display surface was set before the mp was
@@ -384,15 +384,20 @@
     mp->setVideoSurfaceTexture(st);
 
     process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
+
+    // update the piid
+    Parcel *request = parcelForJavaObject(env, piidParcel);
+    auto reply = std::make_unique<Parcel>();
+    return static_cast<jint>(mp->invoke(*request, reply.get()));
 }
 
-static void
-android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz)
+static jint
+android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz, jobject piidParcel)
 {
     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
+    if (mp == nullptr) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
+        return UNKNOWN_ERROR;
     }
 
     // Handle the case where the display surface was set before the mp was
@@ -401,6 +406,11 @@
     mp->setVideoSurfaceTexture(st);
 
     process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
+
+    // update the piid
+    Parcel *request = parcelForJavaObject(env, piidParcel);
+    auto reply = std::make_unique<Parcel>();
+    return static_cast<jint>(mp->invoke(*request, reply.get()));
 }
 
 static void
@@ -1380,8 +1390,8 @@
     {"_setDataSource",      "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},
     {"_setDataSource",      "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
     {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},
-    {"_prepare",            "()V",                              (void *)android_media_MediaPlayer_prepare},
-    {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},
+    {"_prepare",            "(Landroid/os/Parcel;)I",           (void *)android_media_MediaPlayer_prepare},
+    {"_prepareAsync",       "(Landroid/os/Parcel;)I",           (void *)android_media_MediaPlayer_prepareAsync},
     {"_start",              "()V",                              (void *)android_media_MediaPlayer_start},
     {"_stop",               "()V",                              (void *)android_media_MediaPlayer_stop},
     {"getVideoWidth",       "()I",                              (void *)android_media_MediaPlayer_getVideoWidth},
diff --git a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
index fccef23..9147ccd 100644
--- a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
@@ -16,22 +16,22 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Copiere de rezervă completă"</string>
+    <string name="backup_confirm_title" msgid="827563724209303345">"Backup complet"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restabilire completă"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"S-a solicitat crearea unei copii de rezervă complete a tuturor datelor pe un computer desktop conectat. Doriți să permiteți acest lucru?\n\nDacă nu ați solicitat dvs. copierea de rezervă, nu permiteți ca operațiunea să continue."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Faceți backup pentru date"</string>
-    <string name="deny_backup_button_label" msgid="6009119115581097708">"Nu creați copii de rezervă"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"S-a solicitat o restabilire completă a tuturor datelor de pe un computer desktop conectat. Doriți să permiteți acest lucru?\n\nDacă nu dvs. ați solicitat această restabilire, nu permiteți continuarea operațiunii. Acest proces va înlocui toate datele existente în prezent pe dispozitiv!"</string>
-    <string name="allow_restore_button_label" msgid="3081286752277127827">"Restabiliți datele dvs."</string>
-    <string name="deny_restore_button_label" msgid="1724367334453104378">"Nu restabiliți"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"Introduceți mai jos parola actuală pentru copia de rezervă:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Introduceți mai jos parola pentru criptarea dispozitivului."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Introduceți mai jos parola de criptare a dispozitivului. Aceasta va fi utilizată, de asemenea, pentru a cripta arhiva copiei de rezervă."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Introduceți o parolă pentru a o utiliza la criptarea datelor copiei de rezervă complete. Dacă acest câmp rămâne necompletat, pentru copierea de rezervă se va utiliza parola dvs. actuală."</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Dacă doriți să criptați datele copiei de rezervă complete, introduceți o parolă mai jos:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"Dacă datele pentru restabilire sunt criptate, introduceți parola mai jos:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Se începe copierea de rezervă..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Copierea de rezervă a fost finalizată"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"S-a solicitat crearea unui backup complet pentru toate datele pe un computer desktop conectat. Permiți acest lucru?\n\nDacă nu tu ai solicitat backupul, nu permite ca operațiunea să continue."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Fă backup pentru date"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Nu face backup"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"S-a solicitat o restabilire completă a tuturor datelor de pe un computer desktop conectat. Permiți acest lucru?\n\nDacă nu tu ai solicitat această restabilire, nu permite continuarea operațiunii. Acest proces va înlocui toate datele existente pe dispozitiv!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Restabilește datele"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Nu restabili"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Introdu mai jos parola actuală pentru backup:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Introdu mai jos parola pentru criptarea dispozitivului."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Introdu mai jos parola de criptare a dispozitivului. Aceasta va fi folosită și pentru a cripta arhiva backupului."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Introdu o parolă pentru a o folosi la criptarea datelor backupului complet. Dacă acest câmp rămâne necompletat, pentru backup se va folosi parola actuală:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Dacă vrei să criptezi datele backupului complet, introdu o parolă mai jos:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Dacă datele pentru restabilire sunt criptate, introdu parola mai jos:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Se începe backupul..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Backup terminat"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"Se pornește restabilirea..."</string>
     <string name="toast_restore_ended" msgid="1764041639199696132">"Restabilirea s-a încheiat"</string>
     <string name="toast_timeout" msgid="5276598587087626877">"Operația a expirat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 619468e..1d87de9 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -19,16 +19,16 @@
     <string name="app_label" msgid="4470785958457506021">"Manager de dispozitiv Companion"</string>
     <string name="confirmation_title" msgid="3785000297483688997">"Permiteți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să vă acceseze dispozitivul &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ceas"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Alegeți un profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pe care să îl gestioneze &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Alege un profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pe care să îl gestioneze &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="3002344206574997652">"Această aplicație este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să interacționeze cu notificările dvs. și să vă acceseze permisiunile pentru Telefon, SMS, Agendă, Calendar, Jurnale de apeluri și Dispozitive din apropiere."</string>
     <string name="permission_apps" msgid="6142133265286656158">"Aplicații"</string>
     <string name="permission_apps_summary" msgid="798718816711515431">"Să redea în stream aplicațiile telefonului"</string>
-    <string name="title_app_streaming" msgid="2270331024626446950">"Permiteți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
+    <string name="title_app_streaming" msgid="2270331024626446950">"Permite ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele dvs."</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
-    <string name="title_computer" msgid="4693714143506569253">"Permiteți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
+    <string name="title_computer" msgid="4693714143506569253">"Permite ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="permission_notification" msgid="693762568127741203">"Notificări"</string>
     <string name="permission_notification_summary" msgid="884075314530071011">"Poate să citească toate notificările, inclusiv informații cum ar fi agenda, mesajele și fotografiile"</string>
@@ -38,7 +38,7 @@
     <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
     <string name="summary_generic" msgid="2346762210105903720"></string>
-    <string name="consent_yes" msgid="8344487259618762872">"Permiteți"</string>
+    <string name="consent_yes" msgid="8344487259618762872">"Permite"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nu permiteți"</string>
     <string name="consent_back" msgid="2560683030046918882">"Înapoi"</string>
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Oferiți aplicațiilor de pe &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; aceleași permisiuni ca pe &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CredentialManager/OWNERS b/packages/CredentialManager/OWNERS
new file mode 100644
index 0000000..f3b43c1
--- /dev/null
+++ b/packages/CredentialManager/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/credentials/OWNERS
diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml
index 03cb145..1f15619 100644
--- a/packages/PackageInstaller/res/values-ro/strings.xml
+++ b/packages/PackageInstaller/res/values-ro/strings.xml
@@ -17,10 +17,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="7488448184431507488">"Program de instalare a pachetelor"</string>
-    <string name="install" msgid="711829760615509273">"Instalați"</string>
-    <string name="update" msgid="3932142540719227615">"Actualizați"</string>
+    <string name="install" msgid="711829760615509273">"Instalează"</string>
+    <string name="update" msgid="3932142540719227615">"Actualizează"</string>
     <string name="done" msgid="6632441120016885253">"Gata"</string>
-    <string name="cancel" msgid="1018267193425558088">"Anulați"</string>
+    <string name="cancel" msgid="1018267193425558088">"Anulează"</string>
     <string name="installing" msgid="4921993079741206516">"Se instalează…"</string>
     <string name="installing_app" msgid="1165095864863849422">"Se instalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="install_done" msgid="5987363587661783896">"Aplicație instalată."</string>
@@ -36,7 +36,7 @@
     <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe tableta dvs."</string>
     <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe televizorul dvs."</string>
     <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe telefonul dvs."</string>
-    <string name="launch" msgid="3952550563999890101">"Deschideți"</string>
+    <string name="launch" msgid="3952550563999890101">"Deschide"</string>
     <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administratorul nu permite instalarea aplicațiilor obținute din surse necunoscute"</string>
     <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aplicațiile necunoscute nu pot fi instalate de acest utilizator"</string>
     <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Acest utilizator nu are permisiunea să instaleze aplicații"</string>
diff --git a/packages/SettingsLib/FooterPreference/res/values-ro/strings.xml b/packages/SettingsLib/FooterPreference/res/values-ro/strings.xml
index 2b50117..6619684 100644
--- a/packages/SettingsLib/FooterPreference/res/values-ro/strings.xml
+++ b/packages/SettingsLib/FooterPreference/res/values-ro/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="settingslib_learn_more_text" msgid="7385478101223578464">"Aflați mai multe"</string>
+    <string name="settingslib_learn_more_text" msgid="7385478101223578464">"Află mai multe"</string>
 </resources>
diff --git a/packages/SettingsLib/Spa/build.gradle b/packages/SettingsLib/Spa/build.gradle
index 5dc2aa0..f8667ed 100644
--- a/packages/SettingsLib/Spa/build.gradle
+++ b/packages/SettingsLib/Spa/build.gradle
@@ -16,7 +16,7 @@
 
 buildscript {
     ext {
-        spa_min_sdk = 31
+        spa_min_sdk = 21
         jetpack_compose_version = '1.2.0-alpha04'
         jetpack_compose_material3_version = '1.0.0-alpha06'
     }
diff --git a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
index e34fedd..e583138 100644
--- a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
+++ b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml
@@ -35,5 +35,13 @@
             android:name=".GalleryDebugActivity"
             android:exported="true">
         </activity>
+
+        <provider
+            android:name=".GalleryEntryProvider"
+            android:authorities="com.android.spa.gallery.provider"
+            android:enabled="true"
+            android:exported="false">
+        </provider>
+
     </application>
 </manifest>
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt
index 317346d..1ebc5da 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt
@@ -18,4 +18,8 @@
 
 import com.android.settingslib.spa.framework.DebugActivity
 
-class GalleryDebugActivity : DebugActivity(SpaEnvironment.EntryRepository, MainActivity::class.java)
+class GalleryDebugActivity : DebugActivity(
+    SpaEnvironment.EntryRepository,
+    browseActivityClass = MainActivity::class.java,
+    entryProviderAuthorities = "com.android.spa.gallery.provider",
+)
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryEntryProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryEntryProvider.kt
new file mode 100644
index 0000000..d3e0096
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryEntryProvider.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.gallery
+
+import com.android.settingslib.spa.framework.EntryProvider
+
+class GalleryEntryProvider : EntryProvider(
+    SpaEnvironment.EntryRepository,
+    browseActivityClass = MainActivity::class.java,
+)
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
index 787d096..773e5f3 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
@@ -16,9 +16,12 @@
 
 package com.android.settingslib.spa.gallery
 
+import android.os.Bundle
+import androidx.navigation.NamedNavArgument
 import com.android.settingslib.spa.framework.common.SettingsEntryRepository
 import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
+import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
 import com.android.settingslib.spa.gallery.home.HomePageProvider
 import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
 import com.android.settingslib.spa.gallery.page.FooterPageProvider
@@ -30,8 +33,35 @@
 import com.android.settingslib.spa.gallery.preference.PreferencePageProvider
 import com.android.settingslib.spa.gallery.preference.SwitchPreferencePageProvider
 import com.android.settingslib.spa.gallery.preference.TwoTargetSwitchPreferencePageProvider
+import com.android.settingslib.spa.gallery.ui.CategoryPageProvider
 import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
 
+/**
+ * Enum to define all SPP name here.
+ * Since the SPP name would be used in log, DO NOT change it once it is set. One can still change
+ * the display name for better readability if necessary.
+ */
+enum class SettingsPageProviderEnum(val displayName: String) {
+    HOME("home"),
+    PREFERENCE("preference"),
+    ARGUMENT("argument"),
+
+    // Add your SPPs
+}
+
+fun createSettingsPage(
+    SppName: SettingsPageProviderEnum,
+    parameter: List<NamedNavArgument> = emptyList(),
+    arguments: Bundle? = null
+): SettingsPage {
+    return SettingsPage(
+        name = SppName.name,
+        displayName = SppName.displayName,
+        parameter = parameter,
+        arguments = arguments,
+    )
+}
+
 object SpaEnvironment {
     val PageProviderRepository: SettingsPageProviderRepository by
     lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
@@ -49,9 +79,11 @@
                 SettingsPagerPageProvider,
                 FooterPageProvider,
                 IllustrationPageProvider,
+                CategoryPageProvider,
+                ActionButtonPageProvider,
             ),
             rootPages = listOf(
-                SettingsPage.create(HomePageProvider.name)
+                createSettingsPage(SettingsPageProviderEnum.HOME)
             )
         )
     }
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt
new file mode 100644
index 0000000..96e2498
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.gallery.button
+
+import android.os.Bundle
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Delete
+import androidx.compose.material.icons.outlined.Launch
+import androidx.compose.material.icons.outlined.WarningAmber
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.tooling.preview.Preview
+import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
+import com.android.settingslib.spa.framework.common.SettingsPage
+import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.widget.button.ActionButton
+import com.android.settingslib.spa.widget.button.ActionButtons
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.scaffold.RegularScaffold
+
+private const val TITLE = "Sample ActionButton"
+
+object ActionButtonPageProvider : SettingsPageProvider {
+    override val name = "ActionButton"
+
+    @Composable
+    override fun Page(arguments: Bundle?) {
+        ActionButtonPage()
+    }
+
+    fun buildInjectEntry(): SettingsEntryBuilder {
+        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+            .setIsAllowSearch(true)
+            .setUiLayoutFn {
+                Preference(object : PreferenceModel {
+                    override val title = TITLE
+                    override val onClick = navigator(name)
+                })
+            }
+    }
+}
+
+@Composable
+fun ActionButtonPage() {
+    RegularScaffold(title = TITLE) {
+        val actionButtons = listOf(
+            ActionButton(text = "Open", imageVector = Icons.Outlined.Launch) {},
+            ActionButton(text = "Uninstall", imageVector = Icons.Outlined.Delete) {},
+            ActionButton(text = "Force stop", imageVector = Icons.Outlined.WarningAmber) {},
+        )
+        ActionButtons(actionButtons)
+    }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun ActionButtonPagePreview() {
+    SettingsTheme {
+        ActionButtonPage()
+    }
+}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
index d8ef937..c8a4650 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
@@ -21,10 +21,11 @@
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.gallery.R
+import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
+import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
 import com.android.settingslib.spa.gallery.page.ArgumentPageModel
 import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
 import com.android.settingslib.spa.gallery.page.FooterPageProvider
@@ -32,22 +33,24 @@
 import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
 import com.android.settingslib.spa.gallery.page.SliderPageProvider
 import com.android.settingslib.spa.gallery.preference.PreferenceMainPageProvider
+import com.android.settingslib.spa.gallery.ui.CategoryPageProvider
 import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
 import com.android.settingslib.spa.widget.scaffold.HomeScaffold
 
 object HomePageProvider : SettingsPageProvider {
-    override val name = "Home"
+    override val name = SettingsPageProviderEnum.HOME.name
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         return listOf(
-            PreferenceMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
-            ArgumentPageProvider.buildInjectEntry("foo")!!.setLink(fromPage = owner).build(),
-            SliderPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
-            SpinnerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
-            SettingsPagerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
-            FooterPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
-            IllustrationPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
+            PreferenceMainPageProvider.buildInjectEntry().build(),
+            ArgumentPageProvider.buildInjectEntry("foo")!!.build(),
+            SliderPageProvider.buildInjectEntry().build(),
+            SpinnerPageProvider.buildInjectEntry().build(),
+            SettingsPagerPageProvider.buildInjectEntry().build(),
+            FooterPageProvider.buildInjectEntry().build(),
+            IllustrationPageProvider.buildInjectEntry().build(),
+            CategoryPageProvider.buildInjectEntry().build(),
+            ActionButtonPageProvider.buildInjectEntry().build(),
         )
     }
 
@@ -55,7 +58,7 @@
     override fun Page(arguments: Bundle?) {
         HomeScaffold(title = stringResource(R.string.app_name)) {
             for (entry in buildEntry(arguments)) {
-                if (entry.name.startsWith(ArgumentPageModel.name)) {
+                if (entry.owner.isCreateBy(SettingsPageProviderEnum.ARGUMENT.name)) {
                     entry.UiLayout(ArgumentPageModel.buildArgument(intParam = 0))
                 } else {
                     entry.UiLayout()
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
index e32de7a..cc0a79a 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
@@ -24,23 +24,38 @@
 import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
+import com.android.settingslib.spa.gallery.createSettingsPage
 import com.android.settingslib.spa.widget.preference.Preference
 import com.android.settingslib.spa.widget.scaffold.RegularScaffold
 
 object ArgumentPageProvider : SettingsPageProvider {
-    override val name = ArgumentPageModel.name
+    // Defines all entry name in this page.
+    // Note that entry name would be used in log. DO NOT change it once it is set.
+    // One can still change the display name for better readability if necessary.
+    private enum class EntryEnum(val displayName: String) {
+        STRING_PARAM("string_param"),
+        INT_PARAM("int_param"),
+    }
+
+    private fun createEntry(owner: SettingsPage, entry: EntryEnum): SettingsEntryBuilder {
+        return SettingsEntryBuilder.create(owner, entry.name, entry.displayName)
+    }
+
+    override val name = SettingsPageProviderEnum.ARGUMENT.name
 
     override val parameter = ArgumentPageModel.parameter
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
         if (!ArgumentPageModel.isValidArgument(arguments)) return emptyList()
 
-        val owner = SettingsPage.create(name, parameter, arguments)
+        val owner = createSettingsPage(SettingsPageProviderEnum.ARGUMENT, parameter, arguments)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
-            SettingsEntryBuilder.create("string_param", owner)
+            createEntry(owner, EntryEnum.STRING_PARAM)
                 // Set attributes
                 .setIsAllowSearch(true)
+                .setSearchDataFn { ArgumentPageModel.genStringParamSearchData() }
                 .setUiLayoutFn {
                     // Set ui rendering
                     Preference(ArgumentPageModel.create(it).genStringParamPreferenceModel())
@@ -48,9 +63,10 @@
         )
 
         entryList.add(
-            SettingsEntryBuilder.create("int_param", owner)
+            createEntry(owner, EntryEnum.INT_PARAM)
                 // Set attributes
                 .setIsAllowSearch(true)
+                .setSearchDataFn { ArgumentPageModel.genIntParamSearchData() }
                 .setUiLayoutFn {
                     // Set ui rendering
                     Preference(ArgumentPageModel.create(it).genIntParamPreferenceModel())
@@ -68,11 +84,12 @@
         if (!ArgumentPageModel.isValidArgument(arguments)) return null
 
         return SettingsEntryBuilder.createInject(
-            entryName = "${name}_$stringParam",
-            owner = SettingsPage.create(name, parameter, arguments)
+            owner = createSettingsPage(SettingsPageProviderEnum.ARGUMENT, parameter, arguments),
+            displayName = "${name}_$stringParam",
         )
             // Set attributes
             .setIsAllowSearch(false)
+            .setSearchDataFn { ArgumentPageModel.genInjectSearchData() }
             .setUiLayoutFn {
                 // Set ui rendering
                 Preference(ArgumentPageModel.create(it).genInjectPreferenceModel())
@@ -83,7 +100,7 @@
     override fun Page(arguments: Bundle?) {
         RegularScaffold(title = ArgumentPageModel.create(arguments).genPageTitle()) {
             for (entry in buildEntry(arguments)) {
-                if (entry.name.startsWith(name)) {
+                if (entry.owner.isCreateBy(SettingsPageProviderEnum.ARGUMENT.name)) {
                     entry.UiLayout(ArgumentPageModel.buildNextArgument(arguments))
                 } else {
                     entry.UiLayout()
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
index 6e86fd7..e75d09b 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
@@ -23,22 +23,28 @@
 import androidx.navigation.NavType
 import androidx.navigation.navArgument
 import com.android.settingslib.spa.framework.BrowseActivity
+import com.android.settingslib.spa.framework.common.EntrySearchData
 import com.android.settingslib.spa.framework.common.PageModel
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.compose.stateOf
 import com.android.settingslib.spa.framework.util.getIntArg
 import com.android.settingslib.spa.framework.util.getStringArg
 import com.android.settingslib.spa.framework.util.navLink
+import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
 import com.android.settingslib.spa.widget.preference.PreferenceModel
 
-private const val TITLE = "Sample page with arguments"
+// Defines all the resources for this page.
+// In real Settings App, resources data is defined in xml, rather than SPP.
+private const val PAGE_TITLE = "Sample page with arguments"
+private const val STRING_PARAM_TITLE = "String param value"
+private const val INT_PARAM_TITLE = "Int param value"
 private const val STRING_PARAM_NAME = "stringParam"
 private const val INT_PARAM_NAME = "intParam"
+private val ARGUMENT_PAGE_KEYWORDS = listOf("argument keyword1", "argument keyword2")
 
 class ArgumentPageModel : PageModel() {
 
     companion object {
-        const val name = "Argument"
         val parameter = listOf(
             navArgument(STRING_PARAM_NAME) { type = NavType.StringType },
             navArgument(INT_PARAM_NAME) { type = NavType.IntType },
@@ -62,6 +68,18 @@
             return (stringParam != null && listOf("foo", "bar").contains(stringParam))
         }
 
+        fun genStringParamSearchData(): EntrySearchData {
+            return EntrySearchData(title = STRING_PARAM_TITLE)
+        }
+
+        fun genIntParamSearchData(): EntrySearchData {
+            return EntrySearchData(title = INT_PARAM_TITLE)
+        }
+
+        fun genInjectSearchData(): EntrySearchData {
+            return EntrySearchData(title = PAGE_TITLE, keyword = ARGUMENT_PAGE_KEYWORDS)
+        }
+
         @Composable
         fun create(arguments: Bundle?): ArgumentPageModel {
             val pageModel: ArgumentPageModel = viewModel(key = arguments.toString())
@@ -70,7 +88,7 @@
         }
     }
 
-    private val title = TITLE
+    private val title = PAGE_TITLE
     private var arguments: Bundle? = null
     private var stringParam: String? = null
     private var intParam: Int? = null
@@ -92,7 +110,7 @@
     @Composable
     fun genStringParamPreferenceModel(): PreferenceModel {
         return object : PreferenceModel {
-            override val title = "String param value"
+            override val title = STRING_PARAM_TITLE
             override val summary = stateOf(stringParam!!)
         }
     }
@@ -100,7 +118,7 @@
     @Composable
     fun genIntParamPreferenceModel(): PreferenceModel {
         return object : PreferenceModel {
-            override val title = "Int param value"
+            override val title = INT_PARAM_TITLE
             override val summary = stateOf(intParam!!.toString())
         }
     }
@@ -114,7 +132,8 @@
         return object : PreferenceModel {
             override val title = genPageTitle()
             override val summary = stateOf(summaryArray.joinToString(", "))
-            override val onClick = navigator(name + parameter.navLink(arguments))
+            override val onClick = navigator(
+                SettingsPageProviderEnum.ARGUMENT.displayName + parameter.navLink(arguments))
         }
     }
 }
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
index cbd028d..9fc736c 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
@@ -18,132 +18,166 @@
 
 import android.os.Bundle
 import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Autorenew
 import androidx.compose.material.icons.outlined.DisabledByDefault
 import androidx.compose.material.icons.outlined.TouchApp
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.derivedStateOf
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.produceState
-import androidx.compose.runtime.saveable.rememberSaveable
-import androidx.compose.runtime.setValue
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.remember
 import androidx.compose.ui.tooling.preview.Preview
+import com.android.settingslib.spa.framework.common.EntrySearchData
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
-import com.android.settingslib.spa.framework.compose.navigator
-import com.android.settingslib.spa.framework.compose.toState
 import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
+import com.android.settingslib.spa.gallery.createSettingsPage
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.ASYNC_PREFERENCE_TITLE
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.AUTO_UPDATE_PREFERENCE_TITLE
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.DISABLE_PREFERENCE_SUMMARY
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.DISABLE_PREFERENCE_TITLE
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.MANUAL_UPDATE_PREFERENCE_TITLE
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.PAGE_TITLE
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_KEYWORDS
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_SUMMARY
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_TITLE
+import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.logMsg
 import com.android.settingslib.spa.widget.preference.Preference
 import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.preference.SimplePreferenceMarco
 import com.android.settingslib.spa.widget.scaffold.RegularScaffold
 import com.android.settingslib.spa.widget.ui.SettingsIcon
-import kotlinx.coroutines.delay
-
-private const val TITLE = "Sample Preference"
 
 object PreferencePageProvider : SettingsPageProvider {
-    override val name = "Preference"
+    // Defines all entry name in this page.
+    // Note that entry name would be used in log. DO NOT change it once it is set.
+    // One can still change the display name for better readability if necessary.
+    enum class EntryEnum(val displayName: String) {
+        SIMPLE_PREFERENCE("preference"),
+        SUMMARY_PREFERENCE("preference_with_summary"),
+        DISABLED_PREFERENCE("preference_disable"),
+        ASYNC_SUMMARY_PREFERENCE("preference_with_async_summary"),
+        MANUAL_UPDATE_PREFERENCE("preference_actionable"),
+        AUTO_UPDATE_PREFERENCE("preference_auto_update"),
+    }
+
+    override val name = SettingsPageProviderEnum.PREFERENCE.name
+    private val owner = createSettingsPage(SettingsPageProviderEnum.PREFERENCE)
+
+    private fun createEntry(entry: EntryEnum): SettingsEntryBuilder {
+        return SettingsEntryBuilder.create(owner, entry.name, entry.displayName)
+    }
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
-            SettingsEntryBuilder.create("Preference", owner)
+            createEntry(EntryEnum.SIMPLE_PREFERENCE)
                 .setIsAllowSearch(true)
-                .setUiLayoutFn {
-                    Preference(object : PreferenceModel {
-                        override val title = "Preference"
-                    })
-                }.build()
+                .setMarco {
+                    logMsg("create marco for ${EntryEnum.SIMPLE_PREFERENCE}")
+                    SimplePreferenceMarco(title = SIMPLE_PREFERENCE_TITLE)
+                }
+                .build()
         )
         entryList.add(
-            SettingsEntryBuilder.create("Preference with summary", owner)
+            createEntry(EntryEnum.SUMMARY_PREFERENCE)
                 .setIsAllowSearch(true)
-                .setUiLayoutFn {
-                    Preference(object : PreferenceModel {
-                        override val title = "Preference"
-                        override val summary = "With summary".toState()
-                    })
-                }.build()
+                .setMarco {
+                    logMsg("create marco for ${EntryEnum.SUMMARY_PREFERENCE}")
+                    SimplePreferenceMarco(
+                        title = SIMPLE_PREFERENCE_TITLE,
+                        summary = SIMPLE_PREFERENCE_SUMMARY,
+                        searchKeywords = SIMPLE_PREFERENCE_KEYWORDS,
+                    )
+                }
+                .build()
         )
         entryList.add(
-            SettingsEntryBuilder.create("Preference with async summary", owner)
+            createEntry(EntryEnum.DISABLED_PREFERENCE)
                 .setIsAllowSearch(true)
+                .setMarco {
+                    logMsg("create marco for ${EntryEnum.DISABLED_PREFERENCE}")
+                    SimplePreferenceMarco(
+                        title = DISABLE_PREFERENCE_TITLE,
+                        summary = DISABLE_PREFERENCE_SUMMARY,
+                        disabled = true,
+                        icon = Icons.Outlined.DisabledByDefault,
+                    )
+                }
+                .build()
+        )
+        entryList.add(
+            createEntry(EntryEnum.ASYNC_SUMMARY_PREFERENCE)
+                .setIsAllowSearch(true)
+                .setSearchDataFn {
+                    EntrySearchData(title = ASYNC_PREFERENCE_TITLE)
+                }
                 .setUiLayoutFn {
-                    Preference(object : PreferenceModel {
-                        override val title = "Preference"
-                        override val summary = produceState(initialValue = " ") {
-                            delay(1000L)
-                            value = "Async summary"
+                    val model = PreferencePageModel.create()
+                    val asyncSummary = remember { model.getAsyncSummary() }
+                    Preference(
+                        object : PreferenceModel {
+                            override val title = ASYNC_PREFERENCE_TITLE
+                            override val summary = asyncSummary
                         }
-                    })
+                    )
                 }.build()
         )
         entryList.add(
-            SettingsEntryBuilder.create("Click me", owner)
+            createEntry(EntryEnum.MANUAL_UPDATE_PREFERENCE)
                 .setIsAllowSearch(true)
                 .setUiLayoutFn {
-                    var count by rememberSaveable { mutableStateOf(0) }
-                    Preference(object : PreferenceModel {
-                        override val title = "Click me"
-                        override val summary = derivedStateOf { count.toString() }
-                        override val onClick: (() -> Unit) = { count++ }
-                        override val icon = @Composable {
-                            SettingsIcon(imageVector = Icons.Outlined.TouchApp)
+                    val model = PreferencePageModel.create()
+                    val manualUpdaterSummary = remember { model.getManualUpdaterSummary() }
+                    Preference(
+                        object : PreferenceModel {
+                            override val title = MANUAL_UPDATE_PREFERENCE_TITLE
+                            override val summary = manualUpdaterSummary
+                            override val onClick = { model.manualUpdaterOnClick() }
+                            override val icon = @Composable {
+                                SettingsIcon(imageVector = Icons.Outlined.TouchApp)
+                            }
                         }
-                    })
+                    )
                 }.build()
         )
         entryList.add(
-            SettingsEntryBuilder.create("Ticker", owner)
+            createEntry(EntryEnum.AUTO_UPDATE_PREFERENCE)
                 .setIsAllowSearch(true)
                 .setUiLayoutFn {
-                    var ticks by rememberSaveable { mutableStateOf(0) }
-                    LaunchedEffect(ticks) {
-                        delay(1000L)
-                        ticks++
-                    }
-                    Preference(object : PreferenceModel {
-                        override val title = "Ticker"
-                        override val summary = derivedStateOf { ticks.toString() }
-                    })
-                }.build()
-        )
-        entryList.add(
-            SettingsEntryBuilder.create("Disabled", owner)
-                .setIsAllowSearch(true)
-                .setUiLayoutFn {
-                    Preference(object : PreferenceModel {
-                        override val title = "Disabled"
-                        override val summary = "Disabled".toState()
-                        override val enabled = false.toState()
-                        override val icon = @Composable {
-                            SettingsIcon(imageVector = Icons.Outlined.DisabledByDefault)
+                    val model = PreferencePageModel.create()
+                    val autoUpdaterSummary = remember { model.getAutoUpdaterSummary() }
+                    Preference(
+                        object : PreferenceModel {
+                            override val title = AUTO_UPDATE_PREFERENCE_TITLE
+                            override val summary = autoUpdaterSummary.observeAsState(" ")
+                            override val icon = @Composable {
+                                SettingsIcon(imageVector = Icons.Outlined.Autorenew)
+                            }
                         }
-                    })
-                }.build()
+                    )
+                }
+                .build()
         )
 
         return entryList
     }
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner = owner)
             .setIsAllowSearch(true)
-            .setUiLayoutFn {
-                Preference(object : PreferenceModel {
-                    override val title = TITLE
-                    override val onClick = navigator(name)
-                })
+            .setMarco {
+                logMsg("create marco for INJECT entry")
+                SimplePreferenceMarco(
+                    title = PAGE_TITLE,
+                    clickRoute = SettingsPageProviderEnum.PREFERENCE.name
+                )
             }
     }
 
     @Composable
     override fun Page(arguments: Bundle?) {
-        RegularScaffold(title = TITLE) {
+        RegularScaffold(title = PAGE_TITLE) {
             for (entry in buildEntry(arguments)) {
                 entry.UiLayout()
             }
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageModel.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageModel.kt
new file mode 100644
index 0000000..1188e1e
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageModel.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.gallery.preference
+
+import android.os.Bundle
+import android.util.Log
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.compose.viewModel
+import com.android.settingslib.spa.framework.common.PageModel
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+class PreferencePageModel : PageModel() {
+    companion object {
+        // Defines all the resources for this page.
+        // In real Settings App, resources data is defined in xml, rather than SPP.
+        const val PAGE_TITLE = "Sample Preference"
+        const val SIMPLE_PREFERENCE_TITLE = "Preference"
+        const val SIMPLE_PREFERENCE_SUMMARY = "Simple summary"
+        const val DISABLE_PREFERENCE_TITLE = "Disabled"
+        const val DISABLE_PREFERENCE_SUMMARY = "Disabled summary"
+        const val ASYNC_PREFERENCE_TITLE = "Async Preference"
+        private const val ASYNC_PREFERENCE_SUMMARY = "Async summary"
+        const val MANUAL_UPDATE_PREFERENCE_TITLE = "Manual Updater"
+        const val AUTO_UPDATE_PREFERENCE_TITLE = "Auto Updater"
+        val SIMPLE_PREFERENCE_KEYWORDS = listOf("simple keyword1", "simple keyword2")
+
+        @Composable
+        fun create(): PreferencePageModel {
+            val pageModel: PreferencePageModel = viewModel()
+            pageModel.initOnce()
+            return pageModel
+        }
+
+        fun logMsg(message: String) {
+            Log.d("PreferencePageModel", message)
+        }
+    }
+
+    private val asyncSummary = mutableStateOf(" ")
+
+    private val manualUpdater = mutableStateOf(0)
+
+    private val autoUpdater = object : MutableLiveData<String>(" ") {
+        private var tick = 0
+        private var updateJob: Job? = null
+        override fun onActive() {
+            logMsg("autoUpdater.active")
+            updateJob = viewModelScope.launch(Dispatchers.IO) {
+                while (true) {
+                    delay(1000L)
+                    tick++
+                    logMsg("autoUpdater.value $tick")
+                    postValue(tick.toString())
+                }
+            }
+        }
+
+        override fun onInactive() {
+            logMsg("autoUpdater.inactive")
+            updateJob?.cancel()
+        }
+    }
+
+    override fun initialize(arguments: Bundle?) {
+        logMsg("init with args " + arguments.toString())
+
+        viewModelScope.launch(Dispatchers.IO) {
+            delay(2000L)
+            asyncSummary.value = ASYNC_PREFERENCE_SUMMARY
+        }
+    }
+
+    fun getAsyncSummary(): State<String> {
+        logMsg("getAsyncSummary")
+        return asyncSummary
+    }
+
+    fun getManualUpdaterSummary(): State<String> {
+        logMsg("getManualUpdaterSummary")
+        return derivedStateOf { manualUpdater.value.toString() }
+    }
+
+    fun manualUpdaterOnClick() {
+        logMsg("manualUpdaterOnClick")
+        manualUpdater.value = manualUpdater.value + 1
+    }
+
+    fun getAutoUpdaterSummary(): LiveData<String> {
+        logMsg("getAutoUpdaterSummary")
+        return autoUpdater
+    }
+}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPage.kt
new file mode 100644
index 0000000..9a525bf
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPage.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.gallery.ui
+
+import android.os.Bundle
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.tooling.preview.Preview
+import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
+import com.android.settingslib.spa.framework.common.SettingsPage
+import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.framework.compose.stateOf
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.scaffold.RegularScaffold
+import com.android.settingslib.spa.widget.ui.Category
+import com.android.settingslib.spa.widget.ui.CategoryTitle
+
+private const val TITLE = "Sample Category"
+
+object CategoryPageProvider : SettingsPageProvider {
+    override val name = "Spinner"
+
+    fun buildInjectEntry(): SettingsEntryBuilder {
+        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+            .setIsAllowSearch(true)
+            .setUiLayoutFn {
+                Preference(object : PreferenceModel {
+                    override val title = TITLE
+                    override val onClick = navigator(name)
+                })
+            }
+    }
+
+    @Composable
+    override fun Page(arguments: Bundle?) {
+        CategoryPage()
+    }
+}
+
+@Composable
+private fun CategoryPage() {
+    RegularScaffold(title = TITLE) {
+        CategoryTitle("Category A")
+        Preference(remember {
+            object : PreferenceModel {
+                override val title = "Preference 1"
+                override val summary = stateOf("Summary 1")
+            }
+        })
+        Preference(remember {
+            object : PreferenceModel {
+                override val title = "Preference 2"
+                override val summary = stateOf("Summary 2")
+            }
+        })
+        Category("Category B") {
+            Preference(remember {
+                object : PreferenceModel {
+                    override val title = "Preference 3"
+                    override val summary = stateOf("Summary 3")
+                }
+            })
+            Preference(remember {
+                object : PreferenceModel {
+                    override val title = "Preference 4"
+                    override val summary = stateOf("Summary 4")
+                }
+            })
+        }
+    }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun SpinnerPagePreview() {
+    SettingsTheme {
+        SpinnerPageProvider.Page(null)
+    }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
index e5a1862..0bb631a 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
@@ -31,12 +31,23 @@
 import androidx.navigation.compose.rememberNavController
 import androidx.navigation.navArgument
 import com.android.settingslib.spa.R
-import com.android.settingslib.spa.framework.common.ROOT_PAGE_NAME
 import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
 import com.android.settingslib.spa.framework.compose.localNavController
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.framework.util.navRoute
 
+const val NULL_PAGE_NAME = "NULL"
+
+/**
+ * The Activity to render ALL SPA pages, and handles jumps between SPA pages.
+ * One can open any SPA page by:
+ *   $ adb shell am start -n <BrowseActivityComponent> -e spa:SpaActivity:destination <SpaPageRoute>
+ * For gallery, BrowseActivityComponent = com.android.settingslib.spa.gallery/.MainActivity
+ * For SettingsGoogle, BrowseActivityComponent = com.android.settings/.spa.SpaActivity
+ * Some examples:
+ *   $ adb shell am start -n <BrowseActivityComponent> -e spa:SpaActivity:destination HOME
+ *   $ adb shell am start -n <BrowseActivityComponent> -e spa:SpaActivity:destination ARGUMENT/bar/5
+ */
 open class BrowseActivity(
     private val sppRepository: SettingsPageProviderRepository,
 ) : ComponentActivity() {
@@ -55,8 +66,8 @@
     private fun MainContent() {
         val navController = rememberNavController()
         CompositionLocalProvider(navController.localNavController()) {
-            NavHost(navController, ROOT_PAGE_NAME) {
-                composable(ROOT_PAGE_NAME) {}
+            NavHost(navController, NULL_PAGE_NAME) {
+                composable(NULL_PAGE_NAME) {}
                 for (page in sppRepository.getAllProviders()) {
                     composable(
                         route = page.name + page.parameter.navRoute() +
@@ -82,7 +93,7 @@
         destinationNavigated.value = true
         LaunchedEffect(Unit) {
             val destination =
-                intent?.getStringExtra(KEY_DESTINATION) ?: sppRepository.getDefaultStartPageName()
+                intent?.getStringExtra(KEY_DESTINATION) ?: sppRepository.getDefaultStartPage()
             if (destination.isNotEmpty()) {
                 navController.navigate(destination) {
                     popUpTo(navController.graph.findStartDestination().id) {
@@ -94,7 +105,7 @@
     }
 
     companion object {
-        const val KEY_DESTINATION = "spa:SpaActivity:destination"
+        const val KEY_DESTINATION = "spaActivityDestination"
         const val HIGHLIGHT_ENTRY_PARAM_NAME = "highlightEntry"
     }
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt
index bd5aaa7..c4e88e1 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt
@@ -17,6 +17,7 @@
 package com.android.settingslib.spa.framework
 
 import android.content.Intent
+import android.net.Uri
 import android.os.Bundle
 import android.util.Log
 import androidx.activity.ComponentActivity
@@ -24,6 +25,7 @@
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.remember
 import androidx.compose.ui.platform.LocalContext
 import androidx.navigation.NavType
 import androidx.navigation.compose.NavHost
@@ -52,24 +54,22 @@
 private const val PARAM_NAME_PAGE_ID = "pid"
 private const val PARAM_NAME_ENTRY_ID = "eid"
 
+/**
+ * The Debug Activity to display all Spa Pages & Entries.
+ * One can open the debug activity by:
+ *   $ adb shell am start -n <Activity>
+ * For gallery, Activity = com.android.settingslib.spa.gallery/.GalleryDebugActivity
+ * For SettingsGoogle, Activity = com.android.settings/.spa.SpaDebugActivity
+ */
 open class DebugActivity(
     private val entryRepository: SettingsEntryRepository,
     private val browseActivityClass: Class<*>,
+    private val entryProviderAuthorities: String? = null,
 ) : ComponentActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         setTheme(R.style.Theme_SpaLib_DayNight)
         super.onCreate(savedInstanceState)
-
-        val packageName = browseActivityClass.packageName
-        val className = browseActivityClass.toString().removePrefix("class $packageName")
-        for (pageWithEntry in entryRepository.getAllPageWithEntry()) {
-            if (pageWithEntry.page.hasRuntimeParam()) continue
-            val route = pageWithEntry.page.buildRoute()
-            Log.d(
-                "DEBUG ACTIVITY",
-                "adb shell am start -n $packageName/$className -e $KEY_DESTINATION $route"
-            )
-        }
+        displayDebugMessage()
 
         setContent {
             SettingsTheme {
@@ -78,6 +78,31 @@
         }
     }
 
+    private fun displayDebugMessage() {
+        if (entryProviderAuthorities == null) return
+
+        try {
+            val query = EntryProvider.QueryEnum.PAGE_INFO_QUERY
+            contentResolver.query(
+                Uri.parse("content://$entryProviderAuthorities/${query.queryPath}"),
+                null, null, null
+            ).use { cursor ->
+                while (cursor != null && cursor.moveToNext()) {
+                    val route = cursor.getString(query, EntryProvider.ColumnEnum.PAGE_ROUTE)
+                    val entryCount = cursor.getInt(query, EntryProvider.ColumnEnum.PAGE_ENTRY_COUNT)
+                    val hasRuntimeParam =
+                        cursor.getBoolean(query, EntryProvider.ColumnEnum.HAS_RUNTIME_PARAM)
+                    Log.d(
+                        "DEBUG ACTIVITY", "Page Info: $route ($entryCount) " +
+                            (if (hasRuntimeParam) "with" else "no") + "-runtime-params"
+                    )
+                }
+            }
+        } catch (e: Exception) {
+            Log.e("DEBUG ACTIVITY", "Provider querying exception:", e)
+        }
+    }
+
     @Composable
     private fun MainContent() {
         val navController = rememberNavController()
@@ -89,13 +114,13 @@
                 composable(
                     route = "$ROUTE_PAGE/{$PARAM_NAME_PAGE_ID}",
                     arguments = listOf(
-                        navArgument(PARAM_NAME_PAGE_ID) { type = NavType.IntType },
+                        navArgument(PARAM_NAME_PAGE_ID) { type = NavType.StringType },
                     )
                 ) { navBackStackEntry -> OnePage(navBackStackEntry.arguments) }
                 composable(
                     route = "$ROUTE_ENTRY/{$PARAM_NAME_ENTRY_ID}",
                     arguments = listOf(
-                        navArgument(PARAM_NAME_ENTRY_ID) { type = NavType.IntType },
+                        navArgument(PARAM_NAME_ENTRY_ID) { type = NavType.StringType },
                     )
                 ) { navBackStackEntry -> OneEntry(navBackStackEntry.arguments) }
             }
@@ -104,13 +129,15 @@
 
     @Composable
     fun RootPage() {
+        val allPageWithEntry = remember { entryRepository.getAllPageWithEntry() }
+        val allEntry = remember { entryRepository.getAllEntries() }
         HomeScaffold(title = "Settings Debug") {
             Preference(object : PreferenceModel {
-                override val title = "List All Pages"
+                override val title = "List All Pages (${allPageWithEntry.size})"
                 override val onClick = navigator(route = ROUTE_All_PAGES)
             })
             Preference(object : PreferenceModel {
-                override val title = "List All Entries"
+                override val title = "List All Entries (${allEntry.size})"
                 override val onClick = navigator(route = ROUTE_All_ENTRIES)
             })
         }
@@ -118,14 +145,15 @@
 
     @Composable
     fun AllPages() {
-        RegularScaffold(title = "All Pages") {
-            for (pageWithEntry in entryRepository.getAllPageWithEntry()) {
+        val allPageWithEntry = remember { entryRepository.getAllPageWithEntry() }
+        RegularScaffold(title = "All Pages (${allPageWithEntry.size})") {
+            for (pageWithEntry in allPageWithEntry) {
                 Preference(object : PreferenceModel {
                     override val title =
                         "${pageWithEntry.page.displayName} (${pageWithEntry.entries.size})"
                     override val summary = pageWithEntry.page.formatArguments().toState()
                     override val onClick =
-                        navigator(route = ROUTE_PAGE + "/${pageWithEntry.page.id}")
+                        navigator(route = ROUTE_PAGE + "/${pageWithEntry.page.id()}")
                 })
             }
         }
@@ -133,16 +161,18 @@
 
     @Composable
     fun AllEntries() {
-        RegularScaffold(title = "All Entries") {
-            EntryList(entryRepository.getAllEntries())
+        val allEntry = remember { entryRepository.getAllEntries() }
+        RegularScaffold(title = "All Entries (${allEntry.size})") {
+            EntryList(allEntry)
         }
     }
 
     @Composable
     fun OnePage(arguments: Bundle?) {
-        val id = arguments!!.getInt(PARAM_NAME_PAGE_ID)
+        val id = arguments!!.getString(PARAM_NAME_PAGE_ID, "")
         val pageWithEntry = entryRepository.getPageWithEntry(id)!!
-        RegularScaffold(title = "Page ${pageWithEntry.page.displayName}") {
+        RegularScaffold(title = "Page - ${pageWithEntry.page.displayName}") {
+            Text(text = "id = ${pageWithEntry.page.id()}")
             Text(text = pageWithEntry.page.formatArguments())
             Text(text = "Entry size: ${pageWithEntry.entries.size}")
             Preference(model = object : PreferenceModel {
@@ -156,15 +186,16 @@
 
     @Composable
     fun OneEntry(arguments: Bundle?) {
-        val id = arguments!!.getInt(PARAM_NAME_ENTRY_ID)
+        val id = arguments!!.getString(PARAM_NAME_ENTRY_ID, "")
         val entry = entryRepository.getEntry(id)!!
-        RegularScaffold(title = "Entry ${entry.displayName}") {
+        val entryContent = remember { entry.formatContent() }
+        RegularScaffold(title = "Entry - ${entry.displayTitle()}") {
             Preference(model = object : PreferenceModel {
                 override val title = "open entry"
                 override val enabled = (!entry.hasRuntimeParam()).toState()
                 override val onClick = openEntry(entry)
             })
-            Text(text = entry.formatAll())
+            Text(text = entryContent)
         }
     }
 
@@ -172,10 +203,10 @@
     private fun EntryList(entries: Collection<SettingsEntry>) {
         for (entry in entries) {
             Preference(object : PreferenceModel {
-                override val title = entry.displayName
+                override val title = entry.displayTitle()
                 override val summary =
                     "${entry.fromPage?.displayName} -> ${entry.toPage?.displayName}".toState()
-                override val onClick = navigator(route = ROUTE_ENTRY + "/${entry.id}")
+                override val onClick = navigator(route = ROUTE_ENTRY + "/${entry.id()}")
             })
         }
     }
@@ -183,8 +214,8 @@
     @Composable
     private fun openPage(page: SettingsPage): (() -> Unit)? {
         if (page.hasRuntimeParam()) return null
-        val route = page.buildRoute()
         val context = LocalContext.current
+        val route = page.buildRoute()
         val intent = Intent(context, browseActivityClass).apply {
             putExtra(KEY_DESTINATION, route)
         }
@@ -197,8 +228,8 @@
     @Composable
     private fun openEntry(entry: SettingsEntry): (() -> Unit)? {
         if (entry.hasRuntimeParam()) return null
-        val route = entry.buildRoute()
         val context = LocalContext.current
+        val route = entry.buildRoute()
         val intent = Intent(context, browseActivityClass).apply {
             putExtra(KEY_DESTINATION, route)
         }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt
new file mode 100644
index 0000000..33f1eb5
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.framework
+
+import android.content.ComponentName
+import android.content.ContentProvider
+import android.content.ContentValues
+import android.content.Context
+import android.content.Intent
+import android.content.Intent.URI_INTENT_SCHEME
+import android.content.UriMatcher
+import android.content.pm.ProviderInfo
+import android.database.Cursor
+import android.database.MatrixCursor
+import android.net.Uri
+import android.util.Log
+import com.android.settingslib.spa.framework.common.SettingsEntryRepository
+import com.android.settingslib.spa.framework.common.SettingsPage
+
+/**
+ * The content provider to return entry related data, which can be used for search and hierarchy.
+ * One can query the provider result by:
+ *   $ adb shell content query --uri content://<AuthorityPath>/<QueryPath>
+ * For gallery, AuthorityPath = com.android.spa.gallery.provider
+ * For SettingsGoogle, AuthorityPath = com.android.settings.spa.provider
+ * Some examples:
+ *   $ adb shell content query --uri content://<AuthorityPath>/page_start
+ *   $ adb shell content query --uri content://<AuthorityPath>/page_info
+ */
+open class EntryProvider(
+    private val entryRepository: SettingsEntryRepository,
+    private val browseActivityClass: Class<*>? = null,
+) : ContentProvider() {
+
+    /**
+     * Enum to define all column names in provider.
+     */
+    enum class ColumnEnum(val id: String) {
+        PAGE_ID("pageId"),
+        PAGE_NAME("pageName"),
+        PAGE_ROUTE("pageRoute"),
+        PAGE_INTENT_URI("pageIntent"),
+        PAGE_ENTRY_COUNT("entryCount"),
+        HAS_RUNTIME_PARAM("hasRuntimeParam"),
+        PAGE_START_ADB("pageStartAdb"),
+    }
+
+    /**
+     * Enum to define all queries supported in the provider.
+     */
+    enum class QueryEnum(
+        val queryPath: String,
+        val queryMatchCode: Int,
+        val columnNames: List<ColumnEnum>
+    ) {
+        PAGE_START_COMMAND(
+            "page_start", 1,
+            listOf(ColumnEnum.PAGE_START_ADB)
+        ),
+        PAGE_INFO_QUERY(
+            "page_info", 2,
+            listOf(
+                ColumnEnum.PAGE_ID,
+                ColumnEnum.PAGE_NAME,
+                ColumnEnum.PAGE_ROUTE,
+                ColumnEnum.PAGE_INTENT_URI,
+                ColumnEnum.PAGE_ENTRY_COUNT,
+                ColumnEnum.HAS_RUNTIME_PARAM,
+            )
+        ),
+    }
+
+    private var uriMatcher: UriMatcher? = null
+
+    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
+        TODO("Implement this to handle requests to delete one or more rows")
+    }
+
+    override fun getType(uri: Uri): String? {
+        TODO(
+            "Implement this to handle requests for the MIME type of the data" +
+                "at the given URI"
+        )
+    }
+
+    override fun insert(uri: Uri, values: ContentValues?): Uri? {
+        TODO("Implement this to handle requests to insert a new row.")
+    }
+
+    override fun update(
+        uri: Uri,
+        values: ContentValues?,
+        selection: String?,
+        selectionArgs: Array<String>?
+    ): Int {
+        TODO("Implement this to handle requests to update one or more rows.")
+    }
+
+    override fun onCreate(): Boolean {
+        return true
+    }
+
+    override fun attachInfo(context: Context?, info: ProviderInfo?) {
+        uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
+        if (info != null) {
+            uriMatcher!!.addURI(
+                info.authority,
+                QueryEnum.PAGE_START_COMMAND.queryPath,
+                QueryEnum.PAGE_START_COMMAND.queryMatchCode
+            )
+            uriMatcher!!.addURI(
+                info.authority,
+                QueryEnum.PAGE_INFO_QUERY.queryPath,
+                QueryEnum.PAGE_INFO_QUERY.queryMatchCode
+            )
+        }
+        super.attachInfo(context, info)
+    }
+
+    override fun query(
+        uri: Uri,
+        projection: Array<String>?,
+        selection: String?,
+        selectionArgs: Array<String>?,
+        sortOrder: String?
+    ): Cursor? {
+        return try {
+            when (uriMatcher!!.match(uri)) {
+                QueryEnum.PAGE_START_COMMAND.queryMatchCode -> queryPageStartCommand()
+                QueryEnum.PAGE_INFO_QUERY.queryMatchCode -> queryPageInfo()
+                else -> throw UnsupportedOperationException("Unknown Uri $uri")
+            }
+        } catch (e: UnsupportedOperationException) {
+            throw e
+        } catch (e: Exception) {
+            Log.e("EntryProvider", "Provider querying exception:", e)
+            null
+        }
+    }
+
+    private fun queryPageStartCommand(): Cursor {
+        val cursor = MatrixCursor(QueryEnum.PAGE_START_COMMAND.getColumns())
+        for (pageWithEntry in entryRepository.getAllPageWithEntry()) {
+            val command = createBrowsePageAdbCommand(pageWithEntry.page)
+            if (command != null) {
+                cursor.newRow().add(ColumnEnum.PAGE_START_ADB.id, command)
+            }
+        }
+        return cursor
+    }
+
+    private fun queryPageInfo(): Cursor {
+        val cursor = MatrixCursor(QueryEnum.PAGE_INFO_QUERY.getColumns())
+        for (pageWithEntry in entryRepository.getAllPageWithEntry()) {
+            val page = pageWithEntry.page
+            cursor.newRow()
+                .add(ColumnEnum.PAGE_ID.id, page.id())
+                .add(ColumnEnum.PAGE_NAME.id, page.displayName)
+                .add(ColumnEnum.PAGE_ROUTE.id, page.buildRoute())
+                .add(ColumnEnum.PAGE_ENTRY_COUNT.id, pageWithEntry.entries.size)
+                .add(ColumnEnum.HAS_RUNTIME_PARAM.id, if (page.hasRuntimeParam()) 1 else 0)
+                .add(
+                    ColumnEnum.PAGE_INTENT_URI.id,
+                    createBrowsePageIntent(page).toUri(URI_INTENT_SCHEME)
+                )
+        }
+        return cursor
+    }
+
+    private fun createBrowsePageIntent(page: SettingsPage): Intent {
+        if (context == null || browseActivityClass == null || page.hasRuntimeParam())
+            return Intent()
+
+        return Intent().setComponent(ComponentName(context!!, browseActivityClass)).apply {
+            putExtra(BrowseActivity.KEY_DESTINATION, page.buildRoute())
+        }
+    }
+
+    private fun createBrowsePageAdbCommand(page: SettingsPage): String? {
+        if (context == null || page.hasRuntimeParam()) return null
+        val packageName = context!!.packageName
+        val activityName =
+            browseActivityClass?.name?.replace(packageName, "") ?: "<browse-activity-class>"
+        return "adb shell am start -n $packageName/$activityName" +
+            " -e ${BrowseActivity.KEY_DESTINATION} ${page.buildRoute()}"
+    }
+}
+
+fun EntryProvider.QueryEnum.getColumns(): Array<String> {
+    return columnNames.map { it.id }.toTypedArray()
+}
+
+fun EntryProvider.QueryEnum.getIndex(name: EntryProvider.ColumnEnum): Int {
+    return columnNames.indexOf(name)
+}
+
+fun Cursor.getString(query: EntryProvider.QueryEnum, columnName: EntryProvider.ColumnEnum): String {
+    return this.getString(query.getIndex(columnName))
+}
+
+fun Cursor.getInt(query: EntryProvider.QueryEnum, columnName: EntryProvider.ColumnEnum): Int {
+    return this.getInt(query.getIndex(columnName))
+}
+
+fun Cursor.getBoolean(
+    query: EntryProvider.QueryEnum,
+    columnName: EntryProvider.ColumnEnum
+): Boolean {
+    return this.getInt(query.getIndex(columnName)) == 1
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/EntryMarco.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/EntryMarco.kt
new file mode 100644
index 0000000..8399d12
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/EntryMarco.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.framework.common
+
+import androidx.compose.runtime.Composable
+
+/**
+ * Defines interface of a entry marco, which contains all entry functions to support different
+ * scenarios, such as browsing (UiLayout), search, etc.
+ * SPA team will rebuild some entry marcos, in order to make the entry creation easier.
+ */
+interface EntryMarco {
+    @Composable
+    fun UiLayout() {}
+    fun getSearchData(): EntrySearchData? = null
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/EntrySearchData.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/EntrySearchData.kt
new file mode 100644
index 0000000..9b262af
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/EntrySearchData.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.framework.common
+
+/**
+ * Defines Search data of one Settings entry.
+ */
+data class EntrySearchData(
+    val title: String = "",
+    val keyword: List<String> = emptyList(),
+) {
+    fun format(): String {
+        val content = listOf(
+            "search_title = $title",
+            "search_keyword = $keyword",
+        )
+        return content.joinToString("\n")
+    }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/PageModel.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/PageModel.kt
index ee12f02..edcca18 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/PageModel.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/PageModel.kt
@@ -22,7 +22,7 @@
 open class PageModel : ViewModel() {
     var initialized = false
 
-    fun initOnce(arguments: Bundle?) {
+    fun initOnce(arguments: Bundle? = null) {
         // Initialize only once
         if (initialized) return
         initialized = true
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt
index b0a1cbe..2239066 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt
@@ -18,96 +18,24 @@
 
 import android.os.Bundle
 import androidx.compose.runtime.Composable
-import androidx.navigation.NamedNavArgument
-import androidx.navigation.NavType
-import com.android.settingslib.spa.framework.BrowseActivity
-import com.android.settingslib.spa.framework.util.navLink
+import androidx.compose.runtime.remember
 
 const val INJECT_ENTRY_NAME = "INJECT"
 const val ROOT_ENTRY_NAME = "ROOT"
-const val ROOT_PAGE_NAME = "Root"
-
-/**
- * Defines data of one Settings entry for Settings search.
- */
-data class SearchData(val keyword: String = "")
-
-/**
- * Defines data of one Settings entry for UI rendering.
- */
-data class UiData(val title: String = "")
-
-/**
- * Defines data to identify a Settings page.
- */
-data class SettingsPage(
-    // The unique id of this page, which is computed by name + normalized(arguments)
-    val id: Int,
-
-    // The name of the page, which is used to compute the unique id, and need to be stable.
-    val name: String,
-
-    // The display name of the page, for better readability.
-    // By default, it is the same as name.
-    val displayName: String,
-
-    // Defined parameters of this page.
-    val parameter: List<NamedNavArgument> = emptyList(),
-
-    // The arguments of this page.
-    val arguments: Bundle? = null,
-) {
-    companion object {
-        fun create(
-            name: String,
-            parameter: List<NamedNavArgument> = emptyList(),
-            arguments: Bundle? = null
-        ): SettingsPage {
-            return SettingsPageBuilder(name, parameter).setArguments(arguments).build()
-        }
-    }
-
-    fun formatArguments(): String {
-        val normalizedArguments = parameter.normalize(arguments)
-        if (normalizedArguments == null || normalizedArguments.isEmpty) return "[No arguments]"
-        return normalizedArguments.toString().removeRange(0, 6)
-    }
-
-    fun formatAll(): String {
-        return "$displayName ${formatArguments()}"
-    }
-
-    fun buildRoute(highlightEntryName: String? = null): String {
-        val highlightParam =
-            if (highlightEntryName == null)
-                ""
-            else
-                "?${BrowseActivity.HIGHLIGHT_ENTRY_PARAM_NAME}=$highlightEntryName"
-        return name + parameter.navLink(arguments) + highlightParam
-    }
-
-    fun hasRuntimeParam(): Boolean {
-        return parameter.hasRuntimeParam(arguments)
-    }
-}
 
 /**
  * Defines data of a Settings entry.
  */
 data class SettingsEntry(
-    // The unique id of this entry, which is computed by name + owner + fromPage + toPage.
-    val id: Int,
-
     // The name of the page, which is used to compute the unique id, and need to be stable.
-    val name: String,
+    private val name: String,
+
+    // The display name of the page, for better readability.
+    val displayName: String,
 
     // The owner page of this entry.
     val owner: SettingsPage,
 
-    // The display name of the entry, for better readability.
-    // By default, it is $owner:$name
-    val displayName: String,
-
     // Defines linking of Settings entries
     val fromPage: SettingsPage? = null,
     val toPage: SettingsPage? = null,
@@ -117,7 +45,7 @@
      * Defines entry attributes here.
      * ========================================
      */
-    val isAllowSearch: Boolean,
+    val isAllowSearch: Boolean = false,
 
     /**
      * ========================================
@@ -129,13 +57,7 @@
      * API to get Search related data for this entry.
      * Returns null if this entry is not available for the search at the moment.
      */
-    val searchData: () -> SearchData? = { null },
-
-    /**
-     * API to get UI related data for this entry.
-     * Returns null if the entry is not render-able.
-     */
-    val uiData: () -> UiData? = { null },
+    private val searchDataImpl: (arguments: Bundle?) -> EntrySearchData? = { null },
 
     /**
      * API to Render UI of this entry directly. For now, we use it in the internal injection, to
@@ -143,65 +65,56 @@
      * injected entry. In the long term, we may deprecate the @Composable Page() API in SPP, and
      * use each entries' UI rendering function in the page instead.
      */
-    val uiLayoutImpl: (@Composable (arguments: Bundle?) -> Unit) = {},
+    private val uiLayoutImpl: (@Composable (arguments: Bundle?) -> Unit) = {},
 ) {
-    fun formatAll(): String {
-        val content = listOf<String>(
-            "owner = ${owner.formatAll()}",
-            "linkFrom = ${fromPage?.formatAll()}",
-            "linkTo = ${toPage?.formatAll()}",
+    // The unique id of this entry, which is computed by name + owner + fromPage + toPage.
+    fun id(): String {
+        return "$name:${owner.id()}(${fromPage?.id()}-${toPage?.id()})".toHashId()
+    }
+
+    fun formatContent(): String {
+        val content = listOf(
+            "id = ${id()}",
+            "owner = ${owner.formatDisplayTitle()}",
+            "linkFrom = ${fromPage?.formatDisplayTitle()}",
+            "linkTo = ${toPage?.formatDisplayTitle()}",
+            "${getSearchData()?.format()}",
         )
         return content.joinToString("\n")
     }
 
-    private fun getDisplayPage(): SettingsPage {
-        // Display the entry on its from-page, or on its owner page if the from-page is unset.
+    fun displayTitle(): String {
+        return "${owner.displayName}:$displayName"
+    }
+
+    private fun containerPage(): SettingsPage {
+        // The Container page of the entry, which is the from-page or
+        // the owner-page if from-page is unset.
         return fromPage ?: owner
     }
 
     fun buildRoute(): String {
-        return getDisplayPage().buildRoute(name)
+        return containerPage().buildRoute(id())
     }
 
     fun hasRuntimeParam(): Boolean {
-        return getDisplayPage().hasRuntimeParam()
+        return containerPage().hasRuntimeParam()
+    }
+
+    private fun fullArgument(runtimeArguments: Bundle? = null): Bundle {
+        val arguments = Bundle()
+        if (owner.arguments != null) arguments.putAll(owner.arguments)
+        if (runtimeArguments != null) arguments.putAll(runtimeArguments)
+        return arguments
+    }
+
+    fun getSearchData(runtimeArguments: Bundle? = null): EntrySearchData? {
+        return searchDataImpl(fullArgument(runtimeArguments))
     }
 
     @Composable
     fun UiLayout(runtimeArguments: Bundle? = null) {
-        val arguments = Bundle()
-        if (owner.arguments != null) arguments.putAll(owner.arguments)
-        if (runtimeArguments != null) arguments.putAll(runtimeArguments)
-        uiLayoutImpl(arguments)
-    }
-}
-
-data class SettingsPageWithEntry(
-    val page: SettingsPage,
-    val entries: List<SettingsEntry>,
-)
-
-class SettingsPageBuilder(
-    private val name: String,
-    private val parameter: List<NamedNavArgument> = emptyList()
-) {
-    private var displayName: String? = null
-    private var arguments: Bundle? = null
-
-    fun build(): SettingsPage {
-        val normArguments = parameter.normalize(arguments)
-        return SettingsPage(
-            id = "$name:${normArguments?.toString()}".toUniqueId(),
-            name = name,
-            displayName = displayName ?: name,
-            parameter = parameter,
-            arguments = arguments,
-        )
-    }
-
-    fun setArguments(arguments: Bundle?): SettingsPageBuilder {
-        this.arguments = arguments
-        return this
+        uiLayoutImpl(fullArgument(runtimeArguments))
     }
 }
 
@@ -209,34 +122,41 @@
  * The helper to build a Settings Entry instance.
  */
 class SettingsEntryBuilder(private val name: String, private val owner: SettingsPage) {
-    private var displayName: String? = null
+    private var displayName = name
     private var fromPage: SettingsPage? = null
     private var toPage: SettingsPage? = null
-    private var isAllowSearch: Boolean? = null
 
-    private var searchDataFn: () -> SearchData? = { null }
-    private var uiLayoutFn: (@Composable (arguments: Bundle?) -> Unit) = {}
+    // Attributes
+    private var isAllowSearch: Boolean = false
+
+    // Functions
+    private var searchDataFn: (arguments: Bundle?) -> EntrySearchData? = { null }
+    private var uiLayoutFn: (@Composable (arguments: Bundle?) -> Unit) = { }
 
     fun build(): SettingsEntry {
         return SettingsEntry(
-            id = "$name:${owner.id}(${fromPage?.id}-${toPage?.id})".toUniqueId(),
-            displayName = displayName ?: "${owner.displayName}:$name",
             name = name,
             owner = owner,
+            displayName = displayName,
 
             // linking data
             fromPage = fromPage,
             toPage = toPage,
 
             // attributes
-            isAllowSearch = getIsSearchable(),
+            isAllowSearch = isAllowSearch,
 
             // functions
-            searchData = searchDataFn,
+            searchDataImpl = searchDataFn,
             uiLayoutImpl = uiLayoutFn,
         )
     }
 
+    fun setDisplayName(displayName: String): SettingsEntryBuilder {
+        this.displayName = displayName
+        return this
+    }
+
     fun setLink(
         fromPage: SettingsPage? = null,
         toPage: SettingsPage? = null
@@ -251,7 +171,16 @@
         return this
     }
 
-    fun setSearchDataFn(fn: () -> SearchData?): SettingsEntryBuilder {
+    fun setMarco(fn: (arguments: Bundle?) -> EntryMarco): SettingsEntryBuilder {
+        setSearchDataFn { fn(it).getSearchData() }
+        setUiLayoutFn {
+            val marco = remember { fn(it) }
+            marco.UiLayout()
+        }
+        return this
+    }
+
+    fun setSearchDataFn(fn: (arguments: Bundle?) -> EntrySearchData?): SettingsEntryBuilder {
         this.searchDataFn = fn
         return this
     }
@@ -261,8 +190,6 @@
         return this
     }
 
-    private fun getIsSearchable(): Boolean = isAllowSearch ?: false
-
     companion object {
         fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
             return SettingsEntryBuilder(entryName, owner)
@@ -276,48 +203,19 @@
             return create(entryName, owner).setLink(toPage = owner)
         }
 
-        fun createInject(owner: SettingsPage, entryName: String? = null): SettingsEntryBuilder {
-            val name = entryName ?: "${INJECT_ENTRY_NAME}_${owner.name}"
-            return createLinkTo(name, owner)
+        fun create(owner: SettingsPage, entryName: String, displayName: String? = null):
+            SettingsEntryBuilder {
+            return SettingsEntryBuilder(entryName, owner).setDisplayName(displayName ?: entryName)
         }
 
-        fun createRoot(owner: SettingsPage, entryName: String? = null): SettingsEntryBuilder {
-            val name = entryName ?: "${ROOT_ENTRY_NAME}_${owner.name}"
-            return createLinkTo(name, owner)
+        fun createInject(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder {
+            val name = displayName ?: "${INJECT_ENTRY_NAME}_${owner.displayName}"
+            return createLinkTo(INJECT_ENTRY_NAME, owner).setDisplayName(name)
+        }
+
+        fun createRoot(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder {
+            val name = displayName ?: "${ROOT_ENTRY_NAME}_${owner.displayName}"
+            return createLinkTo(ROOT_ENTRY_NAME, owner).setDisplayName(name)
         }
     }
 }
-
-private fun String.toUniqueId(): Int {
-    return this.hashCode()
-}
-
-private fun List<NamedNavArgument>.normalize(arguments: Bundle? = null): Bundle? {
-    if (this.isEmpty()) return null
-    val normArgs = Bundle()
-    for (navArg in this) {
-        when (navArg.argument.type) {
-            NavType.StringType -> {
-                val value = arguments?.getString(navArg.name)
-                if (value != null)
-                    normArgs.putString(navArg.name, value)
-                else
-                    normArgs.putString("unset_" + navArg.name, null)
-            }
-            NavType.IntType -> {
-                if (arguments != null && arguments.containsKey(navArg.name))
-                    normArgs.putInt(navArg.name, arguments.getInt(navArg.name))
-                else
-                    normArgs.putString("unset_" + navArg.name, null)
-            }
-        }
-    }
-    return normArgs
-}
-
-private fun List<NamedNavArgument>.hasRuntimeParam(arguments: Bundle? = null): Boolean {
-    for (navArg in this) {
-        if (arguments == null || !arguments.containsKey(navArg.name)) return true
-    }
-    return false
-}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt
index a4e5a58..77f064d 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt
@@ -21,15 +21,20 @@
 
 private const val MAX_ENTRY_SIZE = 5000
 
+data class SettingsPageWithEntry(
+    val page: SettingsPage,
+    val entries: List<SettingsEntry>,
+)
+
 /**
  * The repository to maintain all Settings entries
  */
 class SettingsEntryRepository(sppRepository: SettingsPageProviderRepository) {
     // Map of entry unique Id to entry
-    private val entryMap: Map<Int, SettingsEntry>
+    private val entryMap: Map<String, SettingsEntry>
 
     // Map of Settings page to its contained entries.
-    private val pageWithEntryMap: Map<Int, SettingsPageWithEntry>
+    private val pageWithEntryMap: Map<String, SettingsPageWithEntry>
 
     init {
         logMsg("Initialize")
@@ -39,23 +44,29 @@
         val entryQueue = LinkedList<SettingsEntry>()
         for (page in sppRepository.getAllRootPages()) {
             val rootEntry = SettingsEntryBuilder.createRoot(owner = page).build()
-            if (!entryMap.containsKey(rootEntry.id)) {
+            val rootEntryId = rootEntry.id()
+            if (!entryMap.containsKey(rootEntryId)) {
                 entryQueue.push(rootEntry)
-                entryMap.put(rootEntry.id, rootEntry)
+                entryMap.put(rootEntryId, rootEntry)
             }
         }
 
         while (entryQueue.isNotEmpty() && entryMap.size < MAX_ENTRY_SIZE) {
             val entry = entryQueue.pop()
             val page = entry.toPage
-            if (page == null || pageWithEntryMap.containsKey(page.id)) continue
+            val pageId = page?.id()
+            if (pageId == null || pageWithEntryMap.containsKey(pageId)) continue
             val spp = sppRepository.getProviderOrNull(page.name) ?: continue
-            val newEntries = spp.buildEntry(page.arguments)
-            pageWithEntryMap[page.id] = SettingsPageWithEntry(page, newEntries)
+            val newEntries = spp.buildEntry(page.arguments).map {
+                // Set from-page if it is missing.
+                if (it.fromPage == null) it.copy(fromPage = page) else it
+            }
+            pageWithEntryMap[pageId] = SettingsPageWithEntry(page, newEntries)
             for (newEntry in newEntries) {
-                if (!entryMap.containsKey(newEntry.id)) {
+                val newEntryId = newEntry.id()
+                if (!entryMap.containsKey(newEntryId)) {
                     entryQueue.push(newEntry)
-                    entryMap.put(newEntry.id, newEntry)
+                    entryMap.put(newEntryId, newEntry)
                 }
             }
         }
@@ -67,7 +78,7 @@
         return pageWithEntryMap.values
     }
 
-    fun getPageWithEntry(pageId: Int): SettingsPageWithEntry? {
+    fun getPageWithEntry(pageId: String): SettingsPageWithEntry? {
         return pageWithEntryMap[pageId]
     }
 
@@ -75,7 +86,7 @@
         return entryMap.values
     }
 
-    fun getEntry(entryId: Int): SettingsEntry? {
+    fun getEntry(entryId: String): SettingsEntry? {
         return entryMap[entryId]
     }
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt
new file mode 100644
index 0000000..124743a
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.framework.common
+
+import android.os.Bundle
+import androidx.navigation.NamedNavArgument
+import androidx.navigation.NavType
+import com.android.settingslib.spa.framework.BrowseActivity
+import com.android.settingslib.spa.framework.util.navLink
+
+/**
+ * Defines data to identify a Settings page.
+ */
+data class SettingsPage(
+    // The name of the page, which is used to compute the unique id, and need to be stable.
+    val name: String,
+
+    // The display name of the page, for better readability.
+    val displayName: String,
+
+    // Defined parameters of this page.
+    val parameter: List<NamedNavArgument> = emptyList(),
+
+    // The arguments of this page.
+    val arguments: Bundle? = null,
+) {
+    companion object {
+        fun create(
+            name: String,
+            parameter: List<NamedNavArgument> = emptyList(),
+            arguments: Bundle? = null
+        ): SettingsPage {
+            return SettingsPage(name, name, parameter, arguments)
+        }
+    }
+
+    // The unique id of this page, which is computed by name + normalized(arguments)
+    fun id(): String {
+        val normArguments = parameter.normalize(arguments)
+        return "$name:${normArguments?.toString()}".toHashId()
+    }
+
+    // Returns if this Settings Page is created by the given Spp.
+    fun isCreateBy(SppName: String): Boolean {
+        return name == SppName
+    }
+
+    fun formatArguments(): String {
+        val normalizedArguments = parameter.normalize(arguments)
+        if (normalizedArguments == null || normalizedArguments.isEmpty) return "[No arguments]"
+        return normalizedArguments.toString().removeRange(0, 6)
+    }
+
+    fun formatDisplayTitle(): String {
+        return "$displayName ${formatArguments()}"
+    }
+
+    fun buildRoute(highlightEntryName: String? = null): String {
+        val highlightParam =
+            if (highlightEntryName == null)
+                ""
+            else
+                "?${BrowseActivity.HIGHLIGHT_ENTRY_PARAM_NAME}=$highlightEntryName"
+        return name + parameter.navLink(arguments) + highlightParam
+    }
+
+    fun hasRuntimeParam(): Boolean {
+        return parameter.hasRuntimeParam(arguments)
+    }
+}
+
+private fun List<NamedNavArgument>.normalize(arguments: Bundle? = null): Bundle? {
+    if (this.isEmpty()) return null
+    val normArgs = Bundle()
+    for (navArg in this) {
+        when (navArg.argument.type) {
+            NavType.StringType -> {
+                val value = arguments?.getString(navArg.name)
+                if (value != null)
+                    normArgs.putString(navArg.name, value)
+                else
+                    normArgs.putString("unset_" + navArg.name, null)
+            }
+            NavType.IntType -> {
+                if (arguments != null && arguments.containsKey(navArg.name))
+                    normArgs.putInt(navArg.name, arguments.getInt(navArg.name))
+                else
+                    normArgs.putString("unset_" + navArg.name, null)
+            }
+        }
+    }
+    return normArgs
+}
+
+private fun List<NamedNavArgument>.hasRuntimeParam(arguments: Bundle? = null): Boolean {
+    for (navArg in this) {
+        if (arguments == null || !arguments.containsKey(navArg.name)) return true
+    }
+    return false
+}
+
+fun String.toHashId(): String {
+    return this.hashCode().toString(36)
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepository.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepository.kt
index 6adda6b..77a157f 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepository.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepository.kt
@@ -30,12 +30,8 @@
         logMsg("Initialize Completed: ${pageProviderMap.size} spp")
     }
 
-    fun getDefaultStartPageName(): String {
-        return if (rootPages.isNotEmpty()) {
-            rootPages[0].name
-        } else {
-            ""
-        }
+    fun getDefaultStartPage(): String {
+        return if (rootPages.isEmpty()) "" else rootPages[0].buildRoute()
     }
 
     fun getAllRootPages(): Collection<SettingsPage> {
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
index 32ef0bb..13a2cc9 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
@@ -49,7 +49,8 @@
 }
 
 @Composable
-fun navigator(route: String): () -> Unit {
+fun navigator(route: String?): () -> Unit {
+    if (route == null) return {}
     val navController = LocalNavController.current
     return { navController.navigate(route) }
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/MaterialColors.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/MaterialColors.kt
index 4626f0b..3fa8c65 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/MaterialColors.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/MaterialColors.kt
@@ -16,11 +16,15 @@
 
 package com.android.settingslib.spa.framework.theme
 
+import android.os.Build
 import androidx.compose.material3.ColorScheme
+import androidx.compose.material3.darkColorScheme
 import androidx.compose.material3.dynamicDarkColorScheme
 import androidx.compose.material3.dynamicLightColorScheme
+import androidx.compose.material3.lightColorScheme
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.LocalContext
 
 @Composable
@@ -28,8 +32,15 @@
     val context = LocalContext.current
     return remember(isDarkTheme) {
         when {
-            isDarkTheme -> dynamicDarkColorScheme(context)
-            else -> dynamicLightColorScheme(context)
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
+                if (isDarkTheme) dynamicDarkColorScheme(context)
+                else dynamicLightColorScheme(context)
+            }
+            isDarkTheme -> darkColorScheme()
+            else -> lightColorScheme()
         }
     }
 }
+
+val ColorScheme.divider: Color
+    get() = onSurface.copy(SettingsOpacity.Divider)
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
index bc316f7..fa17e08 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
@@ -17,6 +17,7 @@
 package com.android.settingslib.spa.framework.theme
 
 import android.content.Context
+import android.os.Build
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.staticCompositionLocalOf
@@ -44,8 +45,12 @@
     val context = LocalContext.current
     return remember(isDarkTheme) {
         when {
-            isDarkTheme -> dynamicDarkColorScheme(context)
-            else -> dynamicLightColorScheme(context)
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
+                if (isDarkTheme) dynamicDarkColorScheme(context)
+                else dynamicLightColorScheme(context)
+            }
+            isDarkTheme -> darkColorScheme()
+            else -> lightColorScheme()
         }
     }
 }
@@ -101,3 +106,37 @@
         onSpinnerItemContainer = tonalPalette.neutralVariant30,
     )
 }
+
+private fun darkColorScheme(): SettingsColorScheme {
+    val tonalPalette = tonalPalette()
+    return SettingsColorScheme(
+        background = tonalPalette.neutral10,
+        categoryTitle = tonalPalette.primary90,
+        surface = tonalPalette.neutral20,
+        surfaceHeader = tonalPalette.neutral30,
+        secondaryText = tonalPalette.neutralVariant80,
+        primaryContainer = tonalPalette.secondary90,
+        onPrimaryContainer = tonalPalette.neutral10,
+        spinnerHeaderContainer = tonalPalette.primary90,
+        onSpinnerHeaderContainer = tonalPalette.neutral10,
+        spinnerItemContainer = tonalPalette.secondary90,
+        onSpinnerItemContainer = tonalPalette.neutralVariant30,
+    )
+}
+
+private fun lightColorScheme(): SettingsColorScheme {
+    val tonalPalette = tonalPalette()
+    return SettingsColorScheme(
+        background = tonalPalette.neutral95,
+        categoryTitle = tonalPalette.primary40,
+        surface = tonalPalette.neutral99,
+        surfaceHeader = tonalPalette.neutral90,
+        secondaryText = tonalPalette.neutralVariant30,
+        primaryContainer = tonalPalette.primary90,
+        onPrimaryContainer = tonalPalette.neutral10,
+        spinnerHeaderContainer = tonalPalette.primary90,
+        onSpinnerHeaderContainer = tonalPalette.neutral10,
+        spinnerItemContainer = tonalPalette.secondary90,
+        onSpinnerItemContainer = tonalPalette.neutralVariant30,
+    )
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTonalPalette.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTonalPalette.kt
index f81f5e7..c205aae 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTonalPalette.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTonalPalette.kt
@@ -118,6 +118,84 @@
     val tertiary0: Color,
 )
 
+/** Static colors in Material. */
+internal fun tonalPalette() = SettingsTonalPalette(
+    // The neutral static tonal range.
+    neutral100 = Color(red = 255, green = 255, blue = 255),
+    neutral99 = Color(red = 255, green = 251, blue = 254),
+    neutral95 = Color(red = 244, green = 239, blue = 244),
+    neutral90 = Color(red = 230, green = 225, blue = 229),
+    neutral80 = Color(red = 201, green = 197, blue = 202),
+    neutral70 = Color(red = 174, green = 170, blue = 174),
+    neutral60 = Color(red = 147, green = 144, blue = 148),
+    neutral50 = Color(red = 120, green = 117, blue = 121),
+    neutral40 = Color(red = 96, green = 93, blue = 98),
+    neutral30 = Color(red = 72, green = 70, blue = 73),
+    neutral20 = Color(red = 49, green = 48, blue = 51),
+    neutral10 = Color(red = 28, green = 27, blue = 31),
+    neutral0 = Color(red = 0, green = 0, blue = 0),
+
+    // The neutral variant static tonal range, sometimes called "neutral 2".
+    neutralVariant100 = Color(red = 255, green = 255, blue = 255),
+    neutralVariant99 = Color(red = 255, green = 251, blue = 254),
+    neutralVariant95 = Color(red = 245, green = 238, blue = 250),
+    neutralVariant90 = Color(red = 231, green = 224, blue = 236),
+    neutralVariant80 = Color(red = 202, green = 196, blue = 208),
+    neutralVariant70 = Color(red = 174, green = 169, blue = 180),
+    neutralVariant60 = Color(red = 147, green = 143, blue = 153),
+    neutralVariant50 = Color(red = 121, green = 116, blue = 126),
+    neutralVariant40 = Color(red = 96, green = 93, blue = 102),
+    neutralVariant30 = Color(red = 73, green = 69, blue = 79),
+    neutralVariant20 = Color(red = 50, green = 47, blue = 55),
+    neutralVariant10 = Color(red = 29, green = 26, blue = 34),
+    neutralVariant0 = Color(red = 0, green = 0, blue = 0),
+
+    // The primary static tonal range.
+    primary100 = Color(red = 255, green = 255, blue = 255),
+    primary99 = Color(red = 255, green = 251, blue = 254),
+    primary95 = Color(red = 246, green = 237, blue = 255),
+    primary90 = Color(red = 234, green = 221, blue = 255),
+    primary80 = Color(red = 208, green = 188, blue = 255),
+    primary70 = Color(red = 182, green = 157, blue = 248),
+    primary60 = Color(red = 154, green = 130, blue = 219),
+    primary50 = Color(red = 127, green = 103, blue = 190),
+    primary40 = Color(red = 103, green = 80, blue = 164),
+    primary30 = Color(red = 79, green = 55, blue = 139),
+    primary20 = Color(red = 56, green = 30, blue = 114),
+    primary10 = Color(red = 33, green = 0, blue = 93),
+    primary0 = Color(red = 33, green = 0, blue = 93),
+
+    // The secondary static tonal range.
+    secondary100 = Color(red = 255, green = 255, blue = 255),
+    secondary99 = Color(red = 255, green = 251, blue = 254),
+    secondary95 = Color(red = 246, green = 237, blue = 255),
+    secondary90 = Color(red = 232, green = 222, blue = 248),
+    secondary80 = Color(red = 204, green = 194, blue = 220),
+    secondary70 = Color(red = 176, green = 167, blue = 192),
+    secondary60 = Color(red = 149, green = 141, blue = 165),
+    secondary50 = Color(red = 122, green = 114, blue = 137),
+    secondary40 = Color(red = 98, green = 91, blue = 113),
+    secondary30 = Color(red = 74, green = 68, blue = 88),
+    secondary20 = Color(red = 51, green = 45, blue = 65),
+    secondary10 = Color(red = 29, green = 25, blue = 43),
+    secondary0 = Color(red = 0, green = 0, blue = 0),
+
+    // The tertiary static tonal range.
+    tertiary100 = Color(red = 255, green = 255, blue = 255),
+    tertiary99 = Color(red = 255, green = 251, blue = 250),
+    tertiary95 = Color(red = 255, green = 236, blue = 241),
+    tertiary90 = Color(red = 255, green = 216, blue = 228),
+    tertiary80 = Color(red = 239, green = 184, blue = 200),
+    tertiary70 = Color(red = 210, green = 157, blue = 172),
+    tertiary60 = Color(red = 181, green = 131, blue = 146),
+    tertiary50 = Color(red = 152, green = 105, blue = 119),
+    tertiary40 = Color(red = 125, green = 82, blue = 96),
+    tertiary30 = Color(red = 99, green = 59, blue = 72),
+    tertiary20 = Color(red = 73, green = 37, blue = 50),
+    tertiary10 = Color(red = 49, green = 17, blue = 29),
+    tertiary0 = Color(red = 0, green = 0, blue = 0),
+)
+
 /** Dynamic colors in Material. */
 internal fun dynamicTonalPalette(context: Context) = SettingsTonalPalette(
     // The neutral tonal range from the generated dynamic color palette.
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Parameter.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Parameter.kt
index aaf8107..d7d7750 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Parameter.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Parameter.kt
@@ -25,9 +25,12 @@
 }
 
 fun List<NamedNavArgument>.navLink(arguments: Bundle? = null): String {
-    if (arguments == null) return ""
     val argsArray = mutableListOf<String>()
     for (navArg in this) {
+        if (arguments == null || !arguments.containsKey(navArg.name)) {
+            argsArray.add("[rt]")
+            continue
+        }
         when (navArg.argument.type) {
             NavType.StringType -> {
                 argsArray.add(arguments.getString(navArg.name, ""))
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt
new file mode 100644
index 0000000..3555ec7
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.widget.button
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.IntrinsicSize
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Delete
+import androidx.compose.material.icons.outlined.Launch
+import androidx.compose.material.icons.outlined.WarningAmber
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.FilledTonalButton
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.android.settingslib.spa.framework.theme.SettingsDimension
+import com.android.settingslib.spa.framework.theme.SettingsShape
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.framework.theme.divider
+
+data class ActionButton(
+    val text: String,
+    val imageVector: ImageVector,
+    val onClick: () -> Unit,
+)
+
+@Composable
+fun ActionButtons(actionButtons: List<ActionButton>) {
+    Row(
+        Modifier
+            .padding(SettingsDimension.itemPaddingVertical)
+            .clip(SettingsShape.CornerLarge)
+            .height(IntrinsicSize.Min)
+    ) {
+        for ((index, actionButton) in actionButtons.withIndex()) {
+            if (index > 0) ButtonDivider()
+            ActionButton(actionButton)
+        }
+    }
+}
+
+@Composable
+private fun RowScope.ActionButton(actionButton: ActionButton) {
+    FilledTonalButton(
+        onClick = actionButton.onClick,
+        modifier = Modifier
+            .weight(1f)
+            .fillMaxHeight(),
+        shape = RectangleShape,
+        colors = ButtonDefaults.filledTonalButtonColors(
+            containerColor = MaterialTheme.colorScheme.surface,
+            contentColor = SettingsTheme.colorScheme.categoryTitle,
+        ),
+        contentPadding = PaddingValues(horizontal = 4.dp, vertical = 20.dp),
+    ) {
+        Column(
+            horizontalAlignment = Alignment.CenterHorizontally,
+        ) {
+            Icon(
+                imageVector = actionButton.imageVector,
+                contentDescription = null,
+                modifier = Modifier.size(SettingsDimension.itemIconSize),
+            )
+            Spacer(Modifier.height(4.dp))
+            Text(
+                text = actionButton.text,
+                style = MaterialTheme.typography.labelLarge,
+            )
+        }
+    }
+}
+
+@Composable
+private fun ButtonDivider() {
+    Box(
+        Modifier
+            .width(1.dp)
+            .background(color = MaterialTheme.colorScheme.divider)
+    )
+}
+
+@Preview
+@Composable
+private fun ActionButtonsPreview() {
+    SettingsTheme {
+        ActionButtons(
+            listOf(
+                ActionButton(text = "Open", imageVector = Icons.Outlined.Launch) {},
+                ActionButton(text = "Uninstall", imageVector = Icons.Outlined.Delete) {},
+                ActionButton(text = "Force stop", imageVector = Icons.Outlined.WarningAmber) {},
+            )
+        )
+    }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt
index 0e6f53a..39b8d57 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt
@@ -21,7 +21,39 @@
 import androidx.compose.runtime.State
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import com.android.settingslib.spa.framework.common.EntryMarco
+import com.android.settingslib.spa.framework.common.EntrySearchData
+import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.compose.stateOf
+import com.android.settingslib.spa.widget.ui.createSettingsIcon
+
+data class SimplePreferenceMarco(
+    val title: String,
+    val summary: String? = null,
+    val icon: ImageVector? = null,
+    val disabled: Boolean = false,
+    val clickRoute: String? = null,
+    val searchKeywords: List<String> = emptyList(),
+) : EntryMarco {
+    @Composable
+    override fun UiLayout() {
+        Preference(model = object : PreferenceModel {
+            override val title: String = this@SimplePreferenceMarco.title
+            override val summary = stateOf(this@SimplePreferenceMarco.summary ?: "")
+            override val icon = createSettingsIcon(this@SimplePreferenceMarco.icon)
+            override val enabled = stateOf(!this@SimplePreferenceMarco.disabled)
+            override val onClick = navigator(clickRoute)
+        })
+    }
+
+    override fun getSearchData(): EntrySearchData {
+        return EntrySearchData(
+            title = this@SimplePreferenceMarco.title,
+            keyword = searchKeywords
+        )
+    }
+}
 
 /**
  * The widget model for [Preference] widget.
@@ -71,9 +103,9 @@
 @Composable
 fun Preference(model: PreferenceModel) {
     val modifier = remember(model.enabled.value, model.onClick) {
-      model.onClick?.let { onClick ->
-        Modifier.clickable(enabled = model.enabled.value, onClick = onClick)
-      } ?: Modifier
+        model.onClick?.let { onClick ->
+            Modifier.clickable(enabled = model.enabled.value, onClick = onClick)
+        } ?: Modifier
     }
     BasePreference(
         title = model.title,
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt
index 77ea3c5..5663610 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt
@@ -30,7 +30,7 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import com.android.settingslib.spa.framework.theme.SettingsDimension
-import com.android.settingslib.spa.framework.theme.SettingsOpacity
+import com.android.settingslib.spa.framework.theme.divider
 
 @Composable
 internal fun TwoTargetPreference(
@@ -67,6 +67,6 @@
         Modifier
             .padding(horizontal = SettingsDimension.itemPaddingEnd)
             .size(width = 1.dp, height = SettingsDimension.itemDividerHeight)
-            .background(color = MaterialTheme.colorScheme.onSurface.copy(SettingsOpacity.Divider))
+            .background(color = MaterialTheme.colorScheme.divider)
     )
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
new file mode 100644
index 0000000..6aac5bf3
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.widget.ui
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.android.settingslib.spa.framework.theme.SettingsDimension
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+
+/**
+ * A category title that is placed before a group of similar items.
+ */
+@Composable
+fun CategoryTitle(title: String) {
+    Text(
+        text = title,
+        modifier = Modifier.padding(
+            start = SettingsDimension.itemPaddingStart,
+            top = 20.dp,
+            end = SettingsDimension.itemPaddingEnd,
+            bottom = 8.dp,
+        ),
+        color = SettingsTheme.colorScheme.categoryTitle,
+        style = MaterialTheme.typography.labelMedium,
+    )
+}
+
+/**
+ * A container that is used to group similar items. A [Category] displays a [CategoryTitle] and
+ * visually separates groups of items.
+ */
+@Composable
+fun Category(title: String, content: @Composable ColumnScope.() -> Unit) {
+    Column {
+        var displayTitle by remember { mutableStateOf(false) }
+        if (displayTitle) CategoryTitle(title = title)
+        Column(
+            modifier = Modifier.onGloballyPositioned { coordinates ->
+                displayTitle = coordinates.size.height > 0
+            },
+            content = content,
+        )
+    }
+}
+
+@Preview
+@Composable
+private fun CategoryPreview() {
+    SettingsTheme {
+        CategoryTitle("Appearance")
+    }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Icon.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Icon.kt
index 4f28e37..25a4e70 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Icon.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Icon.kt
@@ -33,3 +33,8 @@
         tint = MaterialTheme.colorScheme.onSurface,
     )
 }
+
+fun createSettingsIcon(imageVector: ImageVector?): (@Composable () -> Unit)? {
+    if (imageVector == null) return null
+    return { SettingsIcon(imageVector = imageVector) }
+}
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/button/ActionButtonsTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/button/ActionButtonsTest.kt
new file mode 100644
index 0000000..8101a94
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/button/ActionButtonsTest.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.widget.button
+
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Launch
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performClick
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class ActionButtonsTest {
+    @get:Rule
+    val composeTestRule = createComposeRule()
+
+    @Test
+    fun button_displayed() {
+        composeTestRule.setContent {
+            ActionButtons(
+                listOf(
+                    ActionButton(text = "Open", imageVector = Icons.Outlined.Launch) {},
+                )
+            )
+        }
+
+        composeTestRule.onNodeWithText("Open").assertIsDisplayed()
+    }
+
+    @Test
+    fun button_clickable() {
+        var clicked by mutableStateOf(false)
+        composeTestRule.setContent {
+            ActionButtons(
+                listOf(
+                    ActionButton(text = "Open", imageVector = Icons.Outlined.Launch) {
+                        clicked = true
+                    },
+                )
+            )
+        }
+
+        composeTestRule.onNodeWithText("Open").performClick()
+
+        assertThat(clicked).isTrue()
+    }
+}
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/CategoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/CategoryTest.kt
new file mode 100644
index 0000000..16e09ee
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/CategoryTest.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.widget.ui
+
+import androidx.compose.runtime.remember
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.framework.compose.stateOf
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class CategoryTest {
+
+    @get:Rule
+    val composeTestRule = createComposeRule()
+
+    @Test
+    fun categoryTitle() {
+        composeTestRule.setContent {
+            CategoryTitle(title = "CategoryTitle")
+        }
+
+        composeTestRule.onNodeWithText("CategoryTitle").assertIsDisplayed()
+    }
+
+    @Test
+    fun category_hasContent_titleDisplayed() {
+        composeTestRule.setContent {
+            Category(title = "CategoryTitle") {
+                Preference(remember {
+                    object : PreferenceModel {
+                        override val title = "Some Preference"
+                        override val summary = stateOf("Some summary")
+                    }
+                })
+            }
+        }
+
+        composeTestRule.onNodeWithText("CategoryTitle").assertIsDisplayed()
+    }
+
+    @Test
+    fun category_noContent_titleNotDisplayed() {
+        composeTestRule.setContent {
+            Category(title = "CategoryTitle") {}
+        }
+
+        composeTestRule.onNodeWithText("CategoryTitle").assertDoesNotExist()
+    }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/res/values/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values/strings.xml
index b2302a5..25dbe00 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values/strings.xml
@@ -14,7 +14,7 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- [CHAR LIMIT=25] Text shown when there are no applications to display. -->
     <string name="no_applications">No apps.</string>
     <!-- [CHAR LIMIT=NONE] Menu for manage apps to control whether system processes are shown -->
@@ -25,4 +25,6 @@
     <string name="app_permission_summary_allowed">Allowed</string>
     <!-- Preference summary text for an app when it is disallowed for a permission. [CHAR LIMIT=45] -->
     <string name="app_permission_summary_not_allowed">Not allowed</string>
+    <!-- Manage applications, version string displayed in app snippet -->
+    <string name="version_text">version <xliff:g id="version_num">%1$s</xliff:g></string>
 </resources>
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/Apps.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/Apps.kt
index 6e1afd9..99a08ab 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/Apps.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/Apps.kt
@@ -22,4 +22,7 @@
 val ApplicationInfo.userId: Int
     get() = UserHandle.getUserId(uid)
 
+val ApplicationInfo.userHandle: UserHandle
+    get() = UserHandle.getUserHandleForUid(uid)
+
 fun ApplicationInfo.toRoute() = "$packageName/$userId"
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
new file mode 100644
index 0000000..0615807
--- /dev/null
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spaprivileged.model.enterprise
+
+import android.app.admin.DevicePolicyResources.Strings.Settings
+import android.content.Context
+import android.os.UserHandle
+import android.os.UserManager
+import androidx.lifecycle.LiveData
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
+import com.android.settingslib.RestrictedLockUtilsInternal
+import com.android.settingslib.spaprivileged.R
+
+data class Restrictions(
+    val userId: Int,
+    val keys: List<String>,
+)
+
+sealed class RestrictedMode
+
+object NoRestricted : RestrictedMode()
+
+object BaseUserRestricted : RestrictedMode()
+
+data class BlockedByAdmin(
+    val enterpriseRepository: EnterpriseRepository,
+    val enforcedAdmin: EnforcedAdmin,
+) : RestrictedMode() {
+    fun getSummary(checked: Boolean?): String = when (checked) {
+        true -> enterpriseRepository.getEnterpriseString(
+            Settings.ENABLED_BY_ADMIN_SWITCH_SUMMARY, R.string.enabled_by_admin
+        )
+        false -> enterpriseRepository.getEnterpriseString(
+            Settings.DISABLED_BY_ADMIN_SWITCH_SUMMARY, R.string.disabled_by_admin
+        )
+        else -> ""
+    }
+}
+
+class RestrictionsProvider(
+    private val context: Context,
+    private val restrictions: Restrictions,
+) {
+    private val userManager by lazy { UserManager.get(context) }
+    private val enterpriseRepository by lazy { EnterpriseRepository(context) }
+
+    val restrictedMode = object : LiveData<RestrictedMode>() {
+        override fun onActive() {
+            postValue(getRestrictedMode())
+        }
+
+        override fun onInactive() {
+        }
+    }
+
+    private fun getRestrictedMode(): RestrictedMode {
+        for (key in restrictions.keys) {
+            if (userManager.hasBaseUserRestriction(key, UserHandle.of(restrictions.userId))) {
+                return BaseUserRestricted
+            }
+        }
+        for (key in restrictions.keys) {
+            RestrictedLockUtilsInternal
+                .checkIfRestrictionEnforced(context, key, restrictions.userId)
+                ?.let {
+                    return BlockedByAdmin(
+                        enterpriseRepository = enterpriseRepository,
+                        enforcedAdmin = it,
+                    )
+                }
+        }
+        return NoRestricted
+    }
+}
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 f51d2db..c89ffe5 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
@@ -17,6 +17,8 @@
 package com.android.settingslib.spaprivileged.template.app
 
 import android.content.pm.ApplicationInfo
+import android.content.pm.PackageInfo
+import android.text.BidiFormatter
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -25,49 +27,60 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Divider
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import com.android.settingslib.spa.framework.compose.rememberDrawablePainter
 import com.android.settingslib.spa.framework.theme.SettingsDimension
 import com.android.settingslib.spa.widget.ui.SettingsBody
 import com.android.settingslib.spa.widget.ui.SettingsTitle
-import com.android.settingslib.spaprivileged.model.app.PackageManagers
+import com.android.settingslib.spaprivileged.R
 import com.android.settingslib.spaprivileged.model.app.rememberAppRepository
 
-@Composable
-fun AppInfo(packageName: String, userId: Int) {
-    Column(
-        modifier = Modifier
-            .fillMaxWidth()
-            .padding(
-                horizontal = SettingsDimension.itemPaddingStart,
-                vertical = SettingsDimension.itemPaddingVertical,
-            ),
-        horizontalAlignment = Alignment.CenterHorizontally,
-    ) {
-        val packageInfo =
-            remember { PackageManagers.getPackageInfoAsUser(packageName, userId) } ?: return
-        Box(modifier = Modifier.padding(SettingsDimension.itemPaddingAround)) {
-            AppIcon(app = packageInfo.applicationInfo, size = SettingsDimension.appIconInfoSize)
+class AppInfoProvider(private val packageInfo: PackageInfo) {
+    @Composable
+    fun AppInfo(displayVersion: Boolean = false) {
+        Column(
+            modifier = Modifier
+                .fillMaxWidth()
+                .padding(
+                    horizontal = SettingsDimension.itemPaddingStart,
+                    vertical = SettingsDimension.itemPaddingVertical,
+                ),
+            horizontalAlignment = Alignment.CenterHorizontally,
+        ) {
+            Box(modifier = Modifier.padding(SettingsDimension.itemPaddingAround)) {
+                AppIcon(app = packageInfo.applicationInfo, size = SettingsDimension.appIconInfoSize)
+            }
+            AppLabel(packageInfo.applicationInfo)
+            if (displayVersion) AppVersion()
         }
-        AppLabel(packageInfo.applicationInfo)
-        AppVersion(packageInfo.versionName)
+    }
+
+    @Composable
+    private fun AppVersion() {
+        if (packageInfo.versionName == null) return
+        Spacer(modifier = Modifier.height(4.dp))
+        SettingsBody(packageInfo.versionName)
+    }
+
+    @Composable
+    fun FooterAppVersion() {
+        if (packageInfo.versionName == null) return
+        Divider()
+        Box(modifier = Modifier.padding(SettingsDimension.itemPadding)) {
+            val versionName = BidiFormatter.getInstance().unicodeWrap(packageInfo.versionName)
+            SettingsBody(stringResource(R.string.version_text, versionName))
+        }
     }
 }
 
 @Composable
-private fun AppVersion(versionName: String?) {
-    if (versionName == null) return
-    Spacer(modifier = Modifier.height(4.dp))
-    SettingsBody(versionName)
-}
-
-@Composable
-fun AppIcon(app: ApplicationInfo, size: Dp) {
+internal fun AppIcon(app: ApplicationInfo, size: Dp) {
     val appRepository = rememberAppRepository()
     Image(
         painter = rememberDrawablePainter(appRepository.produceIcon(app).value),
@@ -77,7 +90,7 @@
 }
 
 @Composable
-fun AppLabel(app: ApplicationInfo) {
+internal fun AppLabel(app: ApplicationInfo) {
     val appRepository = rememberAppRepository()
     SettingsTitle(appRepository.produceLabel(app))
 }
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfoPage.kt
index 9b45318..4f88398 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfoPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfoPage.kt
@@ -17,8 +17,10 @@
 package com.android.settingslib.spaprivileged.template.app
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import com.android.settingslib.spa.widget.scaffold.RegularScaffold
 import com.android.settingslib.spa.widget.ui.Footer
+import com.android.settingslib.spaprivileged.model.app.PackageManagers
 
 @Composable
 fun AppInfoPage(
@@ -29,7 +31,12 @@
     content: @Composable () -> Unit,
 ) {
     RegularScaffold(title = title) {
-        AppInfo(packageName, userId)
+        val appInfoProvider = remember {
+            val packageInfo = PackageManagers.getPackageInfoAsUser(packageName, userId)
+                ?: return@RegularScaffold
+            AppInfoProvider(packageInfo)
+        }
+        appInfoProvider.AppInfo(displayVersion = true)
 
         content()
 
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
index c031fe8..80b2364 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
@@ -34,11 +34,14 @@
 import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.compose.navigator
-import com.android.settingslib.spa.widget.preference.SwitchPreference
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
 import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
 import com.android.settingslib.spaprivileged.model.app.AppRecord
 import com.android.settingslib.spaprivileged.model.app.PackageManagers
 import com.android.settingslib.spaprivileged.model.app.toRoute
+import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
+import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreference
 import kotlinx.coroutines.Dispatchers
 
 private const val ENTRY_NAME = "AllowControl"
@@ -79,10 +82,31 @@
 
     companion object {
         @Composable
-        internal fun navigator(permissionType: String, app: ApplicationInfo) =
+        fun navigator(permissionType: String, app: ApplicationInfo) =
             navigator(route = "$PAGE_NAME/$permissionType/${app.toRoute()}")
 
-        internal fun buildPageData(permissionType: String): SettingsPage {
+        @Composable
+        fun <T : AppRecord> EntryItem(
+            permissionType: String,
+            app: ApplicationInfo,
+            listModel: TogglePermissionAppListModel<T>,
+        ) {
+            val context = LocalContext.current
+            val internalListModel = remember {
+                TogglePermissionInternalAppListModel(context, listModel)
+            }
+            val record = remember { listModel.transformItem(app) }
+            if (!remember { listModel.isChangeable(record) }) return
+            Preference(
+                object : PreferenceModel {
+                    override val title = stringResource(listModel.pageTitleResId)
+                    override val summary = internalListModel.getSummary(record)
+                    override val onClick = navigator(permissionType, app)
+                }
+            )
+        }
+
+        fun buildPageData(permissionType: String): SettingsPage {
             return SettingsPage.create(
                 PAGE_NAME, PAGE_PARAMETER, bundleOf(PERMISSION to permissionType))
         }
@@ -105,7 +129,7 @@
         LaunchedEffect(model, Dispatchers.Default) {
             model.initState()
         }
-        SwitchPreference(model)
+        RestrictedSwitchPreference(model, Restrictions(userId, listModel.switchRestrictionKeys))
     }
 }
 
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
index 4c748b8..5d49d24 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
@@ -20,13 +20,10 @@
 import android.content.pm.ApplicationInfo
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.State
-import androidx.compose.ui.res.stringResource
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.compose.rememberContext
 import com.android.settingslib.spa.framework.util.asyncMapItem
-import com.android.settingslib.spa.widget.preference.Preference
-import com.android.settingslib.spa.widget.preference.PreferenceModel
 import com.android.settingslib.spaprivileged.model.app.AppRecord
 import kotlinx.coroutines.flow.Flow
 
@@ -37,6 +34,8 @@
     val pageTitleResId: Int
     val switchTitleResId: Int
     val footerResId: Int
+    val switchRestrictionKeys: List<String>
+        get() = emptyList()
 
     /**
      * Loads the extra info for the App List, and generates the [AppRecord] List.
@@ -83,28 +82,22 @@
 
     fun createModel(context: Context): TogglePermissionAppListModel<out AppRecord>
 
-    fun buildInjectEntry(): SettingsEntryBuilder {
-        return TogglePermissionAppListPageProvider.buildInjectEntry(permissionType)
-    }
-
-    @Composable
-    fun EntryItem() {
-        val listModel = rememberContext(::createModel)
-        Preference(
-            object : PreferenceModel {
-                override val title = stringResource(listModel.pageTitleResId)
-                override val onClick = TogglePermissionAppListPageProvider.navigator(permissionType)
-            }
-        )
-    }
+    fun buildAppListInjectEntry(): SettingsEntryBuilder =
+        TogglePermissionAppListPageProvider.buildInjectEntry(permissionType) { createModel(it) }
 
     /**
      * Gets the route to the toggle permission App List page.
      *
      * Expose route to enable enter from non-SPA pages.
      */
-    fun getRoute(): String =
+    fun getAppListRoute(): String =
         TogglePermissionAppListPageProvider.getRoute(permissionType)
+
+    @Composable
+    fun InfoPageEntryItem(app: ApplicationInfo) {
+        val listModel = rememberContext(::createModel)
+        TogglePermissionAppInfoPageProvider.EntryItem(permissionType, app, listModel)
+    }
 }
 
 class TogglePermissionAppListTemplate(
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
index 65cc4f9..bd60bd36 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
@@ -22,6 +22,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.State
 import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.livedata.observeAsState
 import androidx.compose.runtime.remember
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
@@ -33,10 +34,17 @@
 import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.framework.compose.rememberContext
 import com.android.settingslib.spa.framework.util.getStringArg
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
 import com.android.settingslib.spaprivileged.R
 import com.android.settingslib.spaprivileged.model.app.AppListModel
 import com.android.settingslib.spaprivileged.model.app.AppRecord
+import com.android.settingslib.spaprivileged.model.app.userId
+import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
+import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider
+import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreference
 import kotlinx.coroutines.flow.Flow
 
 private const val ENTRY_NAME = "AppList"
@@ -102,20 +110,29 @@
          *
          * Expose route to enable enter from non-SPA pages.
          */
-        internal fun getRoute(permissionType: String) = "$PAGE_NAME/$permissionType"
+        fun getRoute(permissionType: String) = "$PAGE_NAME/$permissionType"
 
-        @Composable
-        internal fun navigator(permissionType: String) = navigator(route = getRoute(permissionType))
-
-        internal fun buildInjectEntry(permissionType: String): SettingsEntryBuilder {
+        fun buildInjectEntry(
+            permissionType: String,
+            listModelSupplier: (Context) -> TogglePermissionAppListModel<out AppRecord>,
+        ): SettingsEntryBuilder {
             val appListPage = SettingsPage.create(
                 PAGE_NAME, PAGE_PARAMETER, bundleOf(PERMISSION to permissionType))
             return SettingsEntryBuilder.createInject(owner = appListPage).setIsAllowSearch(false)
+                .setUiLayoutFn {
+                    val listModel = rememberContext(listModelSupplier)
+                    Preference(
+                        object : PreferenceModel {
+                            override val title = stringResource(listModel.pageTitleResId)
+                            override val onClick = navigator(route = getRoute(permissionType))
+                        }
+                    )
+                }
         }
     }
 }
 
-private class TogglePermissionInternalAppListModel<T : AppRecord>(
+internal class TogglePermissionInternalAppListModel<T : AppRecord>(
     private val context: Context,
     private val listModel: TogglePermissionAppListModel<T>,
 ) : AppListModel<T> {
@@ -127,15 +144,37 @@
 
     @Composable
     override fun getSummary(option: Int, record: T): State<String> {
+        return getSummary(record)
+    }
+
+    @Composable
+    fun getSummary(record: T): State<String> {
+        val restrictionsProvider = remember {
+            val restrictions = Restrictions(
+                userId = record.app.userId,
+                keys = listModel.switchRestrictionKeys,
+            )
+            RestrictionsProvider(context, restrictions)
+        }
+        val restrictedMode = restrictionsProvider.restrictedMode.observeAsState()
         val allowed = listModel.isAllowed(record)
         return remember {
             derivedStateOf {
-                when (allowed.value) {
-                    true -> context.getString(R.string.app_permission_summary_allowed)
-                    false -> context.getString(R.string.app_permission_summary_not_allowed)
-                    else -> ""
-                }
+                RestrictedSwitchPreference.getSummary(
+                    context = context,
+                    restrictedMode = restrictedMode.value,
+                    noRestrictedSummary = getNoRestrictedSummary(allowed),
+                    checked = allowed,
+                ).value
             }
         }
     }
+
+    private fun getNoRestrictedSummary(allowed: State<Boolean?>) = derivedStateOf {
+        when (allowed.value) {
+            true -> context.getString(R.string.app_permission_summary_allowed)
+            false -> context.getString(R.string.app_permission_summary_not_allowed)
+            else -> context.getString(R.string.summary_placeholder)
+        }
+    }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt
new file mode 100644
index 0000000..31fd3ad
--- /dev/null
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spaprivileged.template.preference
+
+import android.content.Context
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.semantics.Role
+import com.android.settingslib.RestrictedLockUtils
+import com.android.settingslib.spa.framework.compose.stateOf
+import com.android.settingslib.spa.widget.preference.SwitchPreference
+import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
+import com.android.settingslib.spaprivileged.R
+import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted
+import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin
+import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted
+import com.android.settingslib.spaprivileged.model.enterprise.RestrictedMode
+import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
+import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider
+
+@Composable
+fun RestrictedSwitchPreference(model: SwitchPreferenceModel, restrictions: Restrictions) {
+    if (restrictions.keys.isEmpty()) {
+        SwitchPreference(model)
+        return
+    }
+    val context = LocalContext.current
+    val restrictionsProvider = remember { RestrictionsProvider(context, restrictions) }
+    val restrictedMode = restrictionsProvider.restrictedMode.observeAsState().value ?: return
+    val restrictedSwitchModel = remember(restrictedMode) {
+        RestrictedSwitchPreferenceModel(context, model, restrictedMode)
+    }
+    Box(remember { restrictedSwitchModel.getModifier() }) {
+        SwitchPreference(restrictedSwitchModel)
+    }
+}
+
+object RestrictedSwitchPreference {
+    fun getSummary(
+        context: Context,
+        restrictedMode: RestrictedMode?,
+        noRestrictedSummary: State<String>,
+        checked: State<Boolean?>,
+    ): State<String> = when (restrictedMode) {
+        is NoRestricted -> noRestrictedSummary
+        is BaseUserRestricted -> stateOf(context.getString(R.string.disabled))
+        is BlockedByAdmin -> derivedStateOf { restrictedMode.getSummary(checked.value) }
+        null -> stateOf(context.getString(R.string.summary_placeholder))
+    }
+}
+
+private class RestrictedSwitchPreferenceModel(
+    private val context: Context,
+    model: SwitchPreferenceModel,
+    private val restrictedMode: RestrictedMode,
+) : SwitchPreferenceModel {
+    override val title = model.title
+
+    override val summary = RestrictedSwitchPreference.getSummary(
+        context = context,
+        restrictedMode = restrictedMode,
+        noRestrictedSummary = model.summary,
+        checked = model.checked,
+    )
+
+    override val checked = when (restrictedMode) {
+        is NoRestricted -> model.checked
+        is BaseUserRestricted -> stateOf(false)
+        is BlockedByAdmin -> model.checked
+    }
+
+    override val changeable = when (restrictedMode) {
+        is NoRestricted -> model.changeable
+        is BaseUserRestricted -> stateOf(false)
+        is BlockedByAdmin -> stateOf(false)
+    }
+
+    override val onCheckedChange = when (restrictedMode) {
+        is NoRestricted -> model.onCheckedChange
+        is BaseUserRestricted -> null
+        is BlockedByAdmin -> null
+    }
+
+    fun getModifier(): Modifier = when (restrictedMode) {
+        is BlockedByAdmin -> Modifier.clickable(role = Role.Switch) {
+            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
+                context, restrictedMode.enforcedAdmin
+            )
+        }
+        else -> Modifier
+    }
+}
diff --git a/packages/SettingsLib/res/color/dark_mode_icon_color_dual_tone_background.xml b/packages/SettingsLib/res/color/dark_mode_icon_color_dual_tone_background.xml
deleted file mode 100644
index c8a80ac..0000000
--- a/packages/SettingsLib/res/color/dark_mode_icon_color_dual_tone_background.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:alpha="0.24" android:color="?android:attr/colorBackground" />
-</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/color/dark_mode_icon_color_dual_tone_fill.xml b/packages/SettingsLib/res/color/dark_mode_icon_color_dual_tone_fill.xml
deleted file mode 100644
index 8dcfdbb..0000000
--- a/packages/SettingsLib/res/color/dark_mode_icon_color_dual_tone_fill.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:alpha="0.47" android:color="?android:attr/colorBackground" />
-</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/color/light_mode_icon_color_dual_tone_background.xml b/packages/SettingsLib/res/color/light_mode_icon_color_dual_tone_background.xml
deleted file mode 100644
index 34de548..0000000
--- a/packages/SettingsLib/res/color/light_mode_icon_color_dual_tone_background.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:alpha="0.3" android:color="?android:attr/colorForeground" />
-</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/color/light_mode_icon_color_dual_tone_fill.xml b/packages/SettingsLib/res/color/light_mode_icon_color_dual_tone_fill.xml
deleted file mode 100644
index 15944c3..0000000
--- a/packages/SettingsLib/res/color/light_mode_icon_color_dual_tone_fill.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="?android:attr/colorForeground" />
-</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/drawable/ic_5g_uc_mobiledata.xml b/packages/SettingsLib/res/drawable/ic_5g_uc_mobiledata.xml
deleted file mode 100644
index 93fcad2..0000000
--- a/packages/SettingsLib/res/drawable/ic_5g_uc_mobiledata.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-     Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="27dp"
-        android:height="16dp"
-        android:viewportWidth="27.0"
-        android:viewportHeight="16.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M5.3,13.22c-0.57,0 -1.1,-0.11 -1.58,-0.34c-0.48,-0.22 -0.87,-0.55 -1.18,-0.98C2.24,11.47 2.06,10.93 2,10.3l1.48,-0.2c0.07,0.5 0.25,0.92 0.56,1.25c0.32,0.32 0.74,0.48 1.26,0.48c0.57,0 1.02,-0.18 1.34,-0.55c0.33,-0.37 0.49,-0.87 0.49,-1.48c0,-0.61 -0.16,-1.09 -0.49,-1.46C6.32,7.96 5.88,7.78 5.32,7.78C5,7.78 4.7,7.85 4.42,8C4.15,8.14 3.93,8.33 3.76,8.56L2.28,7.92l0.6,-4.94h5.26v1.36H4.1L3.72,7.02l0.08,0.03C4,6.87 4.25,6.73 4.55,6.62c0.3,-0.12 0.63,-0.18 1.01,-0.18c0.6,0 1.13,0.14 1.6,0.41C7.62,7.11 7.98,7.5 8.24,8c0.27,0.5 0.41,1.1 0.41,1.79c0,0.66 -0.14,1.26 -0.43,1.78c-0.28,0.51 -0.67,0.92 -1.18,1.22C6.55,13.08 5.97,13.22 5.3,13.22z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M14.51,13.22c-0.88,0 -1.66,-0.21 -2.34,-0.64c-0.67,-0.44 -1.2,-1.05 -1.6,-1.83C10.19,9.95 10,9.03 10,7.99c0,-1.05 0.21,-1.96 0.62,-2.74c0.41,-0.79 0.97,-1.4 1.67,-1.83c0.7,-0.44 1.5,-0.66 2.39,-0.66c1.09,0 2.01,0.25 2.74,0.76c0.75,0.5 1.22,1.21 1.41,2.11l-1.47,0.39c-0.17,-0.56 -0.48,-1 -0.94,-1.32c-0.45,-0.33 -1.03,-0.49 -1.75,-0.49c-0.57,0 -1.09,0.14 -1.57,0.43c-0.48,0.29 -0.85,0.71 -1.13,1.27s-0.42,1.25 -0.42,2.07c0,0.81 0.14,1.5 0.41,2.07c0.28,0.56 0.65,0.98 1.11,1.27c0.47,0.29 0.98,0.43 1.54,0.43c0.57,0 1.06,-0.11 1.47,-0.34c0.42,-0.23 0.75,-0.55 0.99,-0.94c0.25,-0.4 0.41,-0.85 0.46,-1.36h-2.88V7.79h4.37c0,0.87 0,1.74 0,2.6c0,0.87 0,1.74 0,2.6H17.6v-1.4h-0.08c-0.28,0.49 -0.67,0.88 -1.18,1.18C15.85,13.07 15.24,13.22 14.51,13.22z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M23,7.39c-0.53,0 -0.94,-0.16 -1.25,-0.47C21.45,6.6 21.3,6.16 21.3,5.6V3h0.8v2.66c0,0.3 0.08,0.54 0.23,0.71C22.48,6.54 22.7,6.62 23,6.62c0.3,0 0.52,-0.08 0.67,-0.25c0.15,-0.17 0.23,-0.41 0.23,-0.71V3h0.8v2.6c0,0.36 -0.07,0.67 -0.2,0.94s-0.33,0.48 -0.58,0.62C23.65,7.32 23.35,7.39 23,7.39z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M22.99,13.1c-0.39,0 -0.73,-0.09 -1.03,-0.28c-0.3,-0.19 -0.53,-0.45 -0.7,-0.79C21.08,11.7 21,11.3 21,10.85c0,-0.46 0.08,-0.85 0.25,-1.19c0.17,-0.34 0.41,-0.6 0.71,-0.78c0.3,-0.18 0.65,-0.28 1.04,-0.28c0.31,0 0.59,0.05 0.86,0.16c0.26,0.11 0.48,0.27 0.65,0.48c0.18,0.21 0.28,0.48 0.32,0.8l-0.83,0.14c-0.06,-0.26 -0.17,-0.46 -0.35,-0.6C23.49,9.44 23.27,9.37 23,9.37c-0.22,0 -0.42,0.06 -0.61,0.17c-0.18,0.11 -0.32,0.28 -0.43,0.5c-0.1,0.22 -0.16,0.49 -0.16,0.81c0,0.32 0.05,0.58 0.16,0.8s0.25,0.39 0.43,0.5c0.18,0.11 0.38,0.17 0.61,0.17c0.26,0 0.47,-0.07 0.65,-0.21c0.18,-0.14 0.3,-0.34 0.35,-0.59l0.85,0.09c-0.06,0.29 -0.17,0.54 -0.32,0.77c-0.15,0.22 -0.36,0.39 -0.61,0.52C23.66,13.03 23.35,13.1 22.99,13.1z"/>
-</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_5g_uw_mobiledata.xml b/packages/SettingsLib/res/drawable/ic_5g_uw_mobiledata.xml
deleted file mode 100644
index ca47b6f..0000000
--- a/packages/SettingsLib/res/drawable/ic_5g_uw_mobiledata.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-     Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="27dp"
-        android:height="16dp"
-        android:viewportWidth="27.0"
-        android:viewportHeight="16.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M5.3,13.22c-0.57,0 -1.1,-0.11 -1.58,-0.34c-0.48,-0.22 -0.87,-0.55 -1.18,-0.98C2.24,11.47 2.06,10.93 2,10.3l1.48,-0.2c0.07,0.5 0.25,0.92 0.56,1.25c0.32,0.32 0.74,0.48 1.26,0.48c0.57,0 1.02,-0.18 1.34,-0.55c0.33,-0.37 0.49,-0.87 0.49,-1.48c0,-0.61 -0.16,-1.09 -0.49,-1.46C6.32,7.96 5.88,7.78 5.32,7.78C5,7.78 4.7,7.85 4.42,8C4.15,8.14 3.93,8.33 3.76,8.56L2.28,7.92l0.6,-4.94h5.26v1.36H4.1L3.72,7.02l0.08,0.03C4,6.87 4.25,6.73 4.55,6.62c0.3,-0.12 0.63,-0.18 1.01,-0.18c0.6,0 1.13,0.14 1.6,0.41C7.62,7.11 7.98,7.5 8.24,8c0.27,0.5 0.41,1.1 0.41,1.79c0,0.66 -0.14,1.26 -0.43,1.78c-0.28,0.51 -0.67,0.92 -1.18,1.22C6.55,13.08 5.97,13.22 5.3,13.22z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M14.51,13.22c-0.88,0 -1.66,-0.21 -2.34,-0.64c-0.67,-0.44 -1.2,-1.05 -1.6,-1.83C10.19,9.95 10,9.03 10,7.99c0,-1.05 0.21,-1.96 0.62,-2.74c0.41,-0.79 0.97,-1.4 1.67,-1.83c0.7,-0.44 1.5,-0.66 2.39,-0.66c1.09,0 2.01,0.25 2.74,0.76c0.75,0.5 1.22,1.21 1.41,2.11l-1.47,0.39c-0.17,-0.56 -0.48,-1 -0.94,-1.32c-0.45,-0.33 -1.03,-0.49 -1.75,-0.49c-0.57,0 -1.09,0.14 -1.57,0.43c-0.48,0.29 -0.85,0.71 -1.13,1.27s-0.42,1.25 -0.42,2.07c0,0.81 0.14,1.5 0.41,2.07c0.28,0.56 0.65,0.98 1.11,1.27c0.47,0.29 0.98,0.43 1.54,0.43c0.57,0 1.06,-0.11 1.47,-0.34c0.42,-0.23 0.75,-0.55 0.99,-0.94c0.25,-0.4 0.41,-0.85 0.46,-1.36h-2.88V7.79h4.37c0,0.87 0,1.74 0,2.6c0,0.87 0,1.74 0,2.6H17.6v-1.4h-0.08c-0.28,0.49 -0.67,0.88 -1.18,1.18C15.85,13.07 15.24,13.22 14.51,13.22z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M23,7.39c-0.53,0 -0.94,-0.16 -1.25,-0.47C21.45,6.6 21.3,6.16 21.3,5.6V3h0.8v2.66c0,0.3 0.08,0.54 0.23,0.71C22.48,6.54 22.7,6.62 23,6.62c0.3,0 0.52,-0.08 0.67,-0.25c0.15,-0.17 0.23,-0.41 0.23,-0.71V3h0.8v2.6c0,0.36 -0.07,0.67 -0.2,0.94s-0.33,0.48 -0.58,0.62C23.65,7.32 23.35,7.39 23,7.39z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M21.41,13L20.3,8.7h0.73l0.64,2.78l0.07,0.38h0.04l0.09,-0.38l0.81,-2.78h0.66l0.79,2.78l0.09,0.37h0.04l0.07,-0.37l0.65,-2.78h0.72L24.59,13H23.9l-0.78,-2.84l-0.1,-0.41h-0.04l-0.1,0.41L22.08,13H21.41z"/>
-</vector>
diff --git a/packages/SettingsLib/res/layout/preference_category_divider.xml b/packages/SettingsLib/res/layout/preference_category_divider.xml
deleted file mode 100644
index 6644eec..0000000
--- a/packages/SettingsLib/res/layout/preference_category_divider.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2017 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.
-  -->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/two_target_divider"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:gravity="start|center_vertical"
-    android:orientation="horizontal">
-    <View
-        android:layout_height="1dp"
-        android:layout_width="match_parent"
-        android:background="?android:attr/dividerHorizontal" />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml b/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml
deleted file mode 100644
index 5b5d474..0000000
--- a/packages/SettingsLib/res/layout/preference_category_material_settings_with_divider.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2017 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.
-  -->
-
-<!-- Similar to preference_category_material_settings.xml, except that this always adds
-     a divider above category. -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-    <include layout="@layout/preference_category_divider"/>
-    <include layout="@layout/preference_category_material"/>
-</LinearLayout>
diff --git a/packages/SettingsLib/res/layout/restricted_popup_menu_item.xml b/packages/SettingsLib/res/layout/restricted_popup_menu_item.xml
deleted file mode 100644
index 52d7775..0000000
--- a/packages/SettingsLib/res/layout/restricted_popup_menu_item.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2016, 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.
-*/
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:gravity="center_vertical"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:paddingEnd="16dp"
-    android:paddingStart="16dp">
-
-    <TextView
-        android:id="@+id/text"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearanceListItemSmall"
-        android:textColor="?android:attr/textColorAlertDialogListItem" />
-
-</RelativeLayout>
diff --git a/packages/SettingsLib/res/layout/settings_dialog_title.xml b/packages/SettingsLib/res/layout/settings_dialog_title.xml
deleted file mode 100644
index 1e065e0..0000000
--- a/packages/SettingsLib/res/layout/settings_dialog_title.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 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
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/settings_title_panel"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:orientation="vertical">
-
-    <LinearLayout
-        android:id="@+id/settings_title_template"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:gravity="center"
-        android:paddingStart="?android:attr/dialogPreferredPadding"
-        android:paddingEnd="?android:attr/dialogPreferredPadding"
-        android:paddingTop="@*android:dimen/dialog_padding_top_material">
-
-        <ImageView
-            android:id="@+id/settings_icon"
-            android:layout_width="24dip"
-            android:layout_height="24dip"
-            android:layout_marginBottom="12dip" />
-
-        <TextView
-            android:id="@+id/settings_title"
-            android:singleLine="true"
-            android:ellipsize="end"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:textAlignment="center"
-            style="?android:attr/windowTitleStyle" />
-    </LinearLayout>
-
-    <Space
-        android:id="@+id/settings_title_divider"
-        android:visibility="gone"
-        android:layout_width="match_parent"
-        android:layout_height="@*android:dimen/dialog_title_divider_material" />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 9578045..a39a2b9 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Ontkoppel"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Gedeaktiveer"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-opstelling het misluk"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nie gekoppel nie weens laegehalte-netwerk"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi-verbinding het misluk"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Stawingsprobleem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Kan nie koppel nie"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Kan nie aan \"<xliff:g id="AP_NAME">%1$s</xliff:g>\" koppel nie"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Sal nie outomaties koppel nie"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Geen internettoegang nie"</string>
     <string name="saved_network" msgid="7143698034077223645">"Gestoor deur <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Gekoppel aan beperkte netwerk"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Outomaties deur %1$s gekoppel"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Outomaties deur netwerkgraderingverskaffer gekoppel"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Gekoppel via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Gekoppel via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Beskikbaar via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tik om aan te meld"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Geen internet nie"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Daar kan nie by private DNS-bediener ingegaan word nie"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Geen internet nie"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Aanmelding word vereis"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Toegangspunt is tydelik vol"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Gekoppel via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Beskikbaar via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Maak tans <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> oop"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Kon nie koppel nie"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Voltooi tans aanmelding …"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Kon nie aanmelding voltooi nie. Tik om weer te probeer."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Aanmelding is voltooi. Koppel tans …"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Baie stadig"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Stadig"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Middelmatig"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Vinnig"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Baie vinnig"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Verval"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Verbind tans…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Gekoppel (geen foon nie)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Gekoppel (geen media nie)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Gekoppel (geen boodskaptoegang nie)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Gekoppel (geen foon of media nie)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Gekoppel, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Gekoppel (geen foon nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 494ec1e..67f43c5 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"ተቋርጧል"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"ተሰናክሏል"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"የአይ.ፒ. ውቅረት መሰናከል"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"በዝቅተኛ አውታረ መረብ ምክንያት አልተገናኘም"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"የWiFi ግንኙነት መሰናከል"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"የማረጋገጫ ችግር"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"መገናኘት አልተቻለም"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"ወደ «<xliff:g id="AP_NAME">%1$s</xliff:g>» ማገናኘት አይቻልም"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"በራስ-ሰር አይገናኝም"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ምንም የበይነመረብ መዳረሻ ያለም"</string>
     <string name="saved_network" msgid="7143698034077223645">"የተቀመጠው በ<xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"ከሚለካ አውታረ መረብ ጋር ተገናኝቷል"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"በ%1$s በኩል በራስ-ሰር ተገናኝቷል"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"በአውታረ መረብ ደረጃ ሰጪ አቅራቢ በኩል በራስ-ሰር ተገናኝቷል"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"በ%1$s በኩል መገናኘት"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"በ <xliff:g id="NAME">%1$s</xliff:g> በኩል ተገናኝተዋል"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"በ%1$s በኩል የሚገኝ"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"ለመመዝገብ መታ ያድርጉ"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ምንም በይነመረብ የለም"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"የግል ዲኤንኤስ አገልጋይ ሊደረስበት አይችልም"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ምንም በይነመረብ የለም"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ወደ መለያ መግባት ያስፈልጋል"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"የመዳረሻ ነጥብ ለጊዜው ሞልቷል"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"በ%1$s በኩል ተገናኝቷል"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"በ%1$s በኩል የሚገኝ"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>ን በመክፈት ላይ"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"መገናኘት አልተቻለም"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"መመዝገብን በማጠናቀቅ ላይ…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"መመዝገብን ማጠናቀቅ አልተቻለም። እንደገና ለመሞከር መታ ያድርጉ።"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ምዝገባ ተጠናቋል። በማገናኘት ላይ…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"በጣም ቀርፋፋ"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"አዘግይ"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"እሺ"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"መካከለኛ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ፈጣን"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"እጅግ በጣም ፈጣን"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ጊዜው አልፏል"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"በማገናኘት ላይ..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"ተገናኝቷል (ምንም ስልክ የለም)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"ተገናኝቷል (ምንም ማህደረ መረጃ የለም)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"ተገናኝቷል (ምንም የመልዕክት መዳረሻ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"ተገናኝቷል (ምንም ስልክ ወይም ማህደረ መረጃ የለም)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"ተገናኝቷል፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"ተገናኝቷል (ምንም ስልክ የለም)፣ ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 5171e6f..705cccb 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"غير متصلة"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"غير مفعّلة"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"‏تعذّر إعداد عنوان IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"الجهاز غير متصل بسبب انخفاض جودة الشبكة"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"‏تعذّر اتصال WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"حدثت مشكلة في المصادقة"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"تعذَّر الاتصال"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"تعذَّر الاتصال بـ \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"لن يتم الاتصال تلقائيًا"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"لا يتوفّر اتصال بالإنترنت"</string>
     <string name="saved_network" msgid="7143698034077223645">"تم الحفظ بواسطة <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"تم الاتصال بشبكة تفرض تكلفة استخدام."</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏تم الاتصال تلقائيًا عبر %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"تم الاتصال تلقائيًا عبر مقدم خدمة تقييم الشبكة"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"‏تم الاتصال عبر %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"تم الاتصال عبر <xliff:g id="NAME">%1$s</xliff:g>."</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"‏متوفرة عبر %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"انقر للاشتراك."</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"لا يتوفر اتصال إنترنت."</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"لا يمكن الوصول إلى خادم أسماء نظام نطاقات خاص"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"لا يتوفر اتصال إنترنت."</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"يلزم تسجيل الدخول"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"نقطة الوصول ممتلئة مؤقتًا"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"‏تم الاتصال عبر %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"‏متوفرة عبر %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"فتح <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"تعذّر الاتصال."</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"جارٍ إكمال الاشتراك…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"تعذّر إكمال الاشتراك. انقر للمحاولة مرة أخرى."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"اكتمل الاشتراك. جارٍ الاتصال…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"بطيئة جدًا"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"بطيئة"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"جيدة"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"متوسطة"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"سريعة"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"سريعة جدًا"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"منتهية الصلاحية"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"جارٍ الاقتران..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"الجهاز متصل (بدون هاتف)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"الجهاز متصل (بدون وسائط)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"الجهاز متصل (بدون وصول إلى الرسائل)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"الجهاز متصل (بدون هاتف أو وسائط)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"الجهاز متصل، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"الجهاز متصل (بدون هاتف)، ومستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index d7d09dd..ba0d302 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"সংযোগ বিচ্ছিন্ন"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"নিষ্ক্ৰিয় হৈ আছে"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP কনফিগাৰেশ্বন বিফল হৈছে"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"নিম্নমানৰ নেটৱৰ্কৰ বাবে সংযোগ কৰা হোৱা নাই"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"ৱাই-ফাই সংযোগ বিফল হৈছে"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"সত্যাপন কৰাত সমস্যা হৈছে"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"সংযোগ কৰিব নোৱাৰে"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'ৰ সৈতে সংযোগ কৰিব পৰা নাই"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"স্বয়ংক্ৰিয়ভাৱে সংযোগ নহ’ব"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ইণ্টাৰনেট সংযোগ নাই"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g>এ ছেভ কৰিছে"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"নিৰিখ-নিৰ্দিষ্ট নেটৱৰ্কৰ সৈতে সংযোগ কৰা হৈছে"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s মাধ্যমেদি স্বয়ংক্ৰিয়ভাৱে সংযোগ কৰা হৈছে"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"নেটৱৰ্ক ৰেটিং প্ৰদানকাৰীৰ জৰিয়তে স্বয়ং সংয়োগ কৰা হ’ল"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s-ৰ মাধ্যমেদি সংযোগ কৰা হৈছে"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g>ৰ জৰিয়তে সংযুক্ত"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"ছাইন আপ কৰিবলৈ টিপক"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ইণ্টাৰনেট সংযোগ নাই"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"ব্যক্তিগত DNS ছাৰ্ভাৰ এক্সেছ কৰিব নোৱাৰি"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ইণ্টাৰনেট সংযোগ নাই"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ছাইন ইন কৰা দৰকাৰী"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"একচেছ পইণ্ট কিছু সময়ৰ বাবে পূৰ্ণ হৈ আছে"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$sৰ যোগেৰে সংযোজিত"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> খুলি থকা হৈছে"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"সংযোগ কৰিব পৰা নগ’ল"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"ছাইন আপ সম্পূৰ্ণ কৰি থকা হৈছে…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"ছাইন আপ সম্পূৰ্ণ কৰিব পৰা নগ’ল। আকৌ চেষ্টা কৰিবলৈ টিপক।"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ছাইন আপ সম্পূৰ্ণ হৈছে সংযোগ কৰি থকা হৈছে…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"অতি লেহেম"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"লেহেমীয়া"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ঠিক"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"মধ্যমীয়া"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"দ্ৰুত"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"অতি দ্ৰুত"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ম্যাদ উকলিছে"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"যোৰা লগোৱা হৈছে…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"সংযোগ কৰা হ’ল (ফ\'ন নাই)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"সংযোগ কৰা হ’ল (মিডিয়া নাই)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"সংযোগ কৰা হ’ল (বাৰ্তাত প্ৰৱেশাধিকাৰ নাই)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"সংযোগ কৰা হ’ল (কোনো ফ\'ন বা মিডিয়া নাই)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"সংযোগ কৰা হ’ল, বেটাৰীৰ স্তৰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"সংযোগ কৰা হ’ল (ফ\'ন নাই), বেটাৰীৰ স্তৰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 0d2f883..33efb4fd 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Bağlantı kəsildi"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Deaktiv"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP Konfiqurasiya Uğursuzluğu"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Şəbəkə keyfiyyəti aşağı olduğuna görə qoşulmadı"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi Bağlantı Uğursuzluğu"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Autentifikasiya problemi"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Qoşulmaq mümkün deyil"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" şəbəkəsinə qoşulmaq mümkün deyil"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Avtomatik qoşulmayacaq"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"İnternet girişi yoxdur"</string>
     <string name="saved_network" msgid="7143698034077223645">"Yadda saxlayan: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Ölçülən şəbəkəyə qoşulub"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s üzərindən avtomatik qoşuldu"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Avtomatik olaraq şəbəkə reytinq provayderi ilə qoşuludur"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s vasitəsilə qoşuludur"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> ilə qoşulub"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s vasitəsilə əlçatandır"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Qeydiyyatdan keçmək üçün klikləyin"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"İnternet yoxdur"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Özəl DNS serverinə giriş mümkün deyil"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"İnternet yoxdur"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Giriş tələb olunur"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Giriş nöqtəsi müvəqqəti olaraq doludur"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s ilə qoşuludur"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s vasitəsilə əlçatandır"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> açılır"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Qoşulmaq mümkün olmadı"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Qeydiyyat tamamlanır…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Qeydiyyat tamamlanmadı. Yenidən cəhd etmək üçün klikləyin."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Qeydiyyat tamamlandı. Qoşulur…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Çox Yavaş"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Yavaş"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Orta"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Sürətli"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Çox Sürətli"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vaxtı keçib"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Birləşdirilir..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Qoşuludur (telefon yoxdur)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Qoşuludur (media yoxdur)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Qoşuludur (mesaj girişi yoxdur)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Qoşuludur (telefon və ya media yoxdur)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Qoşuludur, batareya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Qoşuludur (telefon yoxdur), batareya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 92749327..108a136 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Veza je prekinuta"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Onemogućeno"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP konfiguracija je otkazala"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nije povezano zbog lošeg kvaliteta mreže"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi veza je otkazala"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem sa potvrdom identiteta"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Povezivanje nije uspelo"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Povezivanje sa „<xliff:g id="AP_NAME">%1$s</xliff:g>“ nije uspelo"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Automatsko povezivanje nije uspelo"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Povezani ste na mrežu sa ograničenjem"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezano preko %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezano preko dobavljača ocene mreže"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Povezano preko: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Dostupna je preko pristupne tačke %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Dodirnite da biste se registrovali"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nema interneta"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Pristup privatnom DNS serveru nije uspeo"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nema interneta"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Treba da se prijavite"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Pristupna tačka je privremeno zauzeta"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Povezano preko %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Dostupno preko %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Otvara se <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Povezivanje nije uspelo"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Registracija se dovršava…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Dovršavanje registracije nije uspelo. Dodirnite da biste probali ponovo."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registracija je dovršena. Povezuje se…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Veoma spora"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Spora"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Potvrdi"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Srednja"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Brza"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brza"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Uparivanje..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Povezano (bez telefona): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Povezano (bez medija): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Povezano je (bez pristupa porukama): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Povezano (bez telefona ili medija): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Povezano, nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Povezano (bez telefona), nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 2f1b7d7..5a70202 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Адключана"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Адключана"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Збой канфігурацыі IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Няма падключэння з-за нізкай якасці сеткі"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Збой падлучэння Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Праблема аўтэнтыфікацыі"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Немагчыма падключыцца"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Немагчыма падключыцца да сеткі \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Не будзе аўтаматычна падключацца"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Няма доступу да інтэрнэту"</string>
     <string name="saved_network" msgid="7143698034077223645">"Захавана праз: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Падключана да сеткі з падлікам трафіка"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Аўтаматычна падключана праз %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Аўтаматычна падключана праз пастаўшчыка паслугі ацэнкі сеткі"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Падключана праз %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Падключана праз праграму \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Даступна праз %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Націсніце, каб зарэгістравацца"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Няма падключэння да інтэрнэту"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Не ўдалося атрымаць доступ да прыватнага DNS-сервера"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Няма падключэння да інтэрнэту"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Трэба выканаць уваход"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Пункт доступу часова заняты"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Падключана праз %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Даступна праз %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Адкрываецца <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Не ўдалося падключыцца"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Рэгістрацыя завяршаецца…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Не ўдалося выканаць рэгістрацыю. Дакраніцеся, каб паўтарыць спробу."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Рэгістрацыя завершана. Ідзе падключэнне…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Вельмі павольная"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Павольная"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ОК"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Сярэдняя"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Хуткая"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Вельмі хуткая"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Тэрмін скончыўся"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Спалучэнне..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без званкоў)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без аўдыя)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без паведамленняў)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Падкл. прылада <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без званкоў і аўдыя)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>. Узровень зараду яе акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Падключана прылада <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без званкоў). Узровень зараду яе акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index c839f53..7e97dd3 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Няма връзка"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Деактивирани"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Неуспешно конфигуриране на IP адреса"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Не е установена връзка поради ниското качество на мрежата"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Неуспешна връзка с Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Проблем при удостоверяването"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Не може да се установи връзка"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Не може да се установи връзка с/ъс <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Няма да се свърже автоматично"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Няма достъп до интернет"</string>
     <string name="saved_network" msgid="7143698034077223645">"Запазено от <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Установена е връзка с мрежа с отчитане"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматично е установена връзка чрез %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматично е установена връзка чрез доставчик на услуги за оценяване на мрежите"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Установена е връзка през „%1$s“"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Установена е връзка през <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Мрежата е достъпна през „%1$s“"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Докоснете, за да се регистрирате"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Няма интернет"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Не може да се осъществи достъп до частния DNS сървър"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Няма връзка с интернет"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Изисква се вход в профила"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Точката за достъп временно е пълна"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Установена е връзка през %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Мрежата е достъпна през %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> се отваря"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Не можа да се установи връзка"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Регистрацията се завършва…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Регистрацията не можа да бъде завършена. Докоснете, за да опитате отново."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Регистрацията е завършена. Установява се връзка…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Много бавна"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Бавна"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ОK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Средна"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Бърза"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Много бърза"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Изтекло"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Сдвояване..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Свързано (без телефон)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Свързано (без мултимедия)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Свързано (без достъп до съобщенията)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Свързано (без телефон или мултимедия)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Свързано, батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Свързано (без телефон), батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 7a71dc8..023be24 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"কানেকশন নেই"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"অক্ষম হয়েছে"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP কনফিগারেশনের ব্যর্থতা"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"খারাপ নেটওয়ার্কের কারণে কানেক্ট নয়"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"ওয়াই ফাই সংযোগের ব্যর্থতা"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"যাচাইকরণ সমস্যা"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"কানেক্ট স্থাপন করা যাচ্ছে না"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'এ যোগ করা যায়নি"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"অটোমেটিক কানেক্ট করবে না"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ইন্টারনেট অ্যাক্সেস নেই"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> দ্বারা সেভ করা"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"মিটার্ড নেটওয়ার্কের সঙ্গে কানেক্ট করা"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"স্বয়ংক্রিয়ভাবে %1$s এর মাধ্যমে কানেক্ট হয়েছে"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"নেটওয়ার্কের রেটিং প্রদানকারীর মাধ্যমে অটোমেটিক কানেক্ট"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s মাধ্যমে কানেক্ট হয়েছে"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g>-এর মাধ্যমে কানেক্ট করা আছে"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s এর মাধ্যমে উপলব্ধ"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"সাইন-আপ করতে ট্যাপ করুন"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ইন্টারনেট কানেকশন নেই"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"ব্যক্তিগত ডিএনএস সার্ভার অ্যাক্সেস করা যাবে না"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ইন্টারনেট কানেকশন নেই"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"সাইন-ইন করা দরকার"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"এই মুহূর্তে অ্যাক্সেস পয়েন্টের কোনও কানেকশন ফাঁকা নেই"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s এর মাধ্যমে কানেক্ট হয়েছে"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s এর মাধ্যমে পাওয়া যাচ্ছে"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> খোলা হচ্ছে"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"কানেক্ট করা যায়নি"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"সাইন-আপ সম্পূর্ণ করা হচ্ছে…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"সাইন-আপ করা যায়নি। আবার চেষ্টা করতে ট্যাপ করুন।"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"সাইন-আপ করা হয়ে গেছে। কানেক্ট করা হচ্ছে…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"খুব ধীরে"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"ধীরে"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ঠিক আছে"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"মাঝারি"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"দ্রুত"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"খুব দ্রুত"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"মেয়াদ শেষ হয়ে গেছে"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"যুক্ত করা হচ্ছে..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"কানেক্ট করা আছে (ফোনের অডিও ছাড়া)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"কানেক্ট করা আছে (মিডিয়ার অডিও ছাড়া)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"কানেক্ট করা আছে (মেসেজে অ্যাকসেস নেই)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"কানেক্ট করা আছে (ফোনের বা মিডিয়ার অডিও ছাড়া)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"কানেক্ট করা আছে, ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"কানেক্ট করা আছে (ফোনের অডিও ছাড়া), ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 74325ca..3cb4190 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Nije povezano"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Onemogućeno"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Greška u konfiguraciji IP-a"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Niste povezani zbog slabog kvaliteta mreže"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Greška pri povezivanju na WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem pri autentifikaciji"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nije se moguće povezati"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Nije se moguće povezati na aplikaciju \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Neće se automatski povezati"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Sačuvano: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Povezani ste s mrežom s naplatom"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezano koristeći %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezano putem ocjenjivača mreže"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Povezani preko %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Povezano preko <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Dostupan preko %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Dodirnite za prijavu"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nema internetske veze"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Nije moguće pristupiti privatnom DNS serveru"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nema internetske veze"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Potrebna je prijava"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Pristupna tačka je privremeno puna"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Povezano koristeći %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Dostupna koristeći %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Otvaranje <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Povezivanje nije uspjelo"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Završavanje registracije…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Registraciju nije moguće izvršiti. Dodirnite da pokušate ponovo."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registracija je završena. Povezivanje…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Veoma sporo"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Sporo"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Uredu"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Srednja brzina"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Brzo"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brzo"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Uparivanje…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Povezano (bez telefona)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Povezano (bez medija)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Povezano (bez pristupa porukama)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Povezano (bez telefona ili medija)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Povezano, baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Povezano (bez telefona), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 94c3d56..efa29ee 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Desconnectada"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Desactivat"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Error de configuració d\'IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"No s\'ha connectat a la xarxa perquè la qualitat és baixa"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Error de connexió Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema d\'autenticació"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"No es pot connectar"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"No es pot connectar a <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"No es connectarà automàticament"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No hi ha accés a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Desada per <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connectat a una xarxa d\'ús mesurat"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Connectada automàticament a través de: %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Connectada automàticament a través d\'un proveïdor de valoració de xarxes"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Connectada mitjançant %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Connectat mitjançant <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponible mitjançant %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Toca per registrar-te"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Sense connexió a Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"No es pot accedir al servidor DNS privat"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Sense connexió a Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Cal iniciar la sessió"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"El punt d\'accés està temporalment ple"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Connectat mitjançant %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponible mitjançant %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"S\'està obrint <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"No s\'ha pogut connectar"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"S\'està completant el registre…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"No s\'ha pogut completar el registre. Toca per tornar-ho a provar."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"S\'ha completat el registre. S\'està connectant…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Molt lenta"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lenta"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Correcta"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Mitjana"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Ràpida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Molt ràpida"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducada"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"S\'està vinculant..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense accés al telèfon)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense contingut multimèdia)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense accés als missatges)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connectat (sense telèfon ni multimèdia)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connectat, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connectat (sense accés al telèfon), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
@@ -668,7 +658,7 @@
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si emets <xliff:g id="SWITCHAPP">%1$s</xliff:g> o canvies la sortida, l\'emissió actual s\'aturarà"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emet <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Canvia la sortida"</string>
-    <string name="back_navigation_animation" msgid="8105467568421689484">"Animacions per a les accions de tornada predictives"</string>
-    <string name="back_navigation_animation_summary" msgid="741292224121599456">"Activa animacions del sistema per a la tornada predictiva."</string>
+    <string name="back_navigation_animation" msgid="8105467568421689484">"Animacions de retrocés predictiu"</string>
+    <string name="back_navigation_animation_summary" msgid="741292224121599456">"Activa animacions del sistema de retrocés predictiu."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Aquesta configuració activa animacions del sistema per a accions gestuals predictives. Requereix definir enableOnBackInvokedCallback com a \"true\" en cada aplicació al fitxer de manifest."</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 6746ddf..3736f93 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Odpojeno"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Vypnuto"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Selhání konfigurace protokolu IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nejste připojeni, protože síť je příliš slabá"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Selhání připojení Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problém s ověřením"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nelze se připojit"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"K síti <xliff:g id="AP_NAME">%1$s</xliff:g> se nelze připojit"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Připojení nebude automaticky navázáno"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nebyl zjištěn žádný přístup k internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Uloženo uživatelem <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Připojeno k měřené síti"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automaticky připojeno přes poskytovatele %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automaticky připojeno přes poskytovatele hodnocení sítí"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Připojeno prostřednictvím %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Připojeno přes <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Dostupné prostřednictvím %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Klepnutím se zaregistrujete"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nejste připojeni k internetu"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Nelze získat přístup k soukromému serveru DNS"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nejste připojeni k internetu"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Je vyžadováno přihlášení"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Přístupový bod je dočasně zaplněn"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Připojeno prostřednictvím %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Dostupné prostřednictvím %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Spouštění aplikace <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Nelze se připojit"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Dokončování registrace…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Registraci se nepodařilo dokončit. Klepnutím opakujte akci."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registrace byla dokončena. Připojování…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Velmi pomalá"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Pomalá"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Střední"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rychlá"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Velmi rychlá"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Platnost vypršela"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Párování..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Připojeno k zařízení <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (bez telefonu)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Připojeno k zařízení <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (bez médií)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Připojeno k zařízení <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (bez přístupu ke zprávám)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Připojeno k zařízení <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (bez telefonu a médií)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Připojeno k zařízení <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>, úroveň baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Připojeno k zařízení <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (bez telefonu), úroveň baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index bee5b0f..849604d 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Afbrudt"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Deaktiveret"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-konfigurationsfejl"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Ingen forbindelse på grund af lav netværkskvalitet"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi-forbindelsesfejl"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem med godkendelse"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Kan ikke forbinde"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Der kan ikke oprettes forbindelse til \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Der oprettes ikke automatisk forbindelse"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ingen internetadgang"</string>
     <string name="saved_network" msgid="7143698034077223645">"Gemt af <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Der er oprettet forbindelse til det forbrugsbaserede netværk"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatisk tilsluttet via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatisk forbundet via udbyder af netværksvurdering"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Tilsluttet via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Forbundet via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Tilgængelig via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tryk for at registrere dig"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Intet internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Der er ikke adgang til den private DNS-server"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Intet internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Login er påkrævet"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Adgangspunktet er midlertidigt fuldt"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Tilsluttet via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Tilgængelig via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Åbner <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Der kunne ikke oprettes forbindelse"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Fuldfører registrering…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Registreringen kunne ikke fuldføres. Tryk for at prøve igen."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registreringen er fuldført. Opretter forbindelse…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Meget langsom"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Langsom"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Middel"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Hurtig"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Meget hurtig"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Udløbet"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Parrer..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (ingen telefon)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (ingen medier)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (ingen adgang til beskeder)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (ingen telefon eller medier)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (ingen telefon) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 9082210..d736d59 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Nicht verbunden"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Deaktiviert"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-Konfigurationsfehler"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Keine Verbindung aufgrund der geringen Netzwerkqualität"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WLAN-Verbindungsfehler"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Authentifizierungsproblem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Verbindung nicht möglich"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Keine Verbindung zu \"<xliff:g id="AP_NAME">%1$s</xliff:g>\" möglich"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Kein automatischer Verbindungsaufbau"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Kein Internetzugriff"</string>
     <string name="saved_network" msgid="7143698034077223645">"Gespeichert durch <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Mit kostenpflichtigem Netzwerk verbunden"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatisch über %1$s verbunden"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatisch über Anbieter von Netzwerkbewertungen verbunden"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Über %1$s verbunden"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Verbunden über <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Verfügbar über %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Zum Anmelden tippen"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Kein Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Auf den privaten DNS-Server kann nicht zugegriffen werden"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Kein Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Anmeldung erforderlich"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Zugangspunkt vorübergehend voll belegt"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Über %1$s verbunden"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Verfügbar über %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> wird geöffnet"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Verbindung nicht möglich"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Anmeldung wird abgeschlossen…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Anmeldung konnte nicht abgeschlossen werden. Tippe, um es noch einmal zu versuchen."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Anmeldung abgeschlossen. Verbindung wird hergestellt…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Sehr langsam"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Langsam"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Mittel"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Mittel"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Schnell"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Sehr schnell"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Abgelaufen"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Wird gekoppelt…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Mit <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> verbunden (kein Telefon-Audio)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Mit <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> verbunden (kein Medien-Audio)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Mit <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> verbunden (kein Nachrichtenzugriff)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Mit <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> verbunden (weder Telefon- noch Medien-Audio)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Mit <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> verbunden, Akkustand bei <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Mit <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> verbunden (kein Telefon-Audio), Akkustand bei <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 37be5b0..e76b933 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Αποσυνδεδεμένο"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Απενεργοποιημένο"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Αποτυχία διαμόρφωσης διεύθυνσης IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Δεν υπάρχει σύνδεση λόγω χαμηλής ποιότητας δικτύου"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Αποτυχία σύνδεσης Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Πρόβλημα ελέγχου ταυτότητας"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Αδυναμία σύνδεσης"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Δεν είναι δυνατή η σύνδεση στο δίκτυο \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Δεν θα συνδεθεί αυτόματα"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Δεν υπάρχει πρόσβαση στο διαδίκτυο"</string>
     <string name="saved_network" msgid="7143698034077223645">"Αποθηκεύτηκε από <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Σύνδεση σε δίκτυο με ογκοχρέωση"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Συνδέθηκε αυτόματα μέσω %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Συνδέθηκε αυτόματα μέσω παρόχου αξιολόγησης δικτύου"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Συνδέθηκε μέσω %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Συνδέθηκε μέσω <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Διαθέσιμο μέσω %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Πατήστε για εγγραφή"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Χωρίς σύνδεση στο διαδίκτυο"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Δεν είναι δυνατή η πρόσβαση στον ιδιωτικό διακομιστή DNS."</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Δεν υπάρχει σύνδεση στο διαδίκτυο"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Απαιτείται σύνδεση"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Το σημείο πρόσβασης είναι προσωρινά πλήρες"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Συνδέθηκε μέσω %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Διαθέσιμο μέσω %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Άνοιγμα <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Δεν ήταν δυνατή η σύνδεση"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Ολοκλήρωση εγγραφής…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Δεν ήταν δυνατή η ολοκλήρωση της εγγραφής. Πατήστε για να δοκιμάσετε ξανά."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Η εγγραφή ολοκληρώθηκε. Σύνδεση…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Πολύ αργή"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Αργή"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ΟΚ"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Μέτρια"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Γρήγορη"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Πολύ γρήγορη"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Έληξε"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Σύζευξη..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Σε σύνδεση (χωρίς τηλέφωνο)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Σε σύνδεση (χωρίς μέσα)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Σε σύνδεση (χωρίς πρόσβαση σε μηνύματα)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Σε σύνδεση (χωρίς τηλέφωνο ή μέσα)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Σε σύνδεση, μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Σε σύνδεση (χωρίς τηλέφωνο), μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index cc24ba4..09bc065 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Disconnected"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Disabled"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP Configuration Failure"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Not connected due to low quality network"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi Connection Failure"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Authentication problem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Can\'t connect"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No Internet access"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connected to metered network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatically connected via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatically connected via network rating provider"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Connected via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Available via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tap to sign up"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"No Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Private DNS server cannot be accessed"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"No Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Sign-in required"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Access point temporarily full"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Connected via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Available via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Couldn’t connect"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Completing sign-up…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Couldn’t complete sign-up. Tap to try again"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Sign-up complete. Connecting…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Very slow"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Slow"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Medium"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Fast"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Very fast"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expired"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Pairing…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Connected (no phone)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Connected (no media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Connected (no message access)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Connected (no phone or media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index ef72b12..77b20a6 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Disconnected"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Disabled"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP Configuration Failure"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Not connected due to low quality network"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi Connection Failure"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Authentication problem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Can\'t connect"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No Internet access"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connected to metered network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatically connected via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatically connected via network rating provider"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Connected via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Available via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tap to sign up"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"No Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Private DNS server cannot be accessed"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"No Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Sign-in required"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Access point temporarily full"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Connected via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Available via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Couldn’t connect"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Completing sign-up…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Couldn’t complete sign-up. Tap to try again"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Sign-up complete. Connecting…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Very slow"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Slow"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Medium"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Fast"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Very fast"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expired"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Pairing…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Connected (no phone)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Connected (no media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Connected (no message access)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Connected (no phone or media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index cc24ba4..09bc065 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Disconnected"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Disabled"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP Configuration Failure"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Not connected due to low quality network"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi Connection Failure"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Authentication problem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Can\'t connect"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No Internet access"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connected to metered network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatically connected via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatically connected via network rating provider"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Connected via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Available via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tap to sign up"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"No Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Private DNS server cannot be accessed"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"No Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Sign-in required"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Access point temporarily full"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Connected via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Available via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Couldn’t connect"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Completing sign-up…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Couldn’t complete sign-up. Tap to try again"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Sign-up complete. Connecting…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Very slow"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Slow"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Medium"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Fast"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Very fast"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expired"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Pairing…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Connected (no phone)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Connected (no media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Connected (no message access)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Connected (no phone or media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index cc24ba4..09bc065 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Disconnected"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Disabled"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP Configuration Failure"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Not connected due to low quality network"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi Connection Failure"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Authentication problem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Can\'t connect"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No Internet access"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connected to metered network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatically connected via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatically connected via network rating provider"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Connected via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Available via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tap to sign up"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"No Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Private DNS server cannot be accessed"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"No Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Sign-in required"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Access point temporarily full"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Connected via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Available via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Couldn’t connect"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Completing sign-up…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Couldn’t complete sign-up. Tap to try again"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Sign-up complete. Connecting…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Very slow"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Slow"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Medium"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Fast"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Very fast"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expired"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Pairing…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Connected (no phone)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Connected (no media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Connected (no message access)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Connected (no phone or media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 0fedf4b..f82a757 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎Disconnected‎‏‎‎‏‎"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎Disabled‎‏‎‎‏‎"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎IP Configuration Failure‎‏‎‎‏‎"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎Not connected due to low quality network‎‏‎‎‏‎"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎WiFi Connection Failure‎‏‎‎‏‎"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎Authentication problem‎‏‎‎‏‎"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎Can\'t connect‎‏‎‎‏‎"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‏‏‏‎Can\'t connect to \'‎‏‎‎‏‏‎<xliff:g id="AP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎\'‎‏‎‎‏‎"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎Won\'t automatically connect‎‏‎‎‏‎"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‏‎‏‏‎No internet access‎‏‎‎‏‎"</string>
     <string name="saved_network" msgid="7143698034077223645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎Saved by ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎Connected to metered network‎‏‎‎‏‎"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎Automatically connected via %1$s‎‏‎‎‏‎"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‎Automatically connected via network rating provider‎‏‎‎‏‎"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎Connected via %1$s‎‏‎‎‏‎"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎Connected via ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎Available via %1$s‎‏‎‎‏‎"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎Tap to sign up‎‏‎‎‏‎"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‎‎No internet‎‏‎‎‏‎"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎Private DNS server cannot be accessed‎‏‎‎‏‎"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‎No internet‎‏‎‎‏‎"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎Sign in required‎‏‎‎‏‎"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎Access point temporarily full‎‏‎‎‏‎"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎Connected via %1$s‎‏‎‎‏‎"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎Available via %1$s‎‏‎‎‏‎"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‎Opening ‎‏‎‎‏‏‎<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎Couldn’t connect‎‏‎‎‏‎"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎Completing sign-up…‎‏‎‎‏‎"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎Couldn’t complete sign-up. Tap to try again.‎‏‎‎‏‎"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎Sign-up complete. Connecting…‎‏‎‎‏‎"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎Very Slow‎‏‎‎‏‎"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎Slow‎‏‎‎‏‎"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎OK‎‏‎‎‏‎"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎Medium‎‏‎‎‏‎"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎Fast‎‏‎‎‏‎"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎Very Fast‎‏‎‎‏‎"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎Expired‎‏‎‎‏‎"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎‎Pairing…‎‏‎‎‏‎"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‎Connected (no phone)‎‏‎‎‏‏‎<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎Connected (no media)‎‏‎‎‏‏‎<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎Connected (no message access)‎‏‎‎‏‏‎<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‎‏‎Connected (no phone or media)‎‏‎‎‏‏‎<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎Connected, battery ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‎Connected (no phone), battery ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index fb976e5..1a4e307 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Desconectado"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Inhabilitada"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Error de configuración IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"No se estableció conexión debido a la mala calidad de la red"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Error de conexión Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema de autenticación"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"No se puede establecer la conexión"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"No se puede establecer conexión con \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"No se conectará automáticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No hay acceso a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Conectado a la red de uso medido"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conexión automática mediante %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectado automáticamente mediante proveedor de calificación de red"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Conexión a través de %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Conexión a través de <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponible a través de %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Presiona para registrarte"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Sin Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"No se puede acceder al servidor DNS privado"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Sin Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Acceso obligatorio"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"El punto de acceso está completo temporalmente"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Conexión a través de %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponible a través de %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Abriendo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"No se pudo establecer conexión"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Completando registro…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"No se pudo completar el registro. Presiona para volver a intentarlo."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Se completó el registro. Conectando…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Muy lenta"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lenta"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Aceptar"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vencida"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Vinculando..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Conectado (sin teléfono) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Conectado (sin archivos multimedia) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Conectado (sin acceso a mensajes) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Conectado (sin teléfono/multimedia) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Conectado a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Conectado (sin teléfono) a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 6097023..fdf99e0 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Desconectado"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Inhabilitado"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Error de configuración de IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"No conectado debido a la baja calidad de la red"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Error de conexión Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Error de autenticación"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"No se puede establecer conexión"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"No se puede establecer conexión con \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"No se establecerá conexión automáticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No se ha detectado ningún acceso a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Conectado a una red de uso medido"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectada automáticamente a través de %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectado automáticamente a través de un proveedor de valoración de redes"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado a través de %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Conectado a través de <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponible a través de %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Toca para registrarte"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Sin Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"No se ha podido acceder al servidor DNS privado"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Sin Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Debes iniciar sesión"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Punto de acceso temporalmente lleno"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Conectado a través de %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponible a través de %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Abriendo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"No se ha podido conectar"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Completando registro…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"No se ha podido completar el registro. Toca para volver a intentarlo."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Se ha completado el registro. Conectando…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Muy lenta"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lenta"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Aceptable"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducada"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Emparejando…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sin audio de teléfono)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Conectado (sin audio multimedia) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sin acceso a mensajes)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sin audio de teléfono ni multimedia)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Conectado a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Conectado (sin audio de teléfono) a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 2825c06..bcd395c 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Pole ühendatud"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Keelatud"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP seadistamise ebaõnnestumine"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Võrgu kehva kvaliteedi tõttu ei ühendatud"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi-ühenduse viga"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Autentimise probleem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Ei saa ühendada"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Võrguga „<xliff:g id="AP_NAME">%1$s</xliff:g>” ei saa ühendada"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Automaatselt ei ühendata"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Juurdepääs Internetile puudub"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salvestas: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Ühendatud mahupõhise võrguga"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Ühendus loodi automaatselt teenusega %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ühendus loodi automaatselt võrgukvaliteedi hinnangute pakkuja kaudu"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Ühendatud üksuse %1$s kaudu"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Ühendatud võrgu <xliff:g id="NAME">%1$s</xliff:g> kaudu"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Saadaval üksuse %1$s kaudu"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Puudutage registreerumiseks"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Interneti pole"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Privaatsele DNS-serverile ei pääse juurde"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Interneti-ühendus puudub"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Nõutav on sisselogimine"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Pääsupunkt on ajutiselt täis"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Ühendatud operaatori %1$s kaudu"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Saadaval operaatori %1$s kaudu"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Teenuse <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> avamine"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Ühendust ei saanud luua"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Registreerimise lõpuleviimine …"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Registreerimist ei saanud lõpule viia. Puudutage, et uuesti proovida."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registreerimine on lõpule viidud. Ühendamine …"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Väga aeglane"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Aeglane"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Hea"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Keskmine"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Kiire"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Väga kiire"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Aegunud"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Sidumine ..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Ühendatud (telefoni pole)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Ühendatud (meediat pole)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Ühendatud (juurdepääs sõnumitele puudub)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Ühendatud (telefoni ega meediat pole)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Ühendatud, aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Ühendatud (telefoni pole), aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 765e2f2..8e8150c 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Deskonektatuta"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Desgaituta"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Ezin izan da konfiguratu IP helbidea"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Ez dago konektatuta sarearen kalitate eskasagatik"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Ezin izan da konektatu wifi-sarera"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Autentifikazio-arazoa"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Ezin da konektatu"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Ezin da konektatu \"<xliff:g id="AP_NAME">%1$s</xliff:g>\" sarera"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Ez da konektatuko automatikoki"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ezin da konektatu Internetera"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioak gorde du"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Sare neurtu batera konektatuta"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s bidez automatikoki konektatuta"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatikoki konektatuta sare-balorazioen hornitzailearen bidez"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s bidez konektatuta"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> bidez konektatuta"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s bidez erabilgarri"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Sakatu erregistratzeko"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Ez dago Interneteko konexiorik"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Ezin da atzitu DNS zerbitzari pribatua"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Ez dago Interneteko konexiorik"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Saioa hasi behar da"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Sarbide-puntua beteta dago aldi baterako"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s bidez konektatuta"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s bidez erabilgarri"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> irekitzen"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Ezin izan da konektatu"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Erregistroa osatzen…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Ezin izan da osatu erregistroa. Berriro saiatzeko, ukitu hau."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Erregistratu da. Konektatzen…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Oso motela"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Motela"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Ados"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Tartekoa"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Bizkorra"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Oso bizkorra"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Iraungita"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Parekatzen…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Konektatuta (telefonoaren audiorik gabe)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Konektatuta (gailuaren audiorik gabe)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Konektatuta (mezuetarako sarbiderik gabe)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Konektatuta (telefonoaren edo gailuaren audiorik gabe)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Konektatuta. Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>."</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Konektatuta (telefonoaren audiorik gabe). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>."</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index c0b8a27..d40f692 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"اتصال قطع شد"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"غیرفعال شد"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"‏پیکربندی IP انجام نشد"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"اتصال ناموفق به دلیل شبکه با کیفیت پایین"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"‏اتصال Wi-Fi برقرار نشد"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"مشکل اصالت‌سنجی"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"برقراری اتصال ممکن نیست"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"برقراری اتصال به «<xliff:g id="AP_NAME">%1$s</xliff:g>» ممکن نیست"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"اتصال به‌صورت خودکار انجام نمی‌شود"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"دسترسی به اینترنت ندارد"</string>
     <string name="saved_network" msgid="7143698034077223645">"ذخیره‌شده توسط <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"اتصال به شبکه محدود برقرار شد"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏اتصال خودکار ازطریق %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"اتصال خودکار ازطریق ارائه‌دهنده رده‌بندی شبکه"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"‏متصل از طریق %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"متصل شده ازطریق <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"‏در دسترس از طریق %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"برای ثبت‌نام ضربه بزنید"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"عدم اتصال به اینترنت"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"‏سرور DNS خصوصی قابل دسترسی نیست"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"عدم دسترسی به اینترنت"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ورود به سیستم لازم است"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ظرفیت نقطه دسترسی موقتاً تکمیل شده است"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"‏متصل ازطریق %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"‏در دسترس ازطریق %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"درحال بازکردن <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"متصل نشد"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"درحال تکمیل ثبت‌نام…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"ثبت‌نام تکمیل نشد. برای امتحان مجدد ضربه بزنید."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ثبت‌نام کامل شد. درحال اتصال…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"بسیار آهسته"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"آهسته"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"تأیید"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"متوسط"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"سریع"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"خیلی سریع"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"منقضی‌شده"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"در حال مرتبط‌سازی..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"متصل (بدون تلفن)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"متصل (بدون رسانه)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"متصل (بدون دسترسی پیام)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"متصل (بدون تلفن یا رسانه)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"متصل، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"متصل (بدون تلفن)، باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 66373b5..0d6036a 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Yhteys katkaistu"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Pois päältä"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-kokoonpanovirhe"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Ei yhteyttä – verkko huonolaatuinen"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi-yhteysvirhe"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Todennusvirhe"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Yhdistäminen ei onnistu."</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Yhdistäminen verkkoon <xliff:g id="AP_NAME">%1$s</xliff:g> ei onnistu."</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Yhteyttä ei muodosteta automaattisesti"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ei internetyhteyttä"</string>
     <string name="saved_network" msgid="7143698034077223645">"Tallentaja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Yhdistetty maksulliseen verkkoon"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automaattinen yhteys muodostettu palvelun %1$s kautta"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Yhdistetty automaattisesti verkon arviointipalvelun kautta"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Yhdistetty seuraavan kautta: %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Yhdistetty (<xliff:g id="NAME">%1$s</xliff:g>)"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Käytettävissä seuraavan kautta: %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Rekisteröidy napauttamalla"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Ei internetyhteyttä"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Ei pääsyä yksityiselle DNS-palvelimelle"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Ei internetyhteyttä"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Sisäänkirjautuminen vaaditaan"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Yhteyspiste tilapäisesti täynnä"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Yhdistetty, verkko: %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Käytettävissä, verkko: %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Avataan <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Ei yhteyttä"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Viimeistellään rekisteröitymistä…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Rekisteröityminen epäonnistui. Yritä uudelleen napauttamalla."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Rekisteröityminen valmis. Yhdistetään…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Hyvin hidas"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Hidas"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Kohtuullinen"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Nopea"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Hyvin nopea"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vanhentunut"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Laiteparia muodostetaan..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Yhdistetty (ei puhelimen ääntä) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Yhdistetty (ei median ääntä) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Yhdistetty (ei pääsyä viesteihin) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Yhdistetty (ei puhelinta tai mediaa) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Yhdistetty, akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Yhdistetty (ei puhelimen ääntä), akun varaus <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index f1acddae..f276236 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Déconnecté"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Désactivés"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Échec de configuration de l\'adresse IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Non connecté en raison de la mauvaise qualité du réseau"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Échec de connexion Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problème d\'authentification"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Connexion impossible"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Impossible de se connecter à « <xliff:g id="AP_NAME">%1$s</xliff:g> »"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Reconnexion automatique impossible"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Aucun accès à Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Enregistrés par <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Appareil connecté à un réseau mesuré"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatiquement connecté par %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Connecté automatiquement par le fournisseur d\'avis sur le réseau"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Connecté par %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Connecté sur le réseau <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Accessible par %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Toucher pour vous connecter"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Aucune connexion Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Impossible d\'accéder au serveur DNS privé"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Aucune connexion Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Connexion requise"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Le point d\'accès est temporairement plein"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Connecté par %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Accessible par %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Ouverture de <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> en cours…"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Impossible de se connecter"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Terminaison de l\'inscription en cours…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Impossible de terminer l\'inscription. Touchez pour réessayer."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Inscription terminée. Connexion en cours…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Très lente"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lente"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Moyenne"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Élevée"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Très rapide"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expiré"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Association…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Connecté (aucun téléphone) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Connecté (aucun média) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Connecté (aucun accès aux messages) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Connecté (aucun téléphone ni média) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Connecté, pile chargée à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Connecté (aucun téléphone), pile chargée à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index d7cd507..7c4afa7 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Déconnecté"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Désactivé"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Échec de configuration de l\'adresse IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Non connecté en raison de la faible qualité du réseau"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Échec de la connexion Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problème d\'authentification"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Connexion impossible"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Impossible de se connecter au réseau \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Reconnexion automatique impossible"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Aucun accès à Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Enregistré lors de : <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connecté au réseau facturé à l\'usage"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Connecté automatiquement via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Connecté automatiquement via un fournisseur d\'évaluation du réseau"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Connecté via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Connecté via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponible via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Appuyez ici pour vous connecter"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Aucun accès à Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Impossible d\'accéder au serveur DNS privé"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Aucun accès à Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Connexion requise"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Point d\'accès temporairement plein"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Connecté via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponible via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Ouverture de <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>…"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Impossible de se connecter"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Finalisation de l\'inscription…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Impossible de finaliser l\'inscription. Appuyez ici pour réessayer."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Inscription terminée. Connexion…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Très lente"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lente"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Correcte"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Moyenne"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Élevée"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Très rapide"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Arrivé à expiration"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Association…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Connecté (aucun téléphone)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Connecté (aucun contenu mutimédia)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Connecté (sans accès aux messages)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Connecté (aucun tél./contenu multimédia)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Connecté, batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Connecté (aucun téléphone), batterie à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 30ef44e..95d5e21 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Rede desconectada"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Desactivadas"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Erro na configuración de IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Non se estableceu conexión porque a rede é de baixa calidade"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Erro na conexión wifi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema de autenticación"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Non se pode establecer conexión"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Non se pode establecer conexión coa aplicación <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Non se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Sen acceso a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Gardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Estableceuse conexión coa rede sen tarifa plana"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectouse automaticamente a través de %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectada automaticamente a través dun provedor de valoración de redes"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado a través de %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Wifi conectada a través de <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Dispoñible a través de %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Toca para rexistrarte"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Non hai conexión a Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Non se puido acceder ao servidor DNS privado"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Non hai conexión a Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"É obrigatorio iniciar sesión"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"O punto de acceso está temporalmente cheo"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Conectado a través de %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Dispoñible a través de %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Abrindo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Non se puido establecer conexión"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Completando o rexistro…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Non se puido completar o rexistro. Toca para tentalo de novo."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Completouse o rexistro. Conectando…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Moi lenta"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lenta"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Aceptar"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Moi rápida"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducou"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Vinculando..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sen teléfono)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sen audio multimedia)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sen acceso a mensaxes)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sen tel./audio multimedia)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Conectado a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>, batería ao <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Conectado a <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (sen teléfono), batería ao <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 20dbf4f..e8acbd5 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"ડિસ્કનેક્ટ કર્યું"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"અક્ષમ કર્યો"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP કન્ફિગરેશન નિષ્ફળ"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ઓછી ગુણવત્તાવાળા નેટવર્કના લીધે કનેક્ટ થયું નથી"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi કનેક્શન નિષ્ફળ"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"પ્રમાણીકરણ સમસ્યા"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"કનેક્ટ કરી શકાતું નથી"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' સાથે કનેક્ટ કરી શકાતું નથી"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ઑટોમૅટિક રીતે કનેક્ટ કરશે નહીં"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા સચવાયું"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"મીટર્ડ (ડેટા નિયંત્રણ) નેટવર્ક સાથે કનેક્ટેડ છે"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s દ્વારા સ્વત: કનેક્ટ થયેલ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"નેટવર્ક રેટિંગ પ્રદાતા દ્વારા ઑટોમૅટિક રીતે કનેક્ટ થયું"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કનેક્ટ થયેલ"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s દ્વારા ઉપલબ્ધ"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"સાઇન અપ કરવા માટે ટૅપ કરો"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"કોઈ ઇન્ટરનેટ નથી"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"ખાનગી DNS સર્વર ઍક્સેસ કરી શકાતા નથી"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ઇન્ટરનેટ ઍક્સેસ નથી"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"સાઇન ઇન આવશ્યક"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ઍક્સેસ પૉઇન્ટ અસ્થાયીરૂપે ભરાયેલ છે"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s દ્વારા ઉપલબ્ધ"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ખોલી રહ્યાં છીએ"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"કનેક્ટ કરી શકાયું નથી"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"સાઇન અપ પૂર્ણ કરી રહ્યા છીએ…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"સાઇન અપ પૂર્ણ કરી શકાયું નથી. ફરી પ્રયાસ કરવા માટે ટૅપ કરો."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"સાઇન અપ પૂર્ણ. કનેક્ટ કરી રહ્યાં છીએ…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"ખૂબ જ ધીમી"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"ધીમી"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ઓકે"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"મધ્યમ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ઝડપી"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ખૂબ ઝડપી"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"સમય સમાપ્ત થયો"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"જોડી કરી રહ્યું છે…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ ફોન નથી)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ મીડિયા નથી)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ સંદેશ ઍક્સેસ નથી)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> સાથે કનેક્ટ થયેલ (ફોન કે મીડિયા નથી)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> સાથે કનેક્ટ થયેલ, બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ ફોન નથી), બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index db53698..1c4e4a0 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"डिसकनेक्ट किया गया"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"अक्षम"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP कॉन्‍फ़िगरेशन की विफलता"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"खराब नेटवर्क होने के कारण कनेक्ट नहीं हुआ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"वाईफ़ाई कनेक्‍शन विफलता"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"पुष्टि नहीं हो सकी"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"कनेक्ट नहीं हो पा रहा है"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' से कनेक्ट नहीं हो पा रहा है"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"अपने आप कनेक्ट नहीं होगा"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"इंटरनेट नहीं है"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> के द्वारा सहेजा गया"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"सीमित डेटा वाले नेटवर्क से कनेक्ट किया गया"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s के ज़रिए ऑटोमैटिक रूप से कनेक्ट है"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"नेटवर्क रेटिंग कंपनी के ज़रिए अपने आप कनेक्ट है"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s के द्वारा उपलब्ध"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> के ज़रिए कनेक्ट किया गया"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s के द्वारा उपलब्ध"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"साइन अप करने के लिए टैप करें"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"इंटरनेट कनेक्शन नहीं है"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"निजी डीएनएस सर्वर को ऐक्सेस नहीं किया जा सकता"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"इंटरनेट कनेक्शन नहीं है"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"साइन इन करना ज़रूरी है"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ऐक्सेस पॉइंट फ़िलहाल भरा हुआ है"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s के ज़रिए कनेक्ट"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s के ज़रिए उपलब्ध"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> खोला जा रहा है"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"कनेक्ट नहीं किया जा सका"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"साइन-अप पूरा हो रहा है…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"साइन-अप पूरा नहीं हो सका. फिर से कोशिश करने के लिए टैप करें."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"साइन-अप पूरा हुआ. कनेक्ट हो रहा है…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"अत्‍यधिक धीमी"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"धीमी"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ठीक है"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"मध्यम"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"तेज़"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"बहुत ज़्यादा तेज़"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"समयसीमा खत्म हो गई"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"जोड़ा जा रहा है…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"जुड़ गया (फ़ोन के ऑडियो को छोड़कर)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"जुड़ गया (मीडिया ऑडियो को छोड़कर)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"जुड़ गया (मैसेज का ऐक्सेस नहीं)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"जुड़ गया (फ़ोन या मीडिया ऑडियो को छोड़कर)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"जुड़ गया, बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"जुड़ गया (फ़ोन के ऑडियो को छोड़कर), बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 89fcb8e..06166f6 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Nije povezano"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Onemogućeno"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Konfiguracija IP-a nije uspjela"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Niste povezani jer je mreža loše kvalitete"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Povezivanje s Wi-Fijem nije uspjelo"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem u autentifikaciji"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Povezivanje nije uspjelo"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Povezivanje s aplikacijom \"<xliff:g id="AP_NAME">%1$s</xliff:g>\" nije uspjelo"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Neće se povezati automatski"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Spremila aplik. <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Povezano s mrežom s ograničenim prometom"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezan putem %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezan putem ocjenjivača mreže"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Povezano putem %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Povezan putem mreže <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Dostupno putem %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Dodirnite da biste se registrirali"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nema interneta"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Nije moguće pristupiti privatnom DNS poslužitelju"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nema interneta"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Obavezna prijava"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Pristupna je točka privremeno puna"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Povezano putem mreže %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Dostupno putem mreže %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Otvaranje aplikacije <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Povezivanje nije uspjelo"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Dovršavanje registracije…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Nije moguće dovršiti registraciju. Dodirnite za ponovni pokušaj."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registracija je dovršena. Povezivanje…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Vrlo sporo"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Sporo"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"U redu"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Srednje"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Brzo"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Vrlo brzo"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Uparivanje…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Povezano (bez telefona): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Povezano (bez medija): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Povezano (bez pristupa porukama): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Povezano (bez telefona i medija): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Povezano, baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Povezano (bez telefona), baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 21dbfe8..af5a114 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Leválasztva"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Letiltva"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-konfigurációs hiba"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nem kapcsolódik a hálózat rossz minősége miatt"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi-kapcsolati hiba"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Azonosítási probléma"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nem lehet csatlakozni"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Nem lehet csatlakozni a(z) „<xliff:g id="AP_NAME">%1$s</xliff:g>” hálózathoz"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nem csatlakozik automatikusan"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nincs internet-hozzáférés"</string>
     <string name="saved_network" msgid="7143698034077223645">"Mentette: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Forgalomkorlátos hálózathoz csatlakozva"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatikusan csatlakozott a következőn keresztül: %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatikusan csatlakozott a hálózatértékelés szolgáltatóján keresztül"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Csatlakozva a következőn keresztül: %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Kapcsolódva a következőn keresztül: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Elérhető a következőn keresztül: %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Koppintson a regisztrációhoz"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nincs internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"A privát DNS-kiszolgálóhoz nem lehet hozzáférni"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nincs internetkapcsolat"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Bejelentkezést igényel"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"A hozzáférési pont átmenetileg megtelt"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Csatlakozva a következőn keresztül: %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Elérhető a következőn keresztül: %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> megnyitása"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Nem sikerült csatlakozni"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Regisztráció befejezése…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Nem sikerült a regisztráció befejezése. Koppintással újrapróbálkozhat."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"A regisztráció befejeződött. Csatlakozás…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Nagyon lassú"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lassú"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Rendben"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Közepes"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Gyors"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Nagyon gyors"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Lejárt"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Párosítás..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Csatlakoztatva (telefonhang nélkül)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Csatlakoztatva (médiahang nélkül)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Csatlakoztatva (nincs üzenet-hozzáférés)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Csatlakoztatva (nincs telefon- és médiahang)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Csatlakoztatva, az akkumulátor töltöttsége: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Csatlakoztatva (telefonhang nélkül); az akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 4affd4f..61c3e7e 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Կապ չկա"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Անջատված"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP կարգավորման ձախողում"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Չի կապակցվել ցանցի թույլ ազդանշանի պատճառով"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi կապի ձախողում"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Նույնականացման խնդիր"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Կապ չկա"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Հնարավոր չէ միանալ «<xliff:g id="AP_NAME">%1$s</xliff:g>»-ին"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Չի միանա ավտոմատ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ինտերնետ կապ չկա"</string>
     <string name="saved_network" msgid="7143698034077223645">"Պահվել է՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Միացած է վճարովի թրաֆիկով ցանցի"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ավտոմատ միացել է ցանցերի վարկանիշի մատակարարի միջոցով"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Միացված է %1$s-ի միջոցով"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Միացված է <xliff:g id="NAME">%1$s</xliff:g>-ի միջոցով"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Հասանելի է %1$s-ի միջոցով"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Հպեք՝ գրանցվելու համար"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Կապ չկա"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Մասնավոր DNS սերվերն անհասանելի է"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Ինտերնետ կապ չկա"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Անհրաժեշտ է մուտք գործել"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Հասանելիության կետը ժամանակավորապես լիքն է"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Միացված է %1$s-ի միջոցով"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Հասանելի է %1$s-ի միջոցով"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>, բացվում է"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Չհաջողվեց միանալ"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Գրանցումն ավարտվում է…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Չհաջողվեց ավարտել գրանցումը: Հպեք` նորից փորձելու համար:"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Գրանցումն ավարտված է: Միացում…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Շատ դանդաղ"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Դանդաղ"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Լավ"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Միջին"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Արագ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Շատ արագ"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Սպառվել է"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Զուգակցում..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Միացավ <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> սարքին (հեռախոս չկա)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Միացավ <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> սարքին (մեդիա չկա)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Միացավ <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> սարքին (հաղորդագրություններ չկան)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Միացավ <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> սարքին (հեռախոս կամ մեդիա չկա)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Միացված է, մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Միացված է (հեռախոս չկա), մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 69174cf..d7f5857 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Terputus"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Nonaktif"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Kegagalan Konfigurasi IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Tidak terhubung karena jaringan berkualitas rendah"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Kegagalan Sambungan Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Masalah autentikasi"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Tidak dapat terhubung"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Tidak dapat terhubung ke \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Tidak akan terhubung otomatis"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Tidak ada akses internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Disimpan oleh <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Terhubung ke jaringan berbayar"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Terhubung otomatis melalui %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Otomatis terhubung melalui penyedia rating jaringan"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Terhubung melalui %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Terhubung melalui <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Tersedia melalui %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Ketuk untuk mendaftar"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Tidak ada internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Server DNS pribadi tidak dapat diakses"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Tidak ada internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Perlu login"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Titik akses penuh untuk sementara"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Terhubung melalui %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Tersedia melalui %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Membuka <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Tidak dapat terhubung"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Menyelesaikan pendaftaran…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Tidak dapat menyelesaikan pendaftaran. Ketuk untuk mencoba lagi."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Pendaftaran selesai. Menyambungkan…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Sangat Lambat"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lambat"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Oke"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Sedang"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Cepat"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Sangat Cepat"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Sudah tidak berlaku"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Menyambungkan..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Terhubung (tanpa ponsel)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Terhubung (tanpa media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Terhubung (tanpa akses pesan)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Terhubung (tanpa ponsel atau media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Terhubung, baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Terhubung (tanpa ponsel), baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index b541d50..4862904 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Aftengt"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Óvirkt"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-stillingarvilla"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Tenging er ekki til staðar því nettengingin er léleg"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi-tengingarvilla"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Vandamál við auðkenningu"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Ekki tókst að tengjast"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Ekki tókst að tengjast við „<xliff:g id="AP_NAME">%1$s</xliff:g>“"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Mun ekki tengjast sjálfkrafa"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Enginn netaðgangur"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> vistaði"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Tengdist neti með mældri notkun"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Sjálfkrafa tengt um %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Sjálfkrafa tengt um netgæðaveitu"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Tengt í gegnum %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Tenging í gegnum <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Í boði í gegnum %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Ýttu til að skrá þig"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Engin nettenging"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Ekki næst í DNS-einkaþjón"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Engin nettenging"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Innskráningar krafist"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Aðgangsstaður tímabundið fullur"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Tengt í gegnum %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Í boði í gegnum %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Opnar <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Ekki tókst að tengjast"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Gengur frá nýskráningu…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Ekki tókst að ljúka við nýskráningu. Ýttu til að reyna aftur."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Nýskráningu lokið. Tengist…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Mjög hægt"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Hægt"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Í lagi"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Miðlungshratt"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Hratt"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Mjög hratt"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Útrunnin"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Parar…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Tengt (enginn sími) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Tengt (ekkert efni) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Tengt (enginn aðgangur að skilaboðum) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Tengt (enginn sími eða efni) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Tengt, staða rafhlöðu <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Tengt (enginn sími), staða rafhlöðu <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 4e948a4..9e5a224 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Non connessa"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Disattivata"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Errore configurazione IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Impossibile connettersi a causa della bassa qualità della rete"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Errore connessione Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema di autenticazione"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Impossibile stabilire una connessione"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Impossibile connettersi a \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Non verrà eseguita la connessione automatica"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nessun accesso a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salvata da <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connessione a rete a consumo effettuata"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Collegato automaticamente tramite %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Collegato automaticamente tramite fornitore di servizi di valutazione rete"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Collegato tramite %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Connesso tramite <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponibile tramite %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tocca per registrarti"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Internet assente"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Non è possibile accedere al server DNS privato"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nessuna connessione a Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Accesso richiesto"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Punto di accesso momentaneamente al completo"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Connesso tramite %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponibile tramite %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Apertura di <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>…"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Impossibile collegarsi"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Completamento della registrazione…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Impossibile completare la registrazione. Tocca per riprovare."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registrazione completata. Connessione…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Molto lenta"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lenta"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Veloce"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Molto veloce"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Scaduta"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Accoppiamento…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (telefono escluso)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (contenuti multimediali esclusi)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (nessun accesso ai messaggi)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (telefono o media esclusi)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connesso, batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> connesso (telefono escluso), batteria al <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index f1d48f7..c6afad9 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"מנותקת"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"מושבת"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"‏כשל בתצורת IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"אין חיבור לרשת, כי איכות הרשת נמוכה"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"‏כשל בחיבור Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"בעיית אימות"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"לא ניתן להתחבר"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"לא ניתן להתחבר אל <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"לא יתבצע חיבור באופן אוטומטי"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"אין גישה לאינטרנט"</string>
     <string name="saved_network" msgid="7143698034077223645">"נשמר על ידי <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"יש חיבור לרשת המבוססת על חיוב לפי שימוש בנתונים"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏מחובר אוטומטית דרך %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"מחובר אוטומטית דרך ספק של דירוג רשת"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"‏מחובר דרך %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"מחוברת באמצעות <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"‏זמינה דרך %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"יש להקיש כדי להירשם"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"אין אינטרנט"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"‏לא ניתן לגשת לשרת DNS הפרטי"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"אין אינטרנט"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"נדרשת כניסה"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"נקודת הגישה מלאה באופן זמני"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"‏מחובר לרשת של %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"‏זמינה דרך %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"מתבצעת פתיחה של <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"לא ניתן היה להתחבר"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"מתבצעת השלמה של ההרשמה…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"לא ניתן היה להשלים את ההרשמה. יש להקיש כדי לנסות שוב."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"תהליך ההרשמה הסתיים. בתהליך התחברות…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"איטית מאוד"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"איטית"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"אישור"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"בינונית"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"מהירה"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"מהירה מאוד"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"התוקף פג"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"ההתאמה מתבצעת..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"מחובר (ללא טלפון)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"מחובר (ללא מדיה)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"מחובר (ללא גישה להודעות)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"מחובר (ללא טלפון או מדיה)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"מחובר, שיעור הסוללה <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"מחובר (ללא טלפון), שיעור הסוללה <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 8cfc888..43fe178 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"未接続"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"無効"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP設定エラー"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ネットワークの品質が低いため、接続されていません"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi接続エラー"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"認証に問題"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"接続できません"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"「<xliff:g id="AP_NAME">%1$s</xliff:g>」に接続できません"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"自動的に接続されません"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"インターネット接続なし"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g>により保存"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"従量制ネットワークに接続しました"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s 経由で自動的に接続しています"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ネットワーク評価プロバイダ経由で自動的に接続しています"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s経由で接続"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> で接続しました"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s経由で使用可能"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"タップして登録してください"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"インターネットに接続されていません"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"プライベート DNS サーバーにアクセスできません"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"インターネット未接続"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ログインが必要"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"アクセス ポイントが一時的にいっぱいです"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s 経由で接続済み"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s 経由で使用可能"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"「<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>」を開いています"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"接続できませんでした"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"登録を完了しています…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"登録を完了できませんでした。タップしてもう一度お試しください。"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"登録が完了しました。接続しています…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"とても遅い"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"遅い"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"普通"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"速い"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"非常に速い"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"期限切れ"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"ペアとして設定中..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"接続済み(電話なし): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"接続済み(メディアなし): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"接続済み(メッセージ アクセスなし): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"接続済み(電話、メディアなし): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"接続済み、バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"接続済み(電話なし)、バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 3cc44ce..c498b61 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"კავშირი გაწყვეტილია"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"გამორთულია"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP კონფიგურაციის შეფერხება"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"არ არის დაკავშირებული დაბალი ხარისხის ქსელის გამო"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi კავშირის შეფერხება"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"ავთენტიკაციის პრობლემა"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"დაკავშირება ვერ ხერხდება"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"<xliff:g id="AP_NAME">%1$s</xliff:g>-თან დაკავშირება ვერ ხერხდება"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ავტომატურად დაკავშირება ვერ მოხერხდება"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ინტერნეტ-კავშირი არ არის"</string>
     <string name="saved_network" msgid="7143698034077223645">"შენახული <xliff:g id="NAME">%1$s</xliff:g>-ის მიერ"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"დაკავშირებულია ფასიან ქსელთან"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"ავტომატურად დაკავშირდა %1$s-ის მეშვეობით"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ავტომატურად დაკავშირდა ქსელის ხარისხის შეფასების პროვაიდერის მეშვეობით"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s-ით დაკავშირებული"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"დაკავშირებულია <xliff:g id="NAME">%1$s</xliff:g>-ით"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"ხელმისაწვდომია %1$s-ით"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"შეეხეთ რეგისტრაციისთვის"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ინტერნეტ-კავშირი არ არის"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"პირად DNS სერვერზე წვდომა შეუძლებელია"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ინტერნეტ-კავშირი არ არის"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"აუცილებელია სისტემაში შესვლა"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"წვდომის წერტილი დროებით გადატვირთულია"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s-ით დაკავშირებული"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"ხელმისაწვდომია %1$s-ით"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"მიმდინარეობს <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>-ის გახსნა"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"დაკავშირება ვერ მოხერხდა"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"მიმდინარეობს რეგისტრაციის დასრულება…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"რეგისტრაციის დასრულება ვერ მოხერხდა. შეეხეთ ხელახლა საცდელად."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"რეგისტრაცია დასრულდა. მიმდინარეობს დაკავშირება…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"ძალიან ნელი"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"ნელი"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"კარგი"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"საშუალო"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"სწრაფი"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ძალიან სწრაფი"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ვადაგასულია"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"დაწყვილება…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"დაკავშირებულია (ტელეფონი არ არის)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"დაკავშირებულია (მედია არ არის)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"დაკავშირებულია (შეტყობინებებზე წვდომა არ არის)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"დაკავშირებულია (ტელეფონი ამ მედია არ არის)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"დაკავშირებულია. ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"დაკავშირებულია (ტელეფონი არ არის). ბატარეის დონე: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 8eb7db7..363cd0e 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Ажыратылған"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Өшірілген"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP конфигурациясының қатесі"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Желі байланысының сапасы төмен болғандықтан қосылмады"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi байланысының қатесі"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Растау мәселесі"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Қосылу мүмкін емес"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" қолданбасына қосылу мүмкін емес"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматты қосылмайды"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Интернетпен байланыс жоқ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> сақтаған"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Трафик саналатын желіге қосылды."</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s арқылы автоматты қосылды"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Желі рейтингі провайдері арқылы автоматты түрде қосылған"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s арқылы қосылған"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> арқылы жалғанған"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s арқылы қолжетімді"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Тіркелу үшін түртіңіз."</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Интернетпен байланыс жоқ"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Жеке DNS серверіне кіру мүмкін емес."</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Интернетпен байланыс жоқ"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Аккаунтқа кіру керек"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Кіру нүктесі уақытша бос емес"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s арқылы қосылды"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s арқылы қолжетімді"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ашылуда"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Жалғанбады"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Тіркелу процесі аяқталуда…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Тіркелу процесі аяқталмады. Әрекетті қайталау үшін түртіңіз."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Тіркелу процесі аяқталды. Жалғануда…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Өте баяу"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Баяу"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Жарайды"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Орташа"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Жылдам"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Өте жылдам"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мерзімі өтті"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Жұптауда..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> жалғанды (телефонсыз)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> жалғанды (аудиосыз)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> жалғанды (хабарларға кіруге рұқсат жоқ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> жалғанды (телефонсыз не аудиосыз)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Жалғанды, батарея заряды: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Жалғанды (телефонсыз), батарея заряды: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 7bfa1c4..00668fe 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"បាន​ផ្ដាច់"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"បាន​បិទ"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"ការ​កំណត់​រចនាសម្ព័ន្ធ IP បរាជ័យ"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"មិន​អាច​ភ្ជាប់​បាន​ទេ ដោយសារ​បណ្តាញ​មាន​គុណភាព​សេវា​ខ្សោយ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"ការ​ភ្ជាប់​ WiFi បរាជ័យ"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"បញ្ហា​ក្នុង​ការ​ផ្ទៀងផ្ទាត់"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"មិនអាច​ភ្ជាប់​បានទេ"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"មិនអាចភ្ជាប់ជាមួយ \'<xliff:g id="AP_NAME">%1$s</xliff:g>\' បានទេ"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"នឹងមិនភ្ជាប់ដោយស្វ័យប្រវត្តិទេ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"មិនមាន​ការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
     <string name="saved_network" msgid="7143698034077223645">"បានរក្សាទុកដោយ <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"បានភ្ជាប់ទៅ​បណ្ដាញដែលផ្អែកតាមទិន្នន័យដែលប្រើ"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"បានភ្ជាប់ដោយស្វ័យប្រវត្តិតាមរយៈ %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"បានភ្ជាប់​ដោយស្វ័យប្រវត្តិ​តាម​រយៈក្រុមហ៊ុនផ្តល់​ការ​វាយ​តម្លៃលើ​បណ្តាញ"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"បានភ្ជាប់តាមរយៈ %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"ភ្ជាប់​តាម <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"មានតាមរយៈ %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"ចុច​ដើម្បី​ចុះឈ្មោះ"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"គ្មាន​អ៊ីនធឺណិតទេ"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"មិនអាច​ចូលប្រើ​ម៉ាស៊ីនមេ DNS ឯកជន​បានទេ"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"គ្មាន​អ៊ីនធឺណិតទេ"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"តម្រូវ​ឱ្យ​ចូល​គណនី"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ចំណុចចូលប្រើពេញជាបណ្តោះអាសន្ន"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"បានភ្ជាប់តាមរយៈ %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"មានតាមរយៈ %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"កំពុង​បើក <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"មិន​អាចភ្ជាប់​បានទេ"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"កំពុង​បញ្ចប់​ការចុះឈ្មោះ…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"មិនអាច​បញ្ចប់​ការចុះឈ្មោះ​បានទេ។ សូមចុច ដើម្បី​ព្យាយាម​ម្ដង​ទៀត។"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ការចុះ​ឈ្មោះ​បានបញ្ចប់។ កំពុងភ្ជាប់…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"យឺតណាស់"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"យឺត"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"យល់ព្រម"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"មធ្យម"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"លឿន"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"លឿន​ខ្លាំង"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"បានផុតកំណត់"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"កំពុង​ផ្គូផ្គង..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"បាន​ភ្ជាប់ (គ្មាន​ទូរសព្ទ​ទេ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"បាន​ភ្ជាប់ (គ្មាន​មេឌៀ​ទេ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"បាន​ភ្ជាប់ (គ្មាន​ការ​ចូល​ប្រើ​សារ​ទេ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"បាន​ភ្ជាប់ (គ្មាន​ទូរសព្ទ ឬ​មេឌៀ​ទេ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"បានភ្ជាប់ ហើយ​ថ្ម​មាន​កម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"បាន​ភ្ជាប់ (គ្មាន​ទូរសព្ទ​ទេ) ហើយ​ថ្ម​មាន​កម្រិត <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index e77f8d4..ebf742b 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP ಕಾನ್ಫಿಗರೇಶನ್ ವಿಫಲತೆ"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ಕಡಿಮೆ ಗುಣಮಟ್ಟದ ನೆಟ್‌ವರ್ಕ್‌ನಿಂದಾಗಿ ಸಂಪರ್ಕ ಸಾಧಿಸಿಲ್ಲ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi ಸಂಪರ್ಕ ವಿಫಲತೆ"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"ಪ್ರಮಾಣೀಕರಣ ಸಮಸ್ಯೆ"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವಿಲ್ಲ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> ನಿಂದ ಉಳಿಸಲಾಗಿದೆ"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"ಮಾಪನ ಮಾಡಲಾದ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ನೆಟ್‌ವರ್ಕ್ ರೇಟಿಂಗ್ ಒದಗಿಸುವವರ ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> ಆ್ಯಪ್ ಮೂಲಕ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"ಸೈನ್ ಅಪ್ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"ಖಾಸಗಿ DNS ಸರ್ವರ್ ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ಸೈನ್ ಇನ್ ಮಾಡುವ ಅಗತ್ಯವಿದೆ"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ಪ್ರವೇಶ ಕೇಂದ್ರ ತಾತ್ಕಾಲಿಕವಾಗಿ ಭರ್ತಿಯಾಗಿದೆ"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಲಾಗುತ್ತಿದೆ"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"ಸೈನ್-ಅಪ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"ಸೈನ್-ಅಪ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ಮತ್ತೊಮ್ಮೆ ಪ್ರಯತ್ನಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ಸೈನ್-ಅಪ್ ಪೂರ್ಣಗೊಂಡಿದೆ. ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"ತುಂಬಾ ನಿಧಾನವಾಗಿದೆ"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"ನಿಧಾನ"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ಸರಿ"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"ಮಧ್ಯಮ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ವೇಗ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ತುಂಬಾ ವೇಗವಾಗಿದೆ"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ಅವಧಿ ಮುಕ್ತಾಯವಾಗಿದೆ"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"ಜೋಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಇಲ್ಲ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಮಾಧ್ಯಮವಿಲ್ಲ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ಗೆ (ಸಂದೇಶ ಪ್ರವೇಶವಿಲ್ಲ) ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಅಥವಾ ಮಾಧ್ಯಮವಿಲ್ಲ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"ಸಂಪರ್ಕಗೊಂಡಿದೆ, ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಇಲ್ಲ), ಬ್ಯಾಟರಿ ಚಾರ್ಜ್‌ ಮಟ್ಟ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index fe81cb3..21c8091 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"연결 끊김"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"사용 중지됨"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP 설정 실패"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"저품질 네트워크로 인해 연결되지 않음"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi 연결 실패"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"인증 문제"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"연결할 수 없음"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'에 연결할 수 없음"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"자동으로 연결되지 않습니다."</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"인터넷에 연결되어 있지 않음"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g>(으)로 저장됨"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"데이터 전송량 제한이 있는 네트워크에 연결됨"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s을(를) 통해 자동으로 연결됨"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"네트워크 평가 제공업체를 통해 자동으로 연결됨"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s을(를) 통해 연결됨"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g>을(를) 통해 연결됨"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s을(를) 통해 사용 가능"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"탭하여 가입"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"인터넷 연결 없음"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"비공개 DNS 서버에 액세스할 수 없습니다."</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"인터넷 연결 없음"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"로그인 필요"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"액세스 포인트가 일시적으로 가득 참"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s을(를) 통해 연결됨"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s을(를) 통해 사용 가능"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> 여는 중"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"연결할 수 없음"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"가입 완료 중…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"가입을 완료할 수 없습니다. 다시 시도하려면 탭하세요."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"가입이 완료되었습니다. 연결 중…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"매우 느림"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"느림"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"보통"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"보통"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"빠름"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"매우 빠름"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"만료됨"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"페어링 중..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"연결됨(전화 없음)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"연결됨(미디어 없음)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"연결됨(메시지 액세스 권한 없음)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"연결됨(전화 또는 미디어 없음)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"연결됨, 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"연결됨(전화 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index d5dc291..076f317a 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Ажыратылды"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Өчүрүлгөн"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP конфигурациясы бузулду"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Тармактын сапаты начар болгондуктан, туташкан жок"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi туташуусу бузулду"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Аутентификация маселеси бар"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Туташпай жатат"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" тармагына туташпай койду"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматтык түрдө туташпайт"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Интернетке туташпай турат"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> тарабынан сакталды"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Чектелген трафикке туташтырылды"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s аркылуу автоматтык түрдө туташты"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Тармактар рейтингинин булагы аркылуу автоматтык түрдө туташты"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s аркылуу жеткиликтүү"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> аркылуу туташты"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s аркылуу жеткиликтүү"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Катталуу үчүн таптап коюңуз"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Интернет жок"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Жеке DNS сервери жеткиликсиз"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Интернет жок"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Аккаунтка кирүү талап кылынат"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Байланыш түйүнүнө өтө көп түзмөк туташып турат"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s аркылуу туташты"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s аркылуу иштейт"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ачылууда"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Туташпай койду"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Катталуу аяктоодо…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Катталуу аягына чыккан жок. Кайра аракет кылуу үчүн таптап коюңуз."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Катталуу аягына чыкты. Туташууда…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Өтө жай"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Жай"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Жарайт"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Орто"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Ылдам"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Абдан ылдам"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Эскирип калган"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Туташууда…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Туташып турат (телефониясыз)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Туташып турат (медиасыз)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Туташып турат (SMS/MMS жазышуусуз)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Туташып турат (телефониясыз же медиасыз)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Туташып турат, батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Туташып турат (телефониясыз), батареянын деңгээли – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 578017c..9ebe67a 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"ປິດການນຳໃຊ້"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"ການ​ຕັ້ງ​ຄ່າ IP ລົ້ມ​ເຫຼວ"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ບໍ່ໄດ້ເຊື່ອມຕໍ່ເນື່ອງຈາກຄຸນນະພາບເຄືອຂ່າຍຕໍ່າ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"​ການ​ເຊື່ອມ​ຕໍ່ WiFi ລົ້ມ​ເຫຼວ"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"ບັນຫາການພິສູດຢືນຢັນ"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາ \'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ໄດ້"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ຈະບໍ່ເຊື່ອມຕໍ່ອັດຕະໂນມັດ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
     <string name="saved_network" msgid="7143698034077223645">"ບັນທຶກ​​​ໂດຍ <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍທີ່ມີການວັດແທກແລ້ວ"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"ເຊື່ອມຕໍ່ຜ່ານທາງ %1$s ໂດຍອັດຕະໂນມັດ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ເຊື່ອມຕໍ່ກັບອັດຕະໂນມັດແລ້ວຜ່ານຜູ້ໃຫ້ບໍລິການຄະແນນເຄືອຂ່າຍ"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"​ເຊື່ອມຕໍ່​ຜ່ານ %1$s ​ແລ້ວ"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"ເຊື່ອມ​ຕໍ່​ຜ່ານ <xliff:g id="NAME">%1$s</xliff:g> ແລ້ວ"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"ມີ​ໃຫ້​ຜ່ານ %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"ແຕະເພື່ອສະໝັກ"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ບໍ່ມີອິນເຕີເນັດ"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"ບໍ່ສາມາດເຂົ້າເຖິງເຊີບເວີ DNS ສ່ວນຕົວໄດ້"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ບໍ່ມີອິນເຕີເນັດ"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ຈຳເປັນຕ້ອງເຂົ້າສູ່ລະບົບ"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ຈຸດການເຂົ້າເຖິງເຕັມຊົ່ວຄາວ"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"ເຊື່ອມຕໍ່ຜ່ານ %1$s ແລ້ວ"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"ໃຊ້ໄດ້ຜ່ານ %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"ກຳລັງເປີດ <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"ກຳລັງສຳເລັດການສະໝັກ…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"ບໍ່ສາມາດສຳເລັດການສະໝັກໄດ້. ແຕະເພື່ອລອງໃໝ່."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ສະໝັກສຳເລັດແລ້ວ. ກຳລັງເຊື່ອມຕໍ່…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"ຊ້າຫຼາຍ"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"ຊ້າ"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ຕົກລົງ"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"ປານກາງ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ໄວ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ໄວຫຼາຍ"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ໝົດອາຍຸແລ້ວ"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"ກຳລັງຈັບຄູ່..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີມີເດຍ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີສິດເຂົ້າອ່ານຂໍ້ຄວາມ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ ຫຼື ມີເດຍ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"ເຊື່ອມຕໍ່ແລ້ວ, ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ), ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index a2be901..fcea778 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Neprisijungta"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Neleidžiama"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP konfigūracijos triktis"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Neprisijungta dėl žemos kokybės tinklo"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"„Wi-Fi“ ryšio triktis"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Autentifikavimo problema"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nepavyksta prisijungti"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Nepavyksta prisijungti prie „<xliff:g id="AP_NAME">%1$s</xliff:g>“"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nebus automatiškai prisijungiama"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nėra interneto ryšio"</string>
     <string name="saved_network" msgid="7143698034077223645">"Išsaugojo <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Prisijungta prie matuojamo tinklo"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatiškai prisijungta naudojant „%1$s“"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatiškai prisijungta naudojant tinklo įvertinimo paslaugos teikėjo paslaugomis"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Prisijungta naudojant „%1$s“"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Prisijungta naudojant programą „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Pasiekiama naudojant „%1$s“"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Palieskite, kad prisiregistruotumėte"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nėra interneto ryšio"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Privataus DNS serverio negalima pasiekti"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nėra interneto ryšio"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Reikia prisijungti"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Prieigos taškas laikinai visiškai užimtas"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Prisijungta naudojant „%1$s“"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Pasiekiama naudojant „%1$s“"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Atidaroma: „<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>“"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Nepavyko prisijungti"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Baigiamas prisiregistravimas…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Nepavyko užbaigti prisiregistravimo. Jei norite bandyti dar kartą, palieskite."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Prisiregistravimas baigtas. Prijungiama…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Labai lėtas"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lėtas"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Gerai"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Vidutinis"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Greitas"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Labai greitas"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Baigėsi galiojimo laikas"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Susiejama..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Prisijungta (<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>), (telefono nėra)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Prisijungta (<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>), (medijos nėra)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Prisij. (<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>), (prieigos prie praneš. nėra)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Prisijungta (<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>), (telef. ar medijos nėra)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Prisijungta (<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>), akumuliatoriaus įkrovos lygis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Prisijungta (<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>), (telefono nėra), akumuliatoriaus įkrovos lygis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index d09617b..c280737 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Savienojums pārtraukts"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Atspējots"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP konfigurācijas kļūme"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Savienojums nav izveidots zemas kvalitātes tīkla dēļ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi savienojuma kļūme"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Autentificēšanas problēma"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nevar izveidot savienojumu"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Nevar izveidot savienojumu ar tīklu <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Savienojums netiks izveidots automātiski"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nav piekļuves internetam"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saglabāja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Izveidots savienojums ar maksas tīklu"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automātiski savienots, izmantojot %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automātiski izveidots savienojums, izmantojot tīkla vērtējuma sniedzēju"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Savienots, izmantojot %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Savienojums ar <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Pieejams, izmantojot %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Pieskarieties, lai reģistrētos"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nav interneta"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Nevar piekļūt privātam DNS serverim."</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nav piekļuves internetam"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Nepieciešama pierakstīšanās"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Piekļuves punkts īslaicīgi ir pilns"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Savienojums izveidots, izmantojot %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Pieejams, izmantojot %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Notiek lietotnes <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> atvēršana."</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Nevarēja izveidot savienojumu"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Notiek reģistrācijas pabeigšana…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Nevarēja pabeigt reģistrāciju. Pieskarieties, lai mēģinātu vēlreiz."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Reģistrācija ir pabeigta. Notiek savienojuma izveide…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Ļoti lēns"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lēns"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Labi"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Vidējs"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Ātrs"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Ļoti ātrs"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Beidzies derīguma termiņš"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Notiek pāra izveide..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Savienojums izveidots (nav tālrunis): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Savienojums izveidots (nav multivide): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Savienots (nav piekļuves ziņojumiem): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Savienots (nav tālrunis vai multivide): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Savienojums izveidots (<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Savienojums izveidots <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (nav tālrunis), akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 7dc9174..f849900 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Не е поврзано"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Оневозможено"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Конфигурирањето ИП не успеа"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Не е поврзано поради нискиот квалитет на мрежата"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Поврзувањето преку Wi-Fi не успеа"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Проблем со автентикација"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Не може да се поврзе"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Не може да се поврзе на „<xliff:g id="AP_NAME">%1$s</xliff:g>“"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Не може да се поврзе автоматски"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Нема пристап до интернет"</string>
     <string name="saved_network" msgid="7143698034077223645">"Зачувано од <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Поврзано на мрежа со ограничен интернет"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматски поврзано преку %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматски поврзано преку оценувач на мрежа"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Поврзано преку %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Поврзано преку <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Достапно преку %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Допрете за да се регистрирате"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Нема интернет"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Не може да се пристапи до приватниот DNS-сервер"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Нема интернет"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Потребно е најавување"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Пристапната точка привремено е преоптоварена"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Поврзано преку %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Достапно преку %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Се отвора <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Не може да се поврзе"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Се завршува регистрацијата…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Не може да се заврши регистрацијата. Допрете за да се обидете повторно."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Регистрацијата е завршена. Се поврзува…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Многу бавна"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Бавна"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Во ред"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Средна"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Брза"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Многу брза"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Истечено"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Се спарува..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без телефон)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без аудиовизуелни содржини)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без пристап до пораките)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без телефон и аудиовизуел.)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>, ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (без телефон), ниво на батеријата <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index bae251a..cc15e03 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"വിച്ഛേദിച്ചു"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP കോൺഫിഗറേഷൻ പരാജയം"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"മോശം നെറ്റ്‌വർക്ക് ‌ആയതിനാൽ കണക്‌റ്റായില്ല"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi കണക്ഷൻ പരാജയം"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"ആധികാരികമാക്കുന്നതിലെ പ്രശ്‌നം"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"കണക്റ്റുചെയ്യാനാകുന്നില്ല"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' എന്നതിലേക്ക് കണക്‌റ്റുചെയ്യാനാകുന്നില്ല"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"സ്വയമേവ കണക്‌റ്റുചെയ്യില്ല"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> സംരക്ഷിച്ചത്"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"മീറ്റർ ചെയ്ത നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റ് ചെയ്തു"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s വഴി സ്വയമേവ ബന്ധിപ്പിച്ചു"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"നെറ്റ്‌വർക്ക് റേറ്റിംഗ് ദാതാവുമായി സ്വയം കണക്‌റ്റുചെയ്‌തു"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> മുഖേന കണക്‌റ്റ് ചെയ്‌തു"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s വഴി ലഭ്യം"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"സൈൻ അപ്പ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ഇന്റർനെറ്റ് ഇല്ല"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"സ്വകാര്യ DNS സെർവർ ആക്‌സസ് ചെയ്യാനാവില്ല"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ഇന്റർനെറ്റ് ഇല്ല"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"സൈൻ ഇൻ ചെയ്യേണ്ടത് ആവശ്യമാണ്"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ആക്‌സസ് പോയിന്റ് താൽക്കാലികമായി നിറഞ്ഞിരിക്കുന്നു"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s വഴി ലഭ്യം"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> തുറക്കുന്നു"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"കണക്റ്റ് ചെയ്യാനായില്ല"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"സൈൻ അപ്പ് പൂർത്തിയാക്കുന്നു…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"സൈൻ അപ്പ് പൂർത്തിയാക്കാനായില്ല. വീണ്ടും ശ്രമിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"സൈൻ അപ്പ് പൂർത്തിയായി. കണക്റ്റ് ചെയ്യുന്നു…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"വളരെ കുറഞ്ഞ വേഗത്തിൽ"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"കുറഞ്ഞ വേഗത്തിൽ"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ശരി"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"ഇടത്തരം"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"വേഗത്തിൽ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"അതിവേഗം"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"കാലഹരണപ്പെട്ടത്"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"ജോടിയാക്കുന്നു…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"കണ‌ക്റ്റ് ചെ‌യ്‌തു (ഫോൺ ഇല്ല)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"കണക്റ്റ് ചെയ്‌തു (മീഡിയ ഇല്ല)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"കണ‌ക്റ്റ് ചെയ്‌തു (സന്ദേശ ആക്‌സസ് ഇല്ല)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"കണ‌ക്റ്റ് ചെയ്‌തു (ഫോണോ മീഡിയയോ ഇല്ല)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"കണക്റ്റ് ചെയ്‌തു, ബാറ്ററി <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"കണ‌ക്റ്റ് ചെയ്‌തു (ഫോൺ ഇല്ല), ബാറ്ററി നില <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 890f2c4..3701a30 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Салсан"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Идэвхгүйжүүлсэн"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP тохируулга амжилтгүй"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Сүлжээний чанар муу байгаа тул холбогдож чадсангүй"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi холболт амжилтгүй"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Баталгаажуулалтын асуудал"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Холбогдож чадсангүй"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'-д холбогдож чадсангүй"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматаар холбогдохгүй"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Интернет хандалт алга"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> хадгалсан"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Хязгаартай сүлжээнд холбогдсон"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s-р автоматаар холбогдсон"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Сүлжээний үнэлгээ үзүүлэгчээр автоматаар холбогдох"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s-р холбогдсон"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g>-р холбогдсон"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s-р боломжтой"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Бүртгүүлэхийн тулд товшино уу"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Интернэт алга"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Хувийн DNS серверт хандах боломжгүй байна"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Интернэт алга"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Нэвтрэх шаардлагатай"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Хандах цэг түр хугацаанд дүүрсэн байна"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s-р холбогдсон"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s-р боломжтой"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>-г нээж байна"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Холбогдож чадсангүй"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Бүртгэлийг дуусгаж байна…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Бүртгэлийг дуусгаж чадсангүй. Дахин оролдохын тулд товшино уу."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Бүртгүүлж дууслаа. Холбогдож байна…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Маш удаан"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Удаан"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ЗА"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Дунд"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Хурдан"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Маш хурдан"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Хугацаа дууссан"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Хослуулж байна…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Холбогдсон (утас байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Холбогдсон (медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Холбогдсон (мессежийн хандалт байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Холбогдсон (утас эсвэл медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index e87422d..3fffc1a 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"डिस्कनेक्ट केले"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"अक्षम"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP कॉंफिगरेशन अयशस्वी"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"कमी दर्जाच्या नेटवर्कमुळे कनेक्ट केलेले नाही"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi कनेक्शन अयशस्वी"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"प्रमाणीकरण समस्या"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"कनेक्ट करू शकत नाही"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'शी कनेक्‍ट करू शकत नाही"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"स्वयंचलितपणे कनेक्ट करणार नाही"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"इंटरनेट अ‍ॅक्सेस नाही"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे सेव्ह केले"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"मर्यादित नेटवर्कशी कनेक्ट केले आहे"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s द्वारे स्वयंचलितपणे कनेक्ट केले"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"नेटवर्क रेटिंग प्रदात्याद्वारे स्वयंचलितपणे कनेक्ट केले"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s द्वारे कनेक्‍ट केले"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे कनेक्ट केले"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s द्वारे उपलब्‍ध"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"साइन अप करण्यासाठी टॅप करा"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"इंटरनेट नाही"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"खाजगी DNS सर्व्हर ॲक्सेस करू शकत नाही"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"इंटरनेट नाही"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"साइन इन करणे आवश्यक आहे"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"अ‍ॅक्सेस पॉइंट तात्पुरते भरलेले"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s ने कनेक्‍ट केले"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s ने उपलब्‍ध"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> उघडत आहे"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"कनेक्ट करता आले नाही"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"साइन अप पूर्ण होत आहे…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"साइन अप पूर्ण करता आले नाही. पुन्हा प्रयत्न करण्यासाठी टॅप करा."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"साइन अप पूर्ण झाले. कनेक्ट करत आहे…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"खूप हळू"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"हळू"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ठीक आहे"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"मध्‍यम"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"जलद"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"खूप जलद"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"मुदत संपली"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"पेअर करत आहे…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"कनेक्ट केले (फोन नाही)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"कनेक्ट केले (मीडिया नाही)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"कनेक्ट केले (मेसेज अ‍ॅक्सेस नाही)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"कनेक्ट केले (फोन किंवा मीडिया नाही)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"कनेक्ट केले, बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"कनेक्ट केले (फोन नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index e99de6e..79553c0 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Diputuskan sambungan"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Dinyahdayakan"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Kegagalan Konfigurasi IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Tidak disambungkan kerana rangkaian berkualiti rendah"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Kegagalan Sambungan WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Masalah pengesahan"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Tidak dapat bersambung"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Tidak dapat bersambung ke \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Tidak akan menyambung secara automatik"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Tiada akses Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Diselamatkan oleh <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Disambungkan kepada rangkaian bermeter"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Disambungkan secara automatik melalui %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Disambungkan secara automatik melalui pembekal penilaian rangkaian"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Disambungkan melalui %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Disambungkan melalui <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Tersedia melalui %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Ketik untuk daftar"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Tiada Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Pelayan DNS peribadi tidak boleh diakses"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Tiada Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Log masuk diperlukan"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Titik akses penuh buat sementara waktu"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Disambungkan melalui %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Tersedia melalui %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Membuka <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Tidak dapat menyambung"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Menyelesaikan pendaftaran…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Tidak dapat menyelesaikan pendaftaran. Ketik untuk mencuba lagi."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Pendaftaran selesai. Menyambung…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Sangat Perlahan"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Perlahan"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Sederhana"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Laju"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Sangat Laju"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Tamat tempoh"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Menggandingkan..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Disambungkan (tiada telefon)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Disambungkan (tiada media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Disambungkan (tiada akses mesej)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Disambungkan (tiada telefon atau media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Disambungkan, bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Disambungkan (tiada telefon), bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index fcdd028..fc38626 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"ချိတ်ဆက်မထားပါ"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"ပိတ်ထားသည်"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP ပြုပြင်ခြင်း မအောင်မြင်ပါ"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ကွန်ရက်ချိတ်ဆက်မှု အားနည်းသည့်အတွက် ချိတ်ဆက်ထားခြင်း မရှိပါ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi ချိတ်ဆက်မှု မအောင်မြင်ပါ"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"အထောက်အထားစိစစ်မှု ပြဿနာ"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"ချိတ်ဆက်၍ မရပါ"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' နှင့် ချိတ်ဆက်၍ မရပါ"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"အလိုအလျောက်ချိတ်ဆက်မည်မဟုတ်ပါ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"အင်တာနက် ချိတ်ဆက်မှု မရှိပါ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> က သိမ်းဆည်းခဲ့သည်"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"အခမဲ့မဟုတ်သော ကွန်ရက်သို့ ချိတ်ဆက်ထားသည်"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s မှတစ်ဆင့် အလိုအလျောက် ချိတ်ဆက်ထားပါသည်"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ကွန်ရက်အဆင့်သတ်မှတ်ပေးသူ မှတစ်ဆင့် အလိုအလျောက် ချိတ်ဆက်ထားပါသည်"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s မှတစ်ဆင့်ရနိုင်သည်"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"အကောင့်ဖွင့်ရန် တို့ပါ"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"အင်တာနက် မရှိပါ"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"သီးသန့် ဒီအန်အက်စ် (DNS) ဆာဗာကို သုံး၍မရပါ။"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"အင်တာနက် မရှိပါ"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"လက်မှတ်ထိုးဝင်ရန် လိုအပ်သည်"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ကွန်ရက်ချိတ်ဆက်မှု ယာယီပြည့်နေသည်"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s မှတစ်ဆင့် ရနိုင်သည်"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ကို ဖွင့်နေသည်"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"ချိတ်ဆက်၍ မရပါ"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"အကောင့်ဖွင့်ခြင်း အပြီးသတ်နေသည်…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"အကောင့်ဖွင့်ခြင်း အပြီးသတ်၍ မရပါ။ ပြန်စမ်းကြည့်ရန် တို့ပါ။"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"အကောင့်ဖွင့်ခြင်း ပြီးပါပြီ။ ချိတ်ဆက်နေသည်…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"အလွန်နှေး"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"နှေး"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"အတော်အသင့်"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"မြန်"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"အလွန်မြန်"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"သက်တမ်းကုန်သွားပါပြီ"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"တွဲချိတ်နေသည်…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ချိတ်ဆက်ပြီးပြီ (ဖုန်းမရှိပါ)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ချိတ်ဆက်ပြီးပြီ (မီဒီယာ မရှိပါ)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ချိတ်ဆက်ပြီးပြီ (မက်ဆေ့ဂျ် သုံး၍မရပါ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ချိတ်ပြီးပြီ (ဖုန်း (သို့) မီဒီယာ မရှိပါ)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"ချိတ်ဆက်ပြီးပြီ၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"ချိတ်ဆက်ပြီးပြီ (ဖုန်းမရှိပါ)၊ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 0490623..3d1e98d 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Frakoblet"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Slått av"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-konfigurasjonsfeil"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Ikke tilkoblet på grunn av nettverk av lav kvalitet"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi-tilkoblingsfeil"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Autentiseringsproblem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Kan ikke koble til"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Kan ikke koble til «<xliff:g id="AP_NAME">%1$s</xliff:g>»"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Kobler ikke til automatisk"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ingen internettilgang"</string>
     <string name="saved_network" msgid="7143698034077223645">"Lagret av <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Koble til et nettverk med datamåling"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatisk tilkoblet via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatisk tilkoblet via leverandør av nettverksvurdering"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Tilkoblet via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Tilkoblet via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Tilgjengelig via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Trykk for å registrere deg"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Ingen internettilkobling"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Den private DNS-tjeneren kan ikke nås"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Ingen internettilkobling"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Pålogging kreves"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Tilgangspunktet er midlertidig fullt"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Tilkoblet via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Tilgjengelig via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Åpner <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Kunne ikke koble til"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Fullfører registreringen …"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Kunne ikke fullføre registreringen. Trykk for å prøve på nytt."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registreringen er fullført. Kobler til …"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Veldig treg"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Treg"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Ok"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Middels"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rask"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Veldig rask"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Utløpt"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Kobler til …"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Koblet til (ingen telefon) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Koblet til (ingen medier) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Koblet til (ingen meldingstilgang) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Koblet til (ingen telefon eller medier) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Koblet til, batteri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Koblet til (ingen telefon), batteri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 87cb123..777c897 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"डिस्कनेक्ट गरिएको छ"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"असक्षम पारियो"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP विन्यास असफल"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"कम गुणस्तरको नेटवर्कका कारण जडान गर्न सकिएन"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"वाईफाई जडान असफल"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"प्रमाणीकरण समस्या"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"जडान गर्न सकिँदैन"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' मा जडान गर्न सकिँदैन"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"स्वतः जडान हुने छैन"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"इन्टरनेटमाथिको पहुँच छैन"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा सेभ गरियो"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"प्रयोगसम्बन्धी सीमा तोकिएको नेटवर्कमा कनेक्ट गरियो"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s मार्फत् स्वतः जडान गरिएको"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"नेटवर्क मूल्याङ्कनकर्ता मार्फत स्वत: जडान गरिएको"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s मार्फत जडित"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> मार्फत जडान गरिएको"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s मार्फत उपलब्ध"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"साइन अप गर्न ट्याप गर्नुहोस्"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"इन्टरनेट छैन"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"निजी DNS सर्भरमाथि पहुँच प्राप्त गर्न सकिँदैन"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"इन्टरनेटमाथिको पहुँच छैन"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"साइन इन गर्न आवश्यक छ"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"पहुँचसम्बन्धी स्थान अस्थायी रूपमा भरिएको छ"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s मार्फत जडान गरियो"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s मार्फत उपलब्ध"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> खोल्दै"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"जडान गर्न सकिएन"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"साइन अप गर्ने कार्य सम्पन्न गर्दै…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"साइन अप गर्ने कार्य सम्पन्न गर्न सकिएन। फेरि प्रयास गर्न ट्याप गर्नुहोस्।"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"साइन अप गर्ने कार्य सम्पन्न भयो। जडान गर्दै…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"धेरै ढिलो"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"बिस्तारै"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ठिक छ"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"मध्यम"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"छिटो"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"धेरै छिटो"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"म्याद सकियो"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"कनेक्ट गरिँदै छ..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"जडान गरियो (फोनबाहेेक) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"जडान गरियो (मिडियाबाहेक) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"जडान गरियो (सन्देशमाथि पहुँच छैन) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"जडान गरियो (फोन वा मिडियाबाहेक) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"जडान गरियो, ब्याट्री <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"जडान गरियो (फोनबाहेेक), ब्याट्री <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 6693735..d30a21f 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Verbinding verbroken"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Uitgezet"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-configuratie mislukt"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Niet verbonden wegens netwerk van lage kwaliteit"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wifi-verbinding mislukt"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Authenticatieprobleem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Kan geen verbinding maken"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Kan geen verbinding maken met \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Er wordt niet automatisch verbinding gemaakt"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Geen internettoegang"</string>
     <string name="saved_network" msgid="7143698034077223645">"Opgeslagen door \'<xliff:g id="NAME">%1$s</xliff:g>\'"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Verbonden met netwerk met datalimiet"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatisch verbonden via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatisch verbonden via provider van netwerkbeoordelingen"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Verbonden via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Verbonden via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Beschikbaar via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tik om aan te melden"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Geen internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Geen toegang tot privé-DNS-server"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Geen internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Inloggen vereist"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Toegangspunt tijdelijk vol"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Verbonden via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Beschikbaar via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> wordt geopend"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Kan geen verbinding maken"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Aanmelding voltooien…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Kan aanmelding niet voltooien. Tik om het opnieuw te proberen."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Aanmelding voltooid. Verbinden…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Zeer langzaam"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Langzaam"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Redelijk"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Gemiddeld"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Snel"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Zeer snel"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Verlopen"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Koppelen..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Verbonden: <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (geen telefoon)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Verbonden: <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (geen media)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Verbonden: <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (geen berichtentoegang)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Verbonden: <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (geen telefoon of media)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Verbonden: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>, batterij: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Verbonden: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (geen telefoon), batterij: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 94afb93..0120768 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"ବିଛିନ୍ନ କରାଯାଇଛି"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"ଅକ୍ଷମ ହୋଇଛି"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP କନଫିଗରେଶନ ବିଫଳ ହୋଇଛି"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ନିମ୍ନ ମାନର ନେଟ୍‌ୱର୍କ କାରଣରୁ ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"ୱାଇଫାଇ ସଂଯୋଗ ବିଫଳ ହୋଇଛି"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"ପ୍ରମାଣୀକରଣରେ ସମସ୍ୟା"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"ସଂଯୋଗ କରିପାରିବ ନାହିଁ"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ସହିତ ସଂଯୁକ୍ତ ହୋଇପାରୁନାହିଁ"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ସ୍ୱଚାଳିତ ଭାବେ ସଂଯୁକ୍ତ ହେବନାହିଁ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ଇଣ୍ଟରନେଟ୍‌ର କୌଣସି ଆକ୍‌ସେସ୍‌ ନାହିଁ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> ଦ୍ୱାରା ସେଭ କରାଯାଇଛି"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"ମିଟରଯୁକ୍ତ ନେଟୱାର୍କ ସହ ସଂଯୋଗ କରାଯାଇଛି"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲୀ ସଂଯୁକ୍ତ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ନେଟୱର୍କ ମୂଲ୍ୟାୟନ ପ୍ରଦାତାଙ୍କ ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲ୍ୟ ସଂଯୁକ୍ତ"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> ଦ୍ବାରା ସଂଯୋଗ କରାଯାଇଛି"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"ସାଇନ୍ ଅପ୍ ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"ବ୍ୟକ୍ତିଗତ DNS ସର୍ଭର୍ ଆକ୍ସେସ୍ କରିହେବ ନାହିଁ"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"କୌଣସି ଇଣ୍ଟରନେଟ୍‌ ନାହିଁ"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ସାଇନ୍-ଇନ୍ ଆବଶ୍ୟକ"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ଆକ୍ସେସ୍ ପଏଣ୍ଟ ସାମୟିକ ଭାବେ ପୂର୍ଣ୍ଣ"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ଖୋଲୁଛି"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"ସଂଯୋଗ କରିହେଲା ନାହିଁ"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"ସାଇନ୍ ଅପ୍ ଶେଷ ହେଉଛି…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"ସାଇନ୍ ଅପ୍ ଶେଷ ହୋଇପାରିଲା ନାହିଁ। ପୁଣି ଥରେ ଚେଷ୍ଟା କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ସାଇନ୍ ଅପ୍ ଶେଷ ହୋଇଛି। ସଂଯୋଗ କରୁଛି…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"ବହୁତ ମନ୍ଥର"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"କମ୍‌ ବେଗ"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ଠିକ୍‌ ଅଛି"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"ମଧ୍ୟମ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ଦ୍ରୁତ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ଅତି ଦ୍ରୁତ"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ମିଆଦ ଶେଷ ହୋଇଯାଇଛି"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"ପେୟାର୍‌ କରୁଛି…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"ସଂଯୁକ୍ତ ହେଲା (ଫୋନ୍ ନୁହେଁ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"ସଂଯୁକ୍ତ ହେଲା (ମିଡିଆ ନୁହେଁ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"ସଂଯୁକ୍ତ ହେଲା (ମେସେଜ୍ ଆକ୍ସେସ୍ ନାହିଁ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"ସଂଯୁକ୍ତ ହେଲା (ଫୋନ୍ କିମ୍ବା ମେଡିଆ ନୁହେଁ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"ସଂଯୁକ୍ତ ହେଲା, ବ୍ୟାଟେରୀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"ସଂଯୁକ୍ତ ନାହିଁ (ଫୋନ୍ ନୁହେଁ), ବ୍ୟାଟେରୀ<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 7bab52f..1481767 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"ਡਿਸਕਨੈਕਟ ਹੋਇਆ"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"ਅਯੋਗ ਬਣਾਇਆ"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP ਕੌਂਫਿਗਰੇਸ਼ਨ ਅਸਫਲਤਾ"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ਘੱਟ ਗੁਣਵੱਤਾ ਵਾਲੇ ਨੈੱਟਵਰਕ ਕਾਰਨ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi ਕਨੈਕਸ਼ਨ ਅਸਫਲਤਾ"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"ਪ੍ਰਮਾਣੀਕਰਨ ਸਮੱਸਿਆ"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> ਵੱਲੋਂ ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"ਮੀਟਰਬੱਧ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s ਰਾਹੀਂ ਆਪਣੇ-ਆਪ ਕਨੈਕਟ ਹੋਇਆ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ਨੈੱਟਵਰਕ ਰੇਟਿੰਗ ਪ੍ਰਦਾਨਕ ਰਾਹੀਂ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਹੋਇਆ"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"ਸਾਈਨ-ਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ਇੰਟਰਨੈੱਟ ਨਹੀਂ"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"ਨਿੱਜੀ ਡੋਮੇਨ ਨਾਮ ਪ੍ਰਣਾਲੀ (DNS) ਸਰਵਰ \'ਤੇ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ਇੰਟਰਨੈੱਟ ਨਹੀਂ"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ਸਾਈਨ-ਇਨ ਲੋੜੀਂਦਾ ਹੈ"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ਐਕਸੈੱਸ ਪੁਆਇੰਟ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਸੰਪੂਰਨ ਰੁਝੇਂਵੇਂ ਵਿੱਚ ਹੈ"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"ਸਾਈਨ-ਅੱਪ ਮੁਕੰਮਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"ਸਾਈਨ-ਅੱਪ ਮੁਕੰਮਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ਸਾਈਨ-ਅੱਪ ਮੁਕੰਮਲ ਹੋਇਆ ਕਨੈਕਟ ਹੋ ਰਿਹਾ ਹੈ…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"ਬਹੁਤ ਹੌਲੀ"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"ਹੌਲੀ"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ਠੀਕ ਹੈ"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"ਔਸਤ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ਤੇਜ਼"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ਬਹੁਤ ਤੇਜ਼"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ਮਿਆਦ ਮੁੱਕ ਗਈ"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"ਜੋੜਾਬੱਧ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ (ਕੋਈ ਫ਼ੋਨ ਨਹੀਂ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ (ਕੋਈ ਮੀਡੀਆ ਨਹੀਂ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ (ਸੁਨੇਹੇ \'ਤੇ ਪਹੁੰਚ ਨਹੀਂ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ (ਕੋਈ ਫ਼ੋਨ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ, ਬੈਟਰੀ ਦਾ ਪੱਧਰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ (ਕੋਈ ਫ਼ੋਨ ਨਹੀਂ), ਬੈਟਰੀ ਦਾ ਪੱਧਰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 1384d5b..83f8e49 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Rozłączono"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Wyłączona"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Błąd konfiguracji IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Brak połączenia z powodu słabego sygnału sieci"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Błąd połączenia Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem z uwierzytelnianiem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nie można się połączyć"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Nie można się połączyć z siecią „<xliff:g id="AP_NAME">%1$s</xliff:g>”"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nie można połączyć automatycznie"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Brak dostępu do internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Zapisane przez: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Połączono z siecią z pomiarem użycia danych"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatycznie połączono przez: %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatycznie połączono przez dostawcę ocen jakości sieci"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Połączono przez %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Połączenie przez: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Dostępne przez %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Kliknij, by się zarejestrować"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Brak internetu"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Brak dostępu do prywatnego serwera DNS"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Brak internetu"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Musisz się zalogować"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Punkt dostępu jest tymczasowo zajęty"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Połączono przez: %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Dostępna przez: %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Otwieram: <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Nie udało się połączyć"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Kończę rejestrować…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Nie udało się dokończyć rejestracji. Kliknij, by spróbować ponownie."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Rejestracja zakończona. Łączę…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Bardzo wolna"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Wolna"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Średnia"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Szybka"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Bardzo szybka"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Ważność wygasła"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Paruję…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Połączono (bez telefonu) – <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Połączono (bez multimediów) – <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Połączono (bez dostępu do wiadomości) – <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Połączono (bez telefonu i multimediów) – <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Połączono, bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> – <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Połączono (bez telefonu), bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> – <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 36675ae..d9a7c69 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Desconectada"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Desativado"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Falha de configuração de IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Não conectado devido à baixa qualidade da rede"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Falha de conexão Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema de autenticação"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Não é possível estabelecer conexão"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Não é possível conectar-se a \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Não se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Sem acesso à Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salva por <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Conectado a uma rede limitada"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectado automaticamente via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectado automaticamente via provedor de avaliação de rede"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Conectado via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponível via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Toque para se inscrever"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Sem Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Não é possível acessar o servidor DNS privado"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Sem Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"É necessário fazer login"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Ponto de acesso temporariamente cheio"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Conectado via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponível via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Abrindo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Não foi possível conectar"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Concluindo inscrição…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Inscrição concluída. Conectando…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Muito lenta"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lenta"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Ok"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Pareando…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Conectado (sem telefone) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Conectado (sem mídia) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Conectado (sem acesso a mensagens) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Conectado (sem telefone ou mídia) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Conectado, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> de bateria"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Conectado (sem telefone), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> de bateria"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index f5a9625..c24589c 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Desligada"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Desativado"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Falha de configuração de IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Não ligado devido à baixa qualidade da rede"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Falha de ligação Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema de autenticação"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Não é possível ligar"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Não é possível ligar a \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Não é efetuada uma ligação automaticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Sem acesso à Internet."</string>
     <string name="saved_network" msgid="7143698034077223645">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Ligação estabelecida a uma rede de acesso limitado."</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Ligado automaticamente através de %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ligado automaticamente através do fornecedor de classificação de rede"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Ligado através de %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Ligado via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponível através de %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Toque para se inscrever"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Sem Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Não é possível aceder ao servidor DNS."</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Sem Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"É necessário iniciar sessão"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Ponto de acesso temporariamente cheio"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Ligado através de %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponível através de %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"A abrir <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Não foi possível estabelecer ligação"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"A concluir a inscrição…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Inscrição concluída. A ligar…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Muito lenta"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lenta"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"A sincronizar..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Ligado (sem telemóvel)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Ligado (sem multimédia)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Ligado (sem acesso a mensagens)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Ligado (sem telemóvel nem multimédia)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Ligado, bateria a <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Ligado (sem telemóvel), bateria a <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 36675ae..d9a7c69 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Desconectada"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Desativado"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Falha de configuração de IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Não conectado devido à baixa qualidade da rede"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Falha de conexão Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema de autenticação"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Não é possível estabelecer conexão"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Não é possível conectar-se a \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Não se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Sem acesso à Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salva por <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Conectado a uma rede limitada"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectado automaticamente via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectado automaticamente via provedor de avaliação de rede"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Conectado via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponível via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Toque para se inscrever"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Sem Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Não é possível acessar o servidor DNS privado"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Sem Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"É necessário fazer login"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Ponto de acesso temporariamente cheio"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Conectado via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponível via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Abrindo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Não foi possível conectar"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Concluindo inscrição…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Inscrição concluída. Conectando…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Muito lenta"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lenta"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Ok"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Pareando…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Conectado (sem telefone) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Conectado (sem mídia) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Conectado (sem acesso a mensagens) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Conectado (sem telefone ou mídia) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Conectado, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> de bateria"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Conectado (sem telefone), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> de bateria"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 8b6259c..8fb09ac 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Deconectat"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Dezactivată"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Eroare de configurație IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nu există conexiune din cauza rețelei de calitate slabă"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Eroare de conexiune Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problemă la autentificare"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nu se poate conecta"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Nu se poate conecta la „<xliff:g id="AP_NAME">%1$s</xliff:g>”"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nu se va conecta automat"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nu există acces la internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salvată de <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"S-a conectat la o rețea contorizată"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectată automat prin %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectată automat prin furnizor de evaluări ale rețelei"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectată prin %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Conectat prin <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Disponibilă prin %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Atinge pentru a te înscrie"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Fără conexiune la internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Serverul DNS privat nu poate fi accesat"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Fără conexiune la internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Trebuie să te conectezi"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Punctul de acces este temporar plin"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Conectată prin %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Disponibilă prin %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Se deschide <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Nu s-a putut conecta"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Se finalizează înscrierea…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Nu s-a putut finaliza înscrierea. Atinge pentru a încerca din nou."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Înscrierea a fost finalizată. Se conectează…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Foarte lentă"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Lentă"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Bine"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Medie"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rapidă"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Foarte rapidă"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirat"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Se asociază…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Conectat (fără telefon) la <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Conectat (fără conținut media) la <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Conectat (fără acces la mesaje) la <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Conectat (fără telefon sau media) la <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Conectat, baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Conectat (fără telefon), baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 12a5fcc..704d848 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Не подключено"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Отключено"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Ошибка IP-конфигурации"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Подключение невозможно из-за низкого качества сети"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Ошибка подключения Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Ошибка аутентификации"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Ошибка подключения"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Не удалось подключиться к сети \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Подключение не будет выполняться автоматически"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Без доступа к Интернету"</string>
     <string name="saved_network" msgid="7143698034077223645">"Сохранено: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Подключено к сети с ограниченным трафиком"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматически подключено к %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматически подключено через автора рейтинга сетей"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Подключено к %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Подключено через приложение \"<xliff:g id="NAME">%1$s</xliff:g>\"."</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Доступно через %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Нажмите, чтобы зарегистрироваться"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Нет подключения к Интернету"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Доступа к частному DNS-серверу нет."</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Нет подключения к Интернету"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Требуется выполнить вход."</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"К точке доступа подключено слишком много устройств"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Подключено к %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Доступно через %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Открытие <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>…"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Не удалось подключиться."</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Завершение регистрации…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Не удалось завершить регистрацию. Нажмите, чтобы повторить попытку."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Регистрация завершена. Подключение…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Очень медленная"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Медленная"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ОК"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Средняя"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Быстрая"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Очень быстрая"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Срок действия истек"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Устанавливается соединение..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Подключено (кроме звонков)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Подключено (кроме аудио)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Подключено (кроме сообщений)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Подключено (кроме звонков и аудио)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Подключено, уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Подключено (кроме звонков), уровень заряда батареи: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 8abc51a..d67060e 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"විසන්ධි විය"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"අබලයි"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP වින්‍යාස කිරීම අසාර්ථකයි"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"අඩු ගුණත්වයේ ජාලය හේතුවෙන් සම්බන්ධ නොවීය"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi සම්බන්ධතාව අසාර්ථකයි"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"සත්‍යාපනයේ ගැටලුවකි"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"සම්බන්ධ විය නොහැකිය"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' වෙත සම්බන්ධ විය නොහැකිය"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ස්වයංක්‍රිය නැවත සම්බන්ධ නොවනු ඇත"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"අන්තර්ජාල ප්‍රවේශය නැත"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> විසින් සුරකින ලදී"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"මනුගත ජාලයට සම්බන්ධ කර ඇත"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s හරහා ස්වයංක්‍රියව සම්බන්ධ විය"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ජාල ශ්‍රේණිගත සපයන්නා හරහා ස්වයංක්‍රියව සම්බන්ධ විය"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s හරහා සම්බන්ධ විය"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> හරහා සම්බන්ධයි"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"ලියාපදිංචි වීමට තට්ටු කරන්න"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"අන්තර්ජාලය නැත"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"පුද්ගලික DNS සේවාදායකයට ප්‍රවේශ වීමට නොහැකිය"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"අන්තර්ජාලය නැත"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"පිරීම අවශ්‍යයි"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ප්‍රවේශ ලක්ෂ්‍ය තාවකාලිකව පිරී ඇත"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s හරහා සම්බන්ධ විය"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> විවෘත කරමින්"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"සබැඳීමට නොහැකි විය"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"ලියාපදිංචිය සම්පූර්ණ කරමින්…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"ලියාපදිංචිය සම්පූර්ණ කළ නොහැකි විය. නැවත උත්සාහ කිරීමට තට්ටු කරන්න."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ලියාපදිංචිය සම්පූර්ණයි. සබැඳෙමින්…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"ඉතා මන්දගාමී"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"මන්දගාමී"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"හරි"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"මධ්‍යම"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"වේගවත්"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ඉතා වේගවත්"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"කල් ඉකුත් විය"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"යුගල කරමින්…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"සම්බන්ධිතයි (දුරකථනය නැත) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"සම්බන්ධිතයි (මාධ්‍ය නැත)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"සම්බන්ධිතයි (පණිවිඩ ප්‍රවේශය නැත)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"සම්බන්ධිතයි (දුරකථනය හෝ මාධ්‍ය නැත) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"සම්බන්ධිතයි, බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"සම්බන්ධිතයි (දුරකථනය නැත), බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 3a8e078..1982893 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Odpojené"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Vypnuté"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Zlyhanie konfigurácie adresy IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nepripojené z dôvodu siete nízkej kvality"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Zlyhanie pripojenia Wi‑Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problém s overením"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nedá sa pripojiť"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"K sieti <xliff:g id="AP_NAME">%1$s</xliff:g> sa nedá pripojiť"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nedôjde k automatickému pripojeniu"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Žiadny prístup k internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Uložila aplikácia <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Pripojené k meranej sieti"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automaticky pripojené prostredníctvom %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automaticky pripojené prostredníctvom poskytovateľa hodnotenia siete"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Pripojené prostredníctvom %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Pripojené prostredníctvom siete <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"K dispozícii prostredníctvom %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Prihláste sa klepnutím"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Bez internetu"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"K súkromnému serveru DNS sa nepodarilo získať prístup"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Žiadny internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Vyžaduje sa prihlásenie"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Prístupový bod je dočasne plný"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Pripojené prostredníctvom operátora %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"K dispozícii prostredníctvom operátora %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Otvára sa <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Nepodarilo sa pripojiť"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Dokončuje sa registrácia…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Registráciu sa nepodarilo dokončiť. Klepnutím to skúste znova."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registrácia je dokončená. Pripája sa…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Veľmi pomalá"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Pomalá"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Stredná"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rýchla"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Veľmi rýchla"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vypršalo"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Páruje sa..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Pripojené k zariadeniu <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (bez telefónu)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Pripojené k zariadeniu <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (bez médií)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Pripojené k <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (bez prístupu k správam)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Pripojené k <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (bez telefónu a médií)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Pripojené k zariadeniu <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>, úroveň batérie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Pripojené k zariadeniu <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (bez telefónu), úroveň batérie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 9f1aecb..262ecfd 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Ni povezave"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Onemogočeno"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Konfiguracija IP-ja ni uspela"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Ni povezano zaradi slabe kakovosti omrežja"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Povezava prek Wi-Fi-ja ni uspela"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Težava s preverjanjem pristnosti"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Povezava ni mogoča"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Povezava z aplikacijo »<xliff:g id="AP_NAME">%1$s</xliff:g>« ni mogoča"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Samodejna vnovična vzpostavitev povezave se ne bo izvedla"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ni dostopa do interneta"</string>
     <string name="saved_network" msgid="7143698034077223645">"Shranil(-a): <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Povezano z omrežjem z omejenim prenosom podatkov"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Samodejno vzpostavljena povezava prek: %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Samodejno vzpostavljena povezava prek ponudnika ocenjevanja omrežij"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Vzpostavljena povezava prek: %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Povezava vzpostavljena prek omrežja <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Na voljo prek: %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Dotaknite se, če se želite registrirati"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Ni internetne povezave"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Do zasebnega strežnika DNS ni mogoče dostopati"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Brez internetne povezave"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Zahtevana je prijava"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Dostopna točka je trenutno zasedena"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Vzpostavljena povezava prek: %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Na voljo prek: %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Odpiranje ponudnika <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Povezave ni bilo mogoče vzpostaviti"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Dokončevanje registracije …"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Registracije ni bilo mogoče dokončati. Če želite poskusiti znova, se dotaknite."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registracija je končana. Povezovanje …"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Zelo počasna"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Počasna"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"V redu"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Srednje hitra"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Hitra"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Zelo hitra"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Poteklo"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Seznanjanje ..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Povezano (brez telefona) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Povezano (brez predstavnosti) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Povezano (brez dostopa do sporočil) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Povezano (brez telefona/predstavnosti) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Povezano, raven napolnjenosti baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Povezano (brez telefona), raven napolnjenosti baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 515f963..d0f1f7c 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Shkëputur"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Të çaktivizuara"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Dështim në konfigurimin e IP-së"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Nuk është lidhur për shkak të rrjetit me cilësi të dobët"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Dështim i lidhjes WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problem me vërtetimin"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Nuk mund të lidhet"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Nuk mund të lidhet me \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nuk do të lidhet automatikisht"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nuk ka qasje në internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"E ruajtur nga <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Lidhur me një rrjet me matje"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Lidhur automatikisht përmes %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Lidhur automatikisht nëpërmjet ofruesit të vlerësimit të rrjetit"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"E lidhur përmes %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Lidhur përmes <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"E mundshme përmes %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Trokit për t\'u regjistruar"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Nuk ka internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Serveri privat DNS nuk mund të qaset"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Nuk ka internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Kërkohet identifikimi"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Pika e qasjes është përkohësisht plot"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"E lidhur përmes %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"E disponueshme përmes %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Po hapet <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Nuk mund të lidhej"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Po përfundon regjistrimin…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Regjistrimi nuk mund të përfundonte. Trokit për të provuar përsëri."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Regjistrimi përfundoi. Po lidhet…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Shumë e ulët"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"E ngadaltë"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Në rregull"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Mesatare"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"E shpejtë"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Shumë e shpejtë"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Skaduar"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Po çiftohet..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"E lidhur (pa telefon)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"E lidhur (pa media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"E lidhur (nuk ka qasje te mesazhet)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"E lidhur (pa telefon ose media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"E lidhur, bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"E lidhur (pa telefon), bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 61496ae..b102d3a 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Веза је прекинута"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Онемогућено"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP конфигурација је отказала"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Није повезано због лошег квалитета мреже"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi веза је отказала"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Проблем са потврдом идентитета"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Повезивање није успело"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Повезивање са „<xliff:g id="AP_NAME">%1$s</xliff:g>“ није успело"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Аутоматско повезивање није успело"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Нема приступа интернету"</string>
     <string name="saved_network" msgid="7143698034077223645">"Сачувао/ла је <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Повезани сте на мрежу са ограничењем"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Аутоматски повезано преко %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Аутоматски повезано преко добављача оцене мреже"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Веза је успостављена преко приступне тачке %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Повезано преко: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Доступна је преко приступне тачке %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Додирните да бисте се регистровали"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Нема интернета"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Приступ приватном DNS серверу није успео"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Нема интернета"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Треба да се пријавите"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Приступна тачка је привремено заузета"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Повезано преко %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Доступно преко %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Отвара се <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Повезивање није успело"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Регистрација се довршава…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Довршавање регистрације није успело. Додирните да бисте пробали поново."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Регистрација је довршена. Повезује се…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Веома спора"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Спора"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Потврди"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Средња"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Брза"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Веома брза"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Истекло"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Упаривање..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Повезано (без телефона): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Повезано (без медија): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Повезано је (без приступа порукама): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Повезано (без телефона или медија): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Повезано, ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Повезано (без телефона), ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 943ba5f6..8c12372 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Frånkopplad"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Inaktiverad"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP-konfigurationsfel"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Ingen anslutning på grund av låg kvalitet på nätverket"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wifi-anslutningsfel"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Autentiseringsproblem"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Det gick inte att ansluta"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Det gick inte att ansluta till <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Det går inte att ansluta automatiskt"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ingen internetåtkomst"</string>
     <string name="saved_network" msgid="7143698034077223645">"Sparades av <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Ansluten till nätverk med datapriser"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatiskt ansluten via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatiskt ansluten via leverantör av nätverksbetyg"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Anslutet via %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Anslutet via <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Tillgängligt via %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Tryck för att logga in"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Inget internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Det går inte att komma åt den privata DNS-servern."</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Inget internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Inloggning krävs"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Åtkomstpunkten har inga platser över för tillfället"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Anslutet via %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Tillgängligt via %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Öppnar <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Det gick inte att ansluta"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Registreringen slutförs …"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Det gick inte att slutföra registreringen. Tryck för att försöka igen."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registrering slutförd. Ansluter …"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Mycket långsam"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Långsam"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Okej"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Medelsnabb"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Snabb"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Mycket snabb"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Har upphört att gälla"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Parkoppling…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Ansluten (ingen mobil)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Ansluten (inga medier)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Ansluten (ingen meddelandeåtkomst)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Ansluten (ingen mobil och inga medier) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Ansluten, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Ansluten (ingen mobil), batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index b7124a63..72a3751 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Hujaunganishwa"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Imezimwa"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Haikuweza Kusanidi IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Haijaunganishwa kwa sababu intaneti si thabiti"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Haikuweza Kuunganisha kwenye WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Tatizo la uthibitishaji"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Imeshindwa kuunganisha"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Imeshindwa kuunganisha kwenye \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Haiwezi kuunganisha kiotomatiki"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Hakuna muunganisho wa intaneti"</string>
     <string name="saved_network" msgid="7143698034077223645">"Ilihifadhiwa na <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Imeunganishwa kwenye mtandao unaopima data"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Imeunganishwa kiotomatiki kupitia %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Imeunganishwa kiotomatiki kupitia mtoa huduma wa ukadiriaji wa mtandao"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Imeunganishwa kupitia %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Imeunganishwa kupitia <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Inapatikana kupitia %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Gusa ili ujisajili"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Hakuna intaneti"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Seva ya faragha ya DNS haiwezi kufikiwa"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Hakuna intaneti"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Unahitaji kuingia katika akaunti"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Lango la mtandao lina shughuli nyingi kwa sasa"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Imeunganishwa kupitia %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Inapatikana kupitia %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Inafungua <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Imeshindwa kuunganisha"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Inakamilisha usajili…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Imeshindwa kukamilisha usajili. Gusa ili ujaribu tena."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Imekamilisha kusajili. Inaunganisha…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Polepole Sana"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Polepole"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Sawa"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Wastani"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Haraka"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Haraka Sana"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Muda umeisha"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Inaoanisha..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Imeunganishwa (hamna simu)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Imeunganishwa (hamna kifaa cha sauti)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Imeunganishwa (haifikii ujumbe)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Imeunganishwa (hamna simu au kifaa cha sauti)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Imeunganishwa, kiasi cha chaji ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Imeunganishwa (hamna simu), kiasi cha chaji ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 5b3aae3..8714958 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"தொடர்பு துண்டிக்கப்பட்டது"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"முடக்கப்பட்டது"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP உள்ளமைவில் தோல்வி"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"தரம் குறைவான நெட்வொர்க்கின் காரணமாக, இணைக்கப்படவில்லை"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"வைஃபை இணைப்பில் தோல்வி"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"அங்கீகரிப்புச் சிக்கல்"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"இணைக்க முடியவில்லை"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' உடன் இணைக்க முடியவில்லை"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"தானாக இணைக்கப்படாது"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"இண்டர்நெட் அணுகல் இல்லை"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> சேமித்தது"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"கட்டண நெட்வொர்க்குடன் இணைக்கப்பட்டுள்ளது"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s மூலம் தானாக இணைக்கப்பட்டது"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"நெட்வொர்க் மதிப்பீடு வழங்குநரால் தானாக இணைக்கப்பட்டது"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s வழியாக இணைக்கப்பட்டது"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> மூலம் இணைக்கப்பட்டது"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s வழியாகக் கிடைக்கிறது"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"பதிவு செய்யத் தட்டவும்"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"இணைய இணைப்பு இல்லை"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"தனிப்பட்ட DNS சேவையகத்தை அணுக இயலாது"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"இணைய இணைப்பு இல்லை"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"உள்நுழைய வேண்டும்"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"தற்காலிகமாக அணுகல் புள்ளி நிரம்பியுள்ளது"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s வழியாக இணைக்கப்பட்டது"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s வழியாகக் கிடைக்கிறது"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> திறக்கப்படுகிறது"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"இணைக்க முடியவில்லை"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"பதிவு செய்வது நிறைவடைகிறது…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"பதிவு செய்வதை நிறைவுசெய்ய இயலவில்லை மீண்டும் முயற்சிக்கத் தட்டவும்."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"பதிவு செய்வது நிறைவடைந்தது. இணைக்கிறது…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"மிகவும் வேகம் குறைவானது"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"வேகம் குறைவு"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"சரி"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"நடுத்தரம்"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"வேகம்"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"மிகவும் வேகமானது"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"காலாவதியாகிவிட்டது"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"இணைக்கிறது..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> இணைக்கப்பட்டது (மொபைல் இல்லை)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> இணைக்கப்பட்டது (மீடியா இல்லை)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> இணைக்கப்பட்டது (செய்தி அணுகல் இல்லை)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> இணைக்கப்பட்டது (மொபைல்/மீடியா இல்லை)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"இணைக்கப்பட்டது, பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"இணைக்கப்பட்டது (மொபைல் இல்லை), பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index df9b0ef..e35bd76 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"డిస్‌కనెక్ట్ అయ్యింది"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"డిజేబుల్ చేయబడింది"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP కాన్ఫిగరేషన్ వైఫల్యం"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"తక్కువ క్వాలిటీ నెట్‌వర్క్ కారణంగా కనెక్ట్ చేయబడలేదు"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi కనెక్షన్ వైఫల్యం"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"ప్రామాణీకరణ సమస్య"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"కనెక్ట్ చేయడం సాధ్యపడదు"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'కు కనెక్ట్ చేయడం సాధ్యపడదు"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ఆటోమేటిక్‌గా కనెక్ట్ కాదు"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> ద్వారా సేవ్ చేయబడింది"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"డేటా నియంత్రణ నెట్‌వర్క్‌కు కనెక్ట్ చేయబడింది"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s ద్వారా ఆటోమేటిక్‌గా కనెక్ట్ చేయబడింది"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"నెట్‌వర్క్ రేటింగ్ ప్రదాత ద్వారా ఆటోమేటిక్‌గా కనెక్ట్ చేయబడింది"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> ద్వారా కనెక్ట్ చేయబడింది"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"సైన్ అప్ చేయడానికి నొక్కండి"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ఇంటర్నెట్ లేదు"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"ప్రైవేట్ DNS సర్వర్‌ను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ఇంటర్నెట్ లేదు"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"సైన్ ఇన్ చేయాలి"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"యాక్సెస్ పాయింట్ తాత్కాలికంగా నిండుకుంది"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> తెరవబడుతోంది"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"సైన్ అప్ పూర్తివుతోంది…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"సైన్ అప్‌ను పూర్తి చేయడం సాధ్య పడలేదు. మళ్లీ ప్రయత్నించడానికి నొక్కండి."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"సైన్ అప్ పూర్తయింది. కనెక్ట్ చేయబడుతోంది…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"చాలా నెమ్మది"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"నెమ్మది"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"సరే"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"మధ్యస్థం"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"వేగవంతం"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"చాలా వేగవంతం"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"గడువు ముగిసింది"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"పెయిరింగ్..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"కనెక్ట్ చేయబడింది (ఫోన్ కాదు)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"కనెక్ట్ చేయబడింది (మీడియా కాదు)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"కనెక్ట్ చేయబడింది (సందేశ యాక్సెస్ లేదు)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"కనెక్ట్ చేయబడింది (ఫోన్ లేదా మీడియా కాదు)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"కనెక్ట్ చేయబడింది, బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"కనెక్ట్ చేయబడింది (ఫోన్ కాదు), బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index a8744fa..f386e5d 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"ยกเลิกการเชื่อมต่อแล้ว"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"ปิดอยู่"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"การกำหนดค่า IP ล้มเหลว"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ไม่ได้เชื่อมต่อเนื่องจากเครือข่ายคุณภาพต่ำ"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"การเชื่อมต่อ Wi-Fi ล้มเหลว"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"ปัญหาในการตรวจสอบสิทธิ์"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"ไม่สามารถเชื่อมต่อ"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"ไม่สามารถเชื่อมต่อกับ \"<xliff:g id="AP_NAME">%1$s</xliff:g>\""</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"จะไม่เชื่อมต่อโดยอัตโนมัติ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"เข้าถึงอินเทอร์เน็ตไม่ได้"</string>
     <string name="saved_network" msgid="7143698034077223645">"บันทึกโดย<xliff:g id="NAME">%1$s</xliff:g> แล้ว"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"เชื่อมต่อกับเครือข่ายแบบจำกัดปริมาณแล้ว"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"เชื่อมต่ออัตโนมัติผ่าน %1$s แล้ว"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"เชื่อมต่ออัตโนมัติผ่านผู้ให้บริการการจัดอันดับเครือข่าย"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"เชื่อมต่อแล้วผ่าน <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"พร้อมใช้งานผ่านทาง %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"แตะเพื่อลงชื่อสมัครใช้"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"ไม่มีอินเทอร์เน็ต"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"เข้าถึงเซิร์ฟเวอร์ DNS ไม่ได้"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ไม่มีอินเทอร์เน็ต"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ต้องลงชื่อเข้าใช้"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"จุดเข้าใช้งานเต็มชั่วคราว"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"พร้อมใช้งานผ่านทาง %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"กำลังเปิด <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"เชื่อมต่อไม่ได้"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"กำลังลงชื่อสมัครใช้ให้เสร็จสิ้น…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"ลงชื่อสมัครใช้ให้เสร็จสิ้นไม่ได้ แตะเพื่อลองอีกครั้ง"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"การลงชื่อสมัครใช้เสร็จสมบูรณ์ กำลังเชื่อมต่อ…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"ช้ามาก"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"ช้า"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ตกลง"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"ปานกลาง"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"เร็ว"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"เร็วมาก"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"หมดอายุแล้ว"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"กำลังจับคู่อุปกรณ์..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"เชื่อมต่อแล้ว (ไม่รวมโทรศัพท์)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"เชื่อมต่อแล้ว (ไม่รวมสื่อ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"เชื่อมต่อแล้ว (ไม่มีการเข้าถึงข้อความ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"เชื่อมต่อแล้ว (ไม่รวมโทรศัพท์หรือสื่อ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"เชื่อมต่อแล้ว แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"เชื่อมต่อแล้ว (ไม่รวมโทรศัพท์) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index bdcdbac..db27382 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Nadiskonekta"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Naka-disable"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Pagkabigo ng Configuration ng IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Hindi nakakonekta dahil mababa ang kalidad ng network"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Pagkabigo ng Koneksyon sa WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Problema sa pag-authenticate"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Hindi makakonekta"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Hindi makakonekta sa \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Hindi awtomatikong kokonekta"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Walang access sa internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Na-save ng <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Nakakonekta sa nakametrong network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Awtomatikong nakakonekta sa pamamagitan ng %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Awtomatikong nakakonekta sa pamamagitan ng provider ng rating ng network"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Nakakonekta sa pamamagitan ng %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Nakakonekta sa pamamagitan ng <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Available sa pamamagitan ng %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"I-tap para mag-sign up"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Walang internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Hindi ma-access ang pribadong DNS server"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Walang internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Kinakailangang mag-sign in"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Pansamantalang puno ang access point"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Nakakonekta sa pamamagitan ng %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Available sa pamamagitan ng %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Binubuksan ang <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Hindi makakonekta"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Kinukumpleto ang pag-sign up…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Hindi makumpleto ang pag-sign up. I-tap para subukang muli."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Kumpleto na ang pag-sign up. Kumokonekta…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Napakabagal"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Mabagal"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Katamtaman"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Mabilis"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Napakabilis"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Nag-expire na"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Pinapares…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Nakakonekta (walang telepono)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Nakakonekta (walang media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Nakakonekta (walang access sa mensahe)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Nakakonekta (walang telepono o media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Nakakonekta, baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Nakakonekta (walang telepono), baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index de88c2c..8f4bae4 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Bağlı değil"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Devre dışı"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP Yapılandırması Hatası"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Ağ kalitesi düşük olduğundan bağlanamadı"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Kablosuz Bağlantı Hatası"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Kimlik doğrulama sorunu"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Bağlanılamıyor"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" ağına bağlanılamıyor"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Otomatik olarak bağlanma"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"İnternet erişimi yok"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> tarafından kaydedildi"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Sayaçlı ağa bağlı"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s üzerinden otomatik olarak bağlı"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ağ derecelendirme sağlayıcı aracılığıyla otomatik olarak bağlandı"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s üzerinden bağlı"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> ile bağlandı"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s üzerinden kullanılabilir"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Kaydolmak için dokunun"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"İnternet yok"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Gizli DNS sunucusuna erişilemiyor"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"İnternet yok"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Oturum açılması gerekiyor"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Erişim noktası geçici olarak dolu"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s üzerinden bağlı"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s üzerinden kullanılabilir"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> açılıyor"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Bağlanılamadı"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Kayıt işlemi tamamlanıyor…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Kayıt işlemi tamamlanamadı. Tekrar denemek için dokunun."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Kayıt tamamlandı. Bağlanıyor…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Çok Yavaş"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Yavaş"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Tamam"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Orta"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Hızlı"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Çok Hızlı"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Süresi sona erdi"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Eşleniyor…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> cihazına bağlandı (telefon yok)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> cihazına bağlandı (medya yok)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> cihazına bağlandı (mesaj erişimi yok)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> cihazına bağlandı (telefon veya medya yok)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> cihazına bağlandı, pil <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> cihazına bağlandı (telefon yok), pil <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index a438741..a0c68c1 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Від’єднано"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Вимкнено"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Помилка конфігурації IP-адреси"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Не під’єднано через низьку якість мережі"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Помилка з’єднання Wi-Fi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Проблема з автентифікацією"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Не вдається під’єднатись"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Не вдається під’єднатися до мережі <xliff:g id="AP_NAME">%1$s</xliff:g>"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Не під’єднуватиметься автоматично"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Немає доступу до Інтернету"</string>
     <string name="saved_network" msgid="7143698034077223645">"Збережено додатком <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Установлено з\'єднання з мережею з тарифікацією трафіку"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматично під’єднано через %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматично під’єднано через постачальника оцінки якості мережі"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Під’єднано через %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Підключено через додаток <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Доступ через %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Торкніться, щоб увійти"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Немає Інтернету"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Немає доступу до приватного DNS-сервера"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Немає Інтернету"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Потрібно ввійти в обліковий запис"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Точка доступу тимчасово переповнена"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Під’єднано через мережу %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Доступ через мережу %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> відкривається"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Не вдалося підключитись"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Завершення реєстрації…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Не вдалося завершити реєстрацію. Торкніться, щоб повторити спробу."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Реєстрацію завершено. Підключення…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Дуже повільна"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Повільна"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ОК"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Середня"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Швидка"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Дуже швидка"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Термін дії минув"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Підключення…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> під’єднано (без телефона)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> під’єдно (без медіа)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> під’єднано (без доступу до повідомлень)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> під’єднано (без телефона й медіа)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> під’єднано, заряд акумулятора – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> під’єднано (без телефона), заряд акумулятора – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 2e409ba..d0a1204 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"غیر منسلک"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"غیر فعال"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"‏IP کنفیگریشن کی ناکامی"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"کم معیاری نیٹ ورک کی وجہ سے منسلک نہیں ہے"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"‏WiFi کنکشن کی ناکامی"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"توثیق کا مسئلہ"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"منسلک نہیں ہو سکتا ہے"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' سے منسلک نہیں ہو سکتا ہے"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"خودکار طور پر منسلک نہیں ہو گا"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"انٹرنیٹ تک کوئی رسائی نہیں"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> کی جانب سے محفوظ کردہ"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"میٹرڈ نیٹ ورک سے منسلک ہے"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏‎%1$s کے ذریعے از خود منسلک کردہ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"نیٹ ورک درجہ بندی کے فراہم کنندہ کے ذریعے از خود منسلک"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"‏منسلک بذریعہ ‎%1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> کے ذریعے منسلک"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"‏دستیاب بذریعہ ‎%1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"سائن اپ کے لیے تھپتھپائیں"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"انٹرنیٹ نہیں ہے"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"‏نجی DNS سرور تک رسائی حاصل نہیں کی جا سکی"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"انٹرنیٹ نہیں ہے"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"سائن ان درکار ہے"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"رسائی پوائنٹ عارضی طور پر فُل ہے"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"‏منسلک بذریعہ ‎%1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"‏دستیاب بذریعہ ‎%1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> کھل رہا ہے"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"منسلک نہیں کیا جا سکا"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"سائن اپ مکمل ہو رہا ہے…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"سائن اپ مکمل نہیں ہو سکا۔ دوبارہ کوشش کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"سائن اپ مکمل ہو گیا۔ منسلک ہو رہا ہے…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"بہت سست"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"سست"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"ٹھیک ہے"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"متوسط"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"تیز"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"بہت تیز"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"میعاد ختم ہو گئی"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"جوڑا بنایا جا رہا ہے…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"منسلک ہے (فون کے علاوہ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"منسلک ہے (میڈیا کے علاوہ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"منسلک ہے (پیغام تک رسائی نہیں ہے)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"منسلک ہے (فون یا میڈیا کے علاوہ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"منسلک ہو گیا، بٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"منسلک ہے (فون کے علاوہ)، بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index eeec101..1738e01 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Ulanmagan"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Yoqilmagan"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP manzilini sozlab bo‘lmadi"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Sifatsiz tarmoq sababli ulanib bo‘lmadi"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Wi-Fi ulanishini o‘rnatib bo‘lmadi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Tekshiruvda muammo"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Tarmoqqa ulanilmadi"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"“<xliff:g id="AP_NAME">%1$s</xliff:g>” nomli tarmoqqa ulanilmadi"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Avtomatik ravishda ulanilmaydi"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Internet aloqasi yo‘q"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saqlangan: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Trafik hisoblanadigan tarmoqqa ulandi"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s orqali avtomatik ulandi"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Tarmoqlar reytingi muallifi orqali avtomatik ulandi"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s orqali ulangan"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> orqali ulandi"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s orqali ishlaydi"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Yozilish uchun bosing"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Internetga ulanmagansiz"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Xususiy DNS server ishlamayapti"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Internet yo‘q"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Hisob bilan kirish zarur"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Internet kirish nuqtasi vaqtinchalik to‘lgan"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"%1$s orqali ulangan"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"%1$s orqali ishlaydi"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ochilmoqda"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Ulanmadi"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Registratsiya tamomlanmoqda…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Registratsiya tamomlanmadi. Qayta urinish uchun tegining."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Registratsiya qilindi. Ulanmoqda…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Juda sekin"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Sekin"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"OK"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"O‘rtacha"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Tez"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Juda tez"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Muddati tugagan"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Juftlanmoqda…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ulandi (telefondan tashqari)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ulandi (mediadan tashqari)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ulandi (xabarlarga ruxsatsiz)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ulandi (telefon yoki mediadan tashqari)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi, batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"<xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> ulandi (telefondan tashqari), batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index fc11dec..f7f4c0e 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Đã ngắt kết nối"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Đã tắt"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Lỗi cấu hình IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Không được kết nối do mạng chất lượng kém"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Lỗi kết nối WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Sự cố xác thực"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Không thể kết nối"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Không thể kết nối với \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Sẽ không tự động kết nối"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Không có quyền truy cập Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Do <xliff:g id="NAME">%1$s</xliff:g> lưu"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Đã kết nối với mạng có đo lượng dữ liệu"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Tự động được kết nối qua %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Tự động được kết nối qua nhà cung cấp dịch vụ xếp hạng mạng"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Được kết nối qua %1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Đã kết nối qua <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Có sẵn qua %1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Nhấn để đăng ký"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Không có Internet"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Không thể truy cập máy chủ DNS riêng tư"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Không có Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Yêu cầu đăng nhập"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Điểm truy cập tạm thời đã đạt đến giới hạn số lượng thiết bị truy cập."</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Được kết nối qua %1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Có sẵn qua %1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Đang mở <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Không thể kết nối"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Đang hoàn tất đăng ký…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Không thể hoàn tất đăng ký. Nhấn để thử lại."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Đã hoàn tất đăng ký. Đang kết nối…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Rất chậm"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Chậm"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"Khá tốt"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Trung bình"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Nhanh"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Rất nhanh"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Đã hết hạn"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Đang ghép nối…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Đã kết nối (không có điện thoại) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Đã kết nối (không có phương tiện) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Đã kết nối (không có quyền truy cập tin nhắn) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Đã kết nối (không có điện thoại hoặc phương tiện) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Đã kết nối, mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Đã kết nối (không có điện thoại), mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index a4fa1d9..f536bb9 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"已断开连接"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"已停用"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP 配置失败"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"网络质量较差,因此未连接"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WLAN 连接失败"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"身份验证出现问题"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"无法连接"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"无法连接到“<xliff:g id="AP_NAME">%1$s</xliff:g>”"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"无法自动连接"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"无法访问互联网"</string>
     <string name="saved_network" msgid="7143698034077223645">"由“<xliff:g id="NAME">%1$s</xliff:g>”保存"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"已连接到按流量计费的网络"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"已通过%1$s自动连接"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"已自动连接(通过网络评分服务提供方)"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"已通过%1$s连接"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"已通过<xliff:g id="NAME">%1$s</xliff:g>连接到网络"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"可通过%1$s连接"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"点按即可注册"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"无法访问互联网"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"无法访问私人 DNS 服务器"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"无法访问互联网"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"必须登录"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"接入点暂时满载"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"已通过%1$s连接"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"可通过%1$s连接"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"正在打开<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"无法连接"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"正在完成注册…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"无法完成注册。点按即可重试。"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"注册完毕。正在连接…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"很慢"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"慢"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"良好"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"适中"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"快"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"很快"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已失效"</string>
@@ -98,14 +89,13 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"正在配对..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"已连接(无手机信号)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"已连接(无媒体信号)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"已连接(无消息访问权限)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"已连接(无手机或媒体信号)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"已连接,电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"已连接(无手机信号),电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"已连接(无媒体信号),电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"已连接(无手机或媒体信号),电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"使用中,电池电量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"已启用,左:目前电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>;右:目前电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
+    <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"使用中,左:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> 电量,右:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> 电量"</string>
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 的电量"</string>
     <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"左:目前电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>;右:目前电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 369fe52..357302b 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"已中斷連線"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"已停用"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP 設定失敗"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"網絡品質欠佳,因此無法連線"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi 連線失敗"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"驗證問題"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"無法連線"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"無法連線至「<xliff:g id="AP_NAME">%1$s</xliff:g>」"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"不會自動連線"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"無法連接互聯網"</string>
     <string name="saved_network" msgid="7143698034077223645">"由「<xliff:g id="NAME">%1$s</xliff:g>」儲存"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"已連結至按用量收費的網絡"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"已透過 %1$s 自動連線"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"已透過網絡評分供應商自動連線"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"已透過 %1$s 連線"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"已透過「<xliff:g id="NAME">%1$s</xliff:g>」連線"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"可透過 %1$s 連線"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"輕按即可登入"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"沒有互聯網連線"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"無法存取私人 DNS 伺服器"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"沒有互聯網連線"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"必須登入"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"存取點暫時已滿"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"已透過 %1$s 連線"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"可透過 %1$s 連線"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"正在開啟 <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"無法連接"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"正在完成申請…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"無法完成申請。輕按即可重試。"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"已完成申請。連接中…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"非常慢"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"慢"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"良好"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"適中"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"快"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"非常快"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已過期"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"正在配對..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"已連接「<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>」(無手機音訊)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"已連接「<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>」(無媒體音訊)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"已連接「<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>」(無訊息存取權)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"已連接「<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>」(無手機或媒體音訊)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"已連接,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"已連接 (無手機音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 8219811..4ae28304 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"已中斷連線"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"已停用"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP 設定失敗"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"網路品質不佳,因此未連線"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"WiFi 連線失敗"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"驗證問題"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"無法連線"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"無法連線至「<xliff:g id="AP_NAME">%1$s</xliff:g>」"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"無法自動連線"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"沒有可用的網際網路連線"</string>
     <string name="saved_network" msgid="7143698034077223645">"由「<xliff:g id="NAME">%1$s</xliff:g>」儲存"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"已連線到計量付費網路"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"已透過 %1$s 自動連線"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"已透過網路評分供應商自動連線"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"已透過 %1$s 連線"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"透過「<xliff:g id="NAME">%1$s</xliff:g>」連線"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"可透過 %1$s 使用"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"輕觸即可註冊"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"沒有網際網路連線"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"無法存取私人 DNS 伺服器"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"沒有網際網路連線"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"必須登入"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"存取點暫時滿載"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"已透過 %1$s 連線"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"可透過 %1$s 使用"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"正在開啟 <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"無法連線"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"正在完成註冊程序…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"無法完成註冊程序。輕觸即可重試。"</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"註冊完成。連線中…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"非常慢"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"慢"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"確定"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"適中"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"快"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"非常快"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已失效"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"配對中…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"已連線到「<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>」(無手機音訊)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"已連線到「<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>」(無媒體音訊)"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"已連線到「<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>」(無訊息存取權)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"已連線到「<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>」(無手機或媒體音訊)"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"已連線,電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"已連線 (無手機音訊),電量為 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 6ca4cc5..c113dc8 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -53,8 +53,6 @@
     <string name="wifi_disconnected" msgid="7054450256284661757">"Inqamukile"</string>
     <string name="wifi_disabled_generic" msgid="2651916945380294607">"Akusebenzi"</string>
     <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Ukwehluleka kokulungiswa kwe-IP"</string>
-    <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Ayixhunyiwe ngenxa yenethiwekhi yekhwalithi ephansi"</string>
-    <string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"Ukwehlulekla koxhumo le-WiFi"</string>
     <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Inkinga yokufakazela ubuqiniso"</string>
     <string name="wifi_cant_connect" msgid="5718417542623056783">"Ayikwazi ukuxhuma"</string>
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"Ayikwazi ukuxhumeka ku-\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
@@ -63,12 +61,9 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Ngeke ize ixhumeke ngokuzenzakalela"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Akukho ukufinyelela kwe-inthanethi"</string>
     <string name="saved_network" msgid="7143698034077223645">"Kulondolozwe ngu-<xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Kuxhunywe kunethiwekhi eyenziwe imitha"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Ixhumeke ngokuzenzakalela nge-%1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Kuxhunywe ngokuzenzakalelayo ngomhlinzeki wesilinganiso wenethiwekhi"</string>
-    <string name="connected_via_passpoint" msgid="7735442932429075684">"Kuxhumeke nge-%1$s"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Ixhumeke nge-<xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="available_via_passpoint" msgid="1716000261192603682">"Iyatholakala nge-%1$s"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Thepha ukuze ubhalisele"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Ayikho i-inthanethi"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"Iseva eyimfihlo ye-DNS ayikwazi ukufinyelelwa"</string>
@@ -76,17 +71,13 @@
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Ayikho i-inthanethi"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Ukungena ngemvume kuyadingeka"</string>
     <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"Iphoyinti lokufinyelela ligcwele okwesikhashana"</string>
-    <string name="connected_via_carrier" msgid="1968057009076191514">"Kuxhumeke nge-%1$s"</string>
-    <string name="available_via_carrier" msgid="465598683092718294">"Iyatholakala nge-%1$s"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"Ivula i-<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"Ayikwazanga ukuxhumeka"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"Iqedela ukubhalisa…"</string>
     <string name="osu_sign_up_failed" msgid="5605453599586001793">"Ayikwazanga ukuqedelela ukubhalisa. Thepha ukuze uzame futhi."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"Ukubhalisa kuqediwe. Iyaxhuma…"</string>
-    <string name="speed_label_very_slow" msgid="8526005255731597666">"Phansi kakhulu"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"Phansi"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"KULUNGILE"</string>
-    <string name="speed_label_medium" msgid="9078405312828606976">"Okumaphakathi"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Sheshayo"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Kushesha kakhulu"</string>
     <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Iphelelwe isikhathi"</string>
@@ -98,7 +89,6 @@
     <string name="bluetooth_pairing" msgid="4269046942588193600">"Iyabhangqa..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Ixhunyiwe (ayikho ifoni)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Ixhunyiwe (ayikho imidiya)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Ixhunyiwe (akukho ukufinyelela kumlayezo)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Ixhunyiwe (ayikho ifoni noma imidiya)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Ixhunyiwe, ibhethri ngu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Ixhunyiwe (ayikho ifoni), ibhethri ngu-<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 663e8e4..179573b 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -158,18 +158,6 @@
         <item>Opus</item>
     </string-array>
 
-    <!-- Values for Bluetooth Audio Codec selection preference. -->
-    <string-array name="bluetooth_a2dp_codec_values" translatable="false" >
-        <item>1000000</item>
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>
-        <item>3</item>
-        <item>4</item>
-        <item>5</item>
-        <item>6</item>
-    </string-array>
-
     <!-- Summaries for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50]-->
     <string-array name="bluetooth_a2dp_codec_summaries" >
         <item>Use System Selection (Default)</item>
@@ -191,15 +179,6 @@
         <item>96.0 kHz</item>
     </string-array>
 
-    <!-- Values for Bluetooth Audio Codec Sample Rate selection preference. -->
-    <string-array name="bluetooth_a2dp_codec_sample_rate_values" translatable="false" >
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>
-        <item>4</item>
-        <item>8</item>
-    </string-array>
-
     <!-- Summaries for Bluetooth Audio Codec Sample Rate selection preference. [CHAR LIMIT=50]-->
     <string-array name="bluetooth_a2dp_codec_sample_rate_summaries" >
         <item>Use System Selection (Default)</item>
@@ -217,14 +196,6 @@
         <item>32 bits/sample</item>
     </string-array>
 
-    <!-- Values for Bluetooth Audio Codec Bits Per Sample selection preference. -->
-    <string-array name="bluetooth_a2dp_codec_bits_per_sample_values" translatable="false" >
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>
-        <item>4</item>
-    </string-array>
-
     <!-- Summaries for Bluetooth Audio Codec Bits Per Sample selection preference. [CHAR LIMIT=50]-->
     <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries" >
         <item>Use System Selection (Default)</item>
@@ -240,13 +211,6 @@
         <item>Stereo</item>
     </string-array>
 
-    <!-- Values for Bluetooth Audio Codec Channel Mode selection preference. -->
-    <string-array name="bluetooth_a2dp_codec_channel_mode_values" translatable="false" >
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>
-    </string-array>
-
     <!-- Summaries for Bluetooth Audio Codec Channel Mode selection preference. [CHAR LIMIT=50]-->
     <string-array name="bluetooth_a2dp_codec_channel_mode_summaries" >
         <item>Use System Selection (Default)</item>
@@ -262,14 +226,6 @@
         <item>Best Effort (Adaptive Bit Rate)</item>
     </string-array>
 
-    <!-- Values for Bluetooth Audio Codec LDAC Playback Quaility selection preference. -->
-    <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_values" translatable="false" >
-        <item>1000</item>
-        <item>1001</item>
-        <item>1002</item>
-        <item>1003</item>
-    </string-array>
-
     <!-- Summaries for Bluetooth Audio Codec LDAC Playback Quality selection preference. [CHAR LIMIT=70]-->
     <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries" >
         <item>Optimized for Audio Quality</item>
diff --git a/packages/SettingsLib/res/values/colors.xml b/packages/SettingsLib/res/values/colors.xml
index d2d7471..6b7e918 100644
--- a/packages/SettingsLib/res/values/colors.xml
+++ b/packages/SettingsLib/res/values/colors.xml
@@ -17,9 +17,6 @@
 <resources>
     <color name="disabled_text_color">#66000000</color> <!-- 38% black -->
 
-    <color name="usage_graph_dots">@*android:color/tertiary_device_default_settings</color>
-    <color name="list_divider_color">#64000000</color>
-
     <color name="bt_color_icon_1">#b4a50e0e</color> <!-- 72% Material Red 900 -->
     <color name="bt_color_icon_2">#b40d652d</color> <!-- 72% Material Green 900 -->
     <color name="bt_color_icon_3">#b4e37400</color> <!-- 72% Material Yellow 900 -->
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 226b119..3ef3d36 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -19,16 +19,11 @@
     <!-- The y translation to apply at the start in appear animations. -->
     <dimen name="appear_y_translation_start">32dp</dimen>
 
-    <!-- The translation for disappearing security views after having solved them. -->
-    <dimen name="disappear_y_translation">-32dp</dimen>
-
     <!-- Height of a user icon view -->
     <dimen name="user_icon_view_height">24dp</dimen>
     <!-- User spinner -->
-    <dimen name="user_spinner_height">72dp</dimen>
     <dimen name="user_spinner_padding">4dp</dimen>
     <dimen name="user_spinner_padding_sides">20dp</dimen>
-    <dimen name="user_spinner_item_height">56dp</dimen>
 
     <!-- Lock icon for preferences locked by admin -->
     <dimen name="restricted_icon_padding">4dp</dimen>
@@ -36,10 +31,8 @@
     <dimen name="wifi_preference_badge_padding">8dip</dimen>
 
     <!-- Usage graph dimens -->
-    <dimen name="usage_graph_area_height">122dp</dimen>
     <dimen name="usage_graph_margin_top_bottom">9dp</dimen>
     <dimen name="usage_graph_labels_width">56dp</dimen>
-    <dimen name="usage_graph_labels_padding">16dp</dimen>
 
     <dimen name="usage_graph_divider_size">1dp</dimen>
 
@@ -64,22 +57,13 @@
     <!-- Ratio between width and height -->
     <fraction name="bt_battery_ratio_fraction">35%</fraction>
 
-    <!-- Ratio of height between battery icon and bluetooth icon -->
-    <fraction name="bt_battery_scale_fraction">75%</fraction>
-
     <!-- Fraction value to smooth the edges of the battery icon. The path will be inset by this
          fraction of a pixel.-->
     <fraction name="battery_subpixel_smoothing_left">0%</fraction>
     <fraction name="battery_subpixel_smoothing_right">0%</fraction>
 
-    <!-- Zen mode panel: condition item button padding -->
-    <dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
-    <!-- Zen mode panel: spacing between condition items -->
-    <dimen name="zen_mode_condition_detail_item_spacing">12dp</dimen>
     <!-- Zen mode panel: spacing between two-line condition upper and lower lines -->
     <dimen name="zen_mode_condition_detail_item_interline_spacing">4dp</dimen>
-    <!-- Zen mode panel: bottom padding, a bit less than qs_panel_padding -->
-    <dimen name="zen_mode_condition_detail_bottom_padding">4dp</dimen>
 
     <!-- SignalDrawable -->
     <dimen name="signal_icon_size">15dp</dimen>
@@ -93,9 +77,6 @@
     <!-- Size of advanced icon -->
     <dimen name="advanced_icon_size">18dp</dimen>
 
-    <!-- Minimum width for the popup for updating a user's photo. -->
-    <dimen name="update_user_photo_popup_min_width">300dp</dimen>
-
     <dimen name="add_a_photo_circled_padding">6dp</dimen>
     <dimen name="user_photo_size_in_user_info_dialog">112dp</dimen>
     <dimen name="add_a_photo_icon_size_in_user_info_dialog">32dp</dimen>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 06d7bb4..2e0155b 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -91,10 +91,6 @@
     <string name="wifi_disabled_generic">Disabled</string>
     <!-- Status for networked disabled from a DNS or DHCP failure -->
     <string name="wifi_disabled_network_failure">IP Configuration Failure</string>
-    <!-- Status for networks disabled by the network recommendation provider -->
-    <string name="wifi_disabled_by_recommendation_provider">Not connected due to low quality network</string>
-    <!-- Status for networked disabled from a wifi association failure -->
-    <string name="wifi_disabled_wifi_failure">WiFi Connection Failure</string>
     <!-- Status for networks disabled from authentication failure (wrong password
          or certificate). -->
     <string name="wifi_disabled_password_failure">Authentication problem</string>
@@ -114,20 +110,14 @@
     <string name="wifi_no_internet">No internet access</string>
     <!-- Summary for saved networks -->
     <string name="saved_network">Saved by <xliff:g id="name">%1$s</xliff:g></string>
-    <!-- Summary for connect to metered access point [CHAR LIMIT=NONE] -->
-    <string name="connected_to_metered_access_point">Connected to metered network</string>
 
 
     <!-- Status message of Wi-Fi when it is automatically connected by a network recommendation provider. [CHAR LIMIT=NONE] -->
     <string name="connected_via_network_scorer">Automatically connected via %1$s</string>
     <!-- Status message of Wi-Fi when it is automatically connected by a default network recommendation provider. [CHAR LIMIT=NONE] -->
     <string name="connected_via_network_scorer_default">Automatically connected via network rating provider</string>
-    <!-- Status message of Wi-Fi when it is connected by Passpoint configuration. [CHAR LIMIT=NONE] -->
-    <string name="connected_via_passpoint">Connected via %1$s</string>
     <!-- Status message of Wi-Fi when it is connected by a app (via suggestion or network request). [CHAR LIMIT=NONE] -->
     <string name="connected_via_app">Connected via <xliff:g id="name" example="Wifi App">%1$s</xliff:g></string>
-    <!-- Status message of Wi-Fi when network has matching passpoint credentials. [CHAR LIMIT=NONE] -->
-    <string name="available_via_passpoint">Available via %1$s</string>
     <!-- Status message of OSU Provider network when not connected. [CHAR LIMIT=NONE] -->
     <string name="tap_to_sign_up">Tap to sign up</string>
     <!-- Package name for Settings app-->
@@ -153,11 +143,6 @@
     <!-- Summary for networks failing to connect due to association rejection status 17, AP full -->
     <string name="wifi_ap_unable_to_handle_new_sta">Access point temporarily full</string>
 
-    <!-- Status message of Wi-Fi when it is connected to a Carrier Network. [CHAR LIMIT=NONE] -->
-    <string name="connected_via_carrier">Connected via %1$s</string>
-    <!-- Status message of Wi-Fi when an available network is a carrier network. [CHAR LIMIT=NONE] -->
-    <string name="available_via_carrier">Available via %1$s</string>
-
     <!-- Status message of OSU Provider upon initiating provisioning flow [CHAR LIMIT=NONE] -->
     <string name="osu_opening_provider">Opening <xliff:g id="passpointProvider" example="Passpoint Provider">%1$s</xliff:g></string>
     <!-- Status message of OSU Provider when connection fails [CHAR LIMIT=NONE] -->
@@ -169,14 +154,10 @@
     <!-- Status message of OSU Provider on completing provisioning. [CHAR LIMIT=NONE] -->
     <string name="osu_sign_up_complete">Sign-up complete. Connecting\u2026</string>
 
-    <!-- Speed label for very slow network speed -->
-    <string name="speed_label_very_slow">Very Slow</string>
     <!-- Speed label for slow network speed -->
     <string name="speed_label_slow">Slow</string>
     <!-- Speed label for okay network speed -->
     <string name="speed_label_okay">OK</string>
-    <!-- Speed label for medium network speed -->
-    <string name="speed_label_medium">Medium</string>
     <!-- Speed label for fast network speed -->
     <string name="speed_label_fast">Fast</string>
     <!-- Speed label for very fast network speed -->
@@ -203,8 +184,6 @@
     <string name="bluetooth_connected_no_headset">Connected (no phone)<xliff:g id="active_device">%1$s</xliff:g></string>
     <!-- Bluetooth settings.  Message when connected to a device, except for media audio. [CHAR LIMIT=40] -->
     <string name="bluetooth_connected_no_a2dp">Connected (no media)<xliff:g id="active_device">%1$s</xliff:g></string>
-    <!-- Bluetooth settings.  Message when connected to a device, except for map. [CHAR LIMIT=40] -->
-    <string name="bluetooth_connected_no_map">Connected (no message access)<xliff:g id="active_device">%1$s</xliff:g></string>
     <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio. [CHAR LIMIT=40] -->
     <string name="bluetooth_connected_no_headset_no_a2dp">Connected (no phone or media)<xliff:g id="active_device">%1$s</xliff:g></string>
 
diff --git a/packages/SettingsLib/search/Android.bp b/packages/SettingsLib/search/Android.bp
index 45746d9..cfff519 100644
--- a/packages/SettingsLib/search/Android.bp
+++ b/packages/SettingsLib/search/Android.bp
@@ -19,11 +19,11 @@
     name: "SettingsLib-annotation-processor",
     processor_class: "com.android.settingslib.search.IndexableProcessor",
     static_libs: [
-        "javapoet-prebuilt-jar",
+        "javapoet",
     ],
     srcs: [
         "processor-src/**/*.java",
-        "src/com/android/settingslib/search/SearchIndexable.java"
+        "src/com/android/settingslib/search/SearchIndexable.java",
     ],
     java_resource_dirs: ["resources"],
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
index 59735f41..85e8aad 100644
--- a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
@@ -183,7 +183,7 @@
         final String currentShortcutServiceId = Settings.Secure.getStringForUser(
                 context.getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
                 userId);
-        if (currentShortcutServiceId != null) {
+        if (!TextUtils.isEmpty(currentShortcutServiceId)) {
             return currentShortcutServiceId;
         }
         return context.getString(R.string.config_defaultAccessibilityService);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
index 3152e65..fa056e2b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
@@ -16,6 +16,22 @@
 
 package com.android.settingslib.bluetooth;
 
+import static android.bluetooth.BluetoothAdapter.STATE_CONNECTED;
+import static android.bluetooth.BluetoothAdapter.STATE_CONNECTING;
+import static android.bluetooth.BluetoothAdapter.STATE_DISCONNECTED;
+import static android.bluetooth.BluetoothAdapter.STATE_DISCONNECTING;
+import static android.bluetooth.BluetoothAdapter.STATE_OFF;
+import static android.bluetooth.BluetoothAdapter.STATE_ON;
+import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF;
+import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+
+import androidx.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * BluetoothCallback provides a callback interface for the settings
@@ -33,7 +49,7 @@
      * {@link android.bluetooth.BluetoothAdapter#STATE_ON},
      * {@link android.bluetooth.BluetoothAdapter#STATE_TURNING_OFF}.
      */
-    default void onBluetoothStateChanged(int bluetoothState) {}
+    default void onBluetoothStateChanged(@AdapterState int bluetoothState) {}
 
     /**
      * It will be called when the local Bluetooth adapter has started
@@ -54,14 +70,14 @@
      *
      * @param cachedDevice the Bluetooth device.
      */
-    default void onDeviceAdded(CachedBluetoothDevice cachedDevice) {}
+    default void onDeviceAdded(@NonNull CachedBluetoothDevice cachedDevice) {}
 
     /**
      * It will be called when requiring to remove a remote device from CachedBluetoothDevice list
      *
      * @param cachedDevice the Bluetooth device.
      */
-    default void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {}
+    default void onDeviceDeleted(@NonNull CachedBluetoothDevice cachedDevice) {}
 
     /**
      * It will be called when bond state of a remote device is changed.
@@ -73,7 +89,8 @@
      * {@link android.bluetooth.BluetoothDevice#BOND_BONDING},
      * {@link android.bluetooth.BluetoothDevice#BOND_BONDED}.
      */
-    default void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {}
+    default void onDeviceBondStateChanged(
+            @NonNull CachedBluetoothDevice cachedDevice, int bondState) {}
 
     /**
      * It will be called in following situations:
@@ -89,7 +106,9 @@
      * {@link android.bluetooth.BluetoothAdapter#STATE_CONNECTED},
      * {@link android.bluetooth.BluetoothAdapter#STATE_DISCONNECTING}.
      */
-    default void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {}
+    default void onConnectionStateChanged(
+            @Nullable CachedBluetoothDevice cachedDevice,
+            @ConnectionState int state) {}
 
     /**
      * It will be called when device been set as active for {@code bluetoothProfile}
@@ -101,7 +120,8 @@
      * @param activeDevice the active Bluetooth device.
      * @param bluetoothProfile the profile of active Bluetooth device.
      */
-    default void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {}
+    default void onActiveDeviceChanged(
+            @Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) {}
 
     /**
      * It will be called in following situations:
@@ -124,8 +144,10 @@
      * {@link android.bluetooth.BluetoothProfile#STATE_DISCONNECTING}.
      * @param bluetoothProfile the BluetoothProfile id.
      */
-    default void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
-            int state, int bluetoothProfile) {
+    default void onProfileConnectionStateChanged(
+            @NonNull CachedBluetoothDevice cachedDevice,
+            @ConnectionState int state,
+            int bluetoothProfile) {
     }
 
     /**
@@ -138,6 +160,24 @@
      *                     {@link android.bluetooth.BluetoothAdapter#STATE_DISCONNECTED},
      *                     {@link android.bluetooth.BluetoothAdapter#STATE_CONNECTED}
      */
-    default void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
-    }
+    default void onAclConnectionStateChanged(
+            @NonNull CachedBluetoothDevice cachedDevice, int state) {}
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "STATE_" }, value = {
+            STATE_DISCONNECTED,
+            STATE_CONNECTING,
+            STATE_CONNECTED,
+            STATE_DISCONNECTING,
+    })
+    @interface ConnectionState {}
+
+    @IntDef(prefix = { "STATE_" }, value = {
+            STATE_OFF,
+            STATE_TURNING_ON,
+            STATE_ON,
+            STATE_TURNING_OFF,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface AdapterState {}
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 51812f0..a9f4e9c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -32,6 +32,7 @@
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
@@ -193,19 +194,19 @@
         return deviceAdded;
     }
 
-    void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) {
+    void dispatchDeviceAdded(@NonNull CachedBluetoothDevice cachedDevice) {
         for (BluetoothCallback callback : mCallbacks) {
             callback.onDeviceAdded(cachedDevice);
         }
     }
 
-    void dispatchDeviceRemoved(CachedBluetoothDevice cachedDevice) {
+    void dispatchDeviceRemoved(@NonNull CachedBluetoothDevice cachedDevice) {
         for (BluetoothCallback callback : mCallbacks) {
             callback.onDeviceDeleted(cachedDevice);
         }
     }
 
-    void dispatchProfileConnectionStateChanged(CachedBluetoothDevice device, int state,
+    void dispatchProfileConnectionStateChanged(@NonNull CachedBluetoothDevice device, int state,
             int bluetoothProfile) {
         for (BluetoothCallback callback : mCallbacks) {
             callback.onProfileConnectionStateChanged(device, state, bluetoothProfile);
@@ -228,7 +229,8 @@
     }
 
     @VisibleForTesting
-    void dispatchActiveDeviceChanged(CachedBluetoothDevice activeDevice,
+    void dispatchActiveDeviceChanged(
+            @Nullable CachedBluetoothDevice activeDevice,
             int bluetoothProfile) {
         for (CachedBluetoothDevice cachedDevice : mDeviceManager.getCachedDevicesCopy()) {
             boolean isActive = Objects.equals(cachedDevice, activeDevice);
@@ -239,7 +241,7 @@
         }
     }
 
-    private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice, int state) {
+    private void dispatchAclStateChanged(@NonNull CachedBluetoothDevice activeDevice, int state) {
         for (BluetoothCallback callback : mCallbacks) {
             callback.onAclConnectionStateChanged(activeDevice, state);
         }
@@ -456,6 +458,7 @@
                 Log.w(TAG, "ActiveDeviceChangedHandler: action is null");
                 return;
             }
+            @Nullable
             CachedBluetoothDevice activeDevice = mDeviceManager.findDevice(device);
             int bluetoothProfile = 0;
             if (Objects.equals(action, BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED)) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
index d84e57a..3e33da5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
@@ -49,6 +49,10 @@
     }
 
     @Override
+    public void clicked(int sourceCategory, String key) {
+    }
+
+    @Override
     public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
         final LogMaker logMaker = new LogMaker(category)
                 .setType(MetricsProto.MetricsEvent.TYPE_ACTION);
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
index d4ef3d7..cceca13 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
@@ -34,6 +34,11 @@
     void hidden(Context context, int category, int visibleTime);
 
     /**
+     * Logs a click event when user click item.
+     */
+    void clicked(int category, String key);
+
+    /**
      * Logs an user action.
      */
     void action(Context context, int category, Pair<Integer, Object>... taggedData);
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
index 7390b6a..915421a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
@@ -96,6 +96,18 @@
     }
 
     /**
+     * Logs an event when user click item.
+     *
+     * @param category the target page id
+     * @param key the key id that user clicked
+     */
+    public void clicked(int category, String key) {
+        for (LogWriter writer : mLoggerWriters) {
+            writer.clicked(category, key);
+        }
+    }
+
+    /**
      * Logs a simple action without page id or attribution
      *
      * @param category the target page
@@ -138,7 +150,7 @@
     }
 
     public int getMetricsCategory(Object object) {
-        if (object == null || !(object instanceof Instrumentable)) {
+        if (!(object instanceof Instrumentable)) {
             return MetricsEvent.VIEW_UNKNOWN;
         }
         return ((Instrumentable) object).getMetricsCategory();
@@ -198,11 +210,7 @@
             // Not loggable
             return false;
         }
-        action(sourceMetricsCategory,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                logKey,
-                0);
+        clicked(sourceMetricsCategory, logKey);
         return true;
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
index 0e2a3cb..3352d86 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
@@ -80,12 +80,7 @@
                 MetricsEvent.SETTINGS_GESTURES);
 
         assertThat(loggable).isTrue();
-        verify(mLogWriter).action(
-                MetricsEvent.SETTINGS_GESTURES,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                key,
-                0);
+        verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, key);
     }
 
     @Test
@@ -98,12 +93,7 @@
                 MetricsEvent.SETTINGS_GESTURES);
 
         assertThat(loggable).isTrue();
-        verify(mLogWriter).action(
-                MetricsEvent.SETTINGS_GESTURES,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                Intent.ACTION_ASSIST,
-                0);
+        verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, Intent.ACTION_ASSIST);
     }
 
     @Test
@@ -116,12 +106,7 @@
                 MetricsEvent.SETTINGS_GESTURES);
 
         assertThat(loggable).isTrue();
-        verify(mLogWriter).action(
-                MetricsEvent.SETTINGS_GESTURES,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                fragment,
-                0);
+        verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, fragment);
     }
 
     @Test
@@ -140,12 +125,7 @@
         final boolean loggable = mProvider.logStartedIntent(intent, MetricsEvent.SETTINGS_GESTURES);
 
         assertThat(loggable).isTrue();
-        verify(mLogWriter).action(
-                MetricsEvent.SETTINGS_GESTURES,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                Intent.ACTION_ASSIST,
-                0);
+        verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, Intent.ACTION_ASSIST);
     }
 
     @Test
@@ -155,12 +135,7 @@
         final boolean loggable = mProvider.logStartedIntent(intent, MetricsEvent.SETTINGS_GESTURES);
 
         assertThat(loggable).isTrue();
-        verify(mLogWriter).action(
-                MetricsEvent.SETTINGS_GESTURES,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                "pkg/cls",
-                0);
+        verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, "pkg/cls");
     }
 
     @Test
@@ -171,12 +146,7 @@
                 MetricsEvent.SETTINGS_GESTURES, false);
 
         assertThat(loggable).isTrue();
-        verify(mLogWriter).action(
-                MetricsEvent.SETTINGS_GESTURES,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                "pkg/cls/personal",
-                0);
+        verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, "pkg/cls/personal");
     }
 
     @Test
@@ -187,12 +157,7 @@
                 MetricsEvent.SETTINGS_GESTURES, true);
 
         assertThat(loggable).isTrue();
-        verify(mLogWriter).action(
-                MetricsEvent.SETTINGS_GESTURES,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                "pkg/cls/work",
-                0);
+        verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, "pkg/cls/work");
     }
 
     @Test
@@ -226,12 +191,7 @@
                 MetricsEvent.SETTINGS_GESTURES);
 
         assertThat(loggable).isTrue();
-        verify(mLogWriter).action(
-                MetricsEvent.SETTINGS_GESTURES,
-                MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
-                SettingsEnums.PAGE_UNKNOWN,
-                key,
-                0);
+        verify(mLogWriter).clicked(MetricsEvent.SETTINGS_GESTURES, key);
     }
 
     @Test
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 fd181ff..e2b242c 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
@@ -65,7 +65,6 @@
 
     @Test
     public void setIsInstantApp_shouldUpdateInstallType() {
-
         mPreference.onBindViewHolder(mHolder);
         mPreference.setIsInstantApp(true);
 
@@ -77,8 +76,8 @@
     public void setSecondSummary_shouldUpdateSecondSummary() {
         final String defaultTestText = "Test second summary";
 
-        mPreference.onBindViewHolder(mHolder);
         mPreference.setSecondSummary(defaultTestText);
+        mPreference.onBindViewHolder(mHolder);
 
         assertThat(((TextView) mRootView.findViewById(R.id.second_summary)).getText().toString())
                 .isEqualTo(defaultTestText);
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 10ac5d9..f501682 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -72,6 +72,7 @@
         Settings.System.SIP_CALL_OPTIONS,
         Settings.System.SIP_RECEIVE_CALLS,
         Settings.System.POINTER_SPEED,
+        Settings.System.VIBRATE_ON,
         Settings.System.VIBRATE_WHEN_RINGING,
         Settings.System.RINGTONE,
         Settings.System.LOCK_TO_APP_ENABLED,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index e7c7ac0..b1979c9 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -83,7 +83,6 @@
                     Settings.System.SYSTEM_LOCALES, // bug?
                     Settings.System.USER_ROTATION, // backup candidate?
                     Settings.System.VIBRATE_IN_SILENT, // deprecated?
-                    Settings.System.VIBRATE_ON, // candidate for backup?
                     Settings.System.VOLUME_ACCESSIBILITY, // used internally, changing value will
                                                           // not change volume
                     Settings.System.VOLUME_ALARM, // deprecated since API 2?
@@ -769,6 +768,7 @@
                  Settings.Secure.SMS_DEFAULT_APPLICATION,
                  Settings.Secure.SPELL_CHECKER_ENABLED,  // Intentionally removed in Q
                  Settings.Secure.TRUST_AGENTS_INITIALIZED,
+                 Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED,
                  Settings.Secure.TV_APP_USES_NON_SYSTEM_INPUTS,
                  Settings.Secure.TV_INPUT_CUSTOM_LABELS,
                  Settings.Secure.TV_INPUT_HIDDEN_INPUTS,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index b31e36c..6c17036 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -180,6 +180,7 @@
     <uses-permission android:name="android.permission.MANAGE_ROLLBACKS" />
     <uses-permission android:name="android.permission.TEST_MANAGE_ROLLBACKS" />
     <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+    <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
     <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
     <uses-permission android:name="android.permission.REBOOT" />
     <uses-permission android:name="android.permission.DEVICE_POWER" />
diff --git a/packages/Shell/src/com/android/shell/Screenshooter.java b/packages/Shell/src/com/android/shell/Screenshooter.java
index 85f2552..d55eda0 100644
--- a/packages/Shell/src/com/android/shell/Screenshooter.java
+++ b/packages/Shell/src/com/android/shell/Screenshooter.java
@@ -20,6 +20,7 @@
 import android.os.IBinder;
 import android.util.Log;
 import android.view.SurfaceControl;
+import android.window.ScreenCapture;
 
 /**
  * Helper class used to take screenshots.
@@ -40,11 +41,11 @@
         Log.d(TAG, "Taking fullscreen screenshot");
         // Take the screenshot
         final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
-        final SurfaceControl.DisplayCaptureArgs captureArgs =
-                new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
+        final ScreenCapture.DisplayCaptureArgs captureArgs =
+                new ScreenCapture.DisplayCaptureArgs.Builder(displayToken)
                         .build();
-        final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                SurfaceControl.captureDisplay(captureArgs);
+        final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                ScreenCapture.captureDisplay(captureArgs);
         final Bitmap screenShot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
         if (screenShot == null) {
             Log.e(TAG, "Failed to take fullscreen screenshot");
diff --git a/packages/SoundPicker/res/values-ro/strings.xml b/packages/SoundPicker/res/values-ro/strings.xml
index 6190f7f..58b5aeb 100644
--- a/packages/SoundPicker/res/values-ro/strings.xml
+++ b/packages/SoundPicker/res/values-ro/strings.xml
@@ -19,10 +19,10 @@
     <string name="ringtone_default" msgid="798836092118824500">"Ton de apel prestabilit"</string>
     <string name="notification_sound_default" msgid="8133121186242636840">"Sunet de notificare prestabilit"</string>
     <string name="alarm_sound_default" msgid="4787646764557462649">"Sunet de alarmă prestabilit"</string>
-    <string name="add_ringtone_text" msgid="6642389991738337529">"Adăugați un ton de sonerie"</string>
-    <string name="add_alarm_text" msgid="3545497316166999225">"Adăugați o alarmă"</string>
-    <string name="add_notification_text" msgid="4431129543300614788">"Adăugați o notificare"</string>
-    <string name="delete_ringtone_text" msgid="201443984070732499">"Ștergeți"</string>
+    <string name="add_ringtone_text" msgid="6642389991738337529">"Adaugă un ton de sonerie"</string>
+    <string name="add_alarm_text" msgid="3545497316166999225">"Adaugă o alarmă"</string>
+    <string name="add_notification_text" msgid="4431129543300614788">"Adaugă o notificare"</string>
+    <string name="delete_ringtone_text" msgid="201443984070732499">"Șterge"</string>
     <string name="unable_to_add_ringtone" msgid="4583511263449467326">"Nu se poate adăuga tonul de sonerie personalizat"</string>
     <string name="unable_to_delete_ringtone" msgid="6792301380142859496">"Nu se poate șterge tonul de sonerie personalizat"</string>
     <string name="app_label" msgid="3091611356093417332">"Sunete"</string>
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 7d4dcf8..ebabdf57 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -352,8 +352,11 @@
          * The animation was cancelled. Note that [onLaunchAnimationEnd] will still be called after
          * this if the animation was already started, i.e. if [onLaunchAnimationStart] was called
          * before the cancellation.
+         *
+         * If this launch animation affected the occlusion state of the keyguard, WM will provide
+         * us with [newKeyguardOccludedState] so that we can set the occluded state appropriately.
          */
-        fun onLaunchAnimationCancelled() {}
+        fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {}
     }
 
     @VisibleForTesting
@@ -667,7 +670,7 @@
             removeTimeout()
             context.mainExecutor.execute {
                 animation?.cancel()
-                controller.onLaunchAnimationCancelled()
+                controller.onLaunchAnimationCancelled(newKeyguardOccludedState = isKeyguardOccluded)
             }
         }
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index eac5d275..9656b8a 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -238,7 +238,7 @@
                 }
             }
 
-            override fun onLaunchAnimationCancelled() {
+            override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) {
                 controller.onLaunchAnimationCancelled()
                 enableDialogDismiss()
                 dialog.dismiss()
diff --git a/packages/SystemUI/compose/gallery/res/drawable/kitten1.jpeg b/packages/SystemUI/compose/gallery/res/drawable/kitten1.jpeg
new file mode 100644
index 0000000..6241b0b
--- /dev/null
+++ b/packages/SystemUI/compose/gallery/res/drawable/kitten1.jpeg
Binary files differ
diff --git a/packages/SystemUI/compose/gallery/res/drawable/kitten2.jpeg b/packages/SystemUI/compose/gallery/res/drawable/kitten2.jpeg
new file mode 100644
index 0000000..870ef13
--- /dev/null
+++ b/packages/SystemUI/compose/gallery/res/drawable/kitten2.jpeg
Binary files differ
diff --git a/packages/SystemUI/compose/gallery/res/drawable/kitten3.jpeg b/packages/SystemUI/compose/gallery/res/drawable/kitten3.jpeg
new file mode 100644
index 0000000..bb7261c
--- /dev/null
+++ b/packages/SystemUI/compose/gallery/res/drawable/kitten3.jpeg
Binary files differ
diff --git a/packages/SystemUI/compose/gallery/res/drawable/kitten4.jpeg b/packages/SystemUI/compose/gallery/res/drawable/kitten4.jpeg
new file mode 100644
index 0000000..e34b7dd
--- /dev/null
+++ b/packages/SystemUI/compose/gallery/res/drawable/kitten4.jpeg
Binary files differ
diff --git a/packages/SystemUI/compose/gallery/res/drawable/kitten5.jpeg b/packages/SystemUI/compose/gallery/res/drawable/kitten5.jpeg
new file mode 100644
index 0000000..9cde24b
--- /dev/null
+++ b/packages/SystemUI/compose/gallery/res/drawable/kitten5.jpeg
Binary files differ
diff --git a/packages/SystemUI/compose/gallery/res/drawable/kitten6.jpeg b/packages/SystemUI/compose/gallery/res/drawable/kitten6.jpeg
new file mode 100644
index 0000000..17825b6
--- /dev/null
+++ b/packages/SystemUI/compose/gallery/res/drawable/kitten6.jpeg
Binary files differ
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt
index 2e6456b..6805bf8 100644
--- a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/GalleryApp.kt
@@ -28,25 +28,25 @@
 
 /** The gallery app screens. */
 object GalleryAppScreens {
-    val Typography = ChildScreen("typography") { TypographyScreen() }
-    val MaterialColors = ChildScreen("material_colors") { MaterialColorsScreen() }
-    val AndroidColors = ChildScreen("android_colors") { AndroidColorsScreen() }
-    val Buttons = ChildScreen("buttons") { ButtonsScreen() }
-    val ExampleFeature = ChildScreen("example_feature") { ExampleFeatureScreen() }
+    private val Typography = ChildScreen("typography") { TypographyScreen() }
+    private val MaterialColors = ChildScreen("material_colors") { MaterialColorsScreen() }
+    private val AndroidColors = ChildScreen("android_colors") { AndroidColorsScreen() }
+    private val Buttons = ChildScreen("buttons") { ButtonsScreen() }
+    private val ExampleFeature = ChildScreen("example_feature") { ExampleFeatureScreen() }
 
-    val PeopleEmpty =
+    private val PeopleEmpty =
         ChildScreen("people_empty") { navController ->
             EmptyPeopleScreen(onResult = { navController.popBackStack() })
         }
-    val PeopleFew =
+    private val PeopleFew =
         ChildScreen("people_few") { navController ->
             FewPeopleScreen(onResult = { navController.popBackStack() })
         }
-    val PeopleFull =
+    private val PeopleFull =
         ChildScreen("people_full") { navController ->
             FullPeopleScreen(onResult = { navController.popBackStack() })
         }
-    val People =
+    private val People =
         ParentScreen(
             "people",
             mapOf(
@@ -55,6 +55,52 @@
                 "Full" to PeopleFull,
             )
         )
+    private val UserSwitcherSingleUser =
+        ChildScreen("user_switcher_single") { navController ->
+            UserSwitcherScreen(
+                userCount = 1,
+                onFinished = navController::popBackStack,
+            )
+        }
+    private val UserSwitcherThreeUsers =
+        ChildScreen("user_switcher_three") { navController ->
+            UserSwitcherScreen(
+                userCount = 3,
+                onFinished = navController::popBackStack,
+            )
+        }
+    private val UserSwitcherFourUsers =
+        ChildScreen("user_switcher_four") { navController ->
+            UserSwitcherScreen(
+                userCount = 4,
+                onFinished = navController::popBackStack,
+            )
+        }
+    private val UserSwitcherFiveUsers =
+        ChildScreen("user_switcher_five") { navController ->
+            UserSwitcherScreen(
+                userCount = 5,
+                onFinished = navController::popBackStack,
+            )
+        }
+    private val UserSwitcherSixUsers =
+        ChildScreen("user_switcher_six") { navController ->
+            UserSwitcherScreen(
+                userCount = 6,
+                onFinished = navController::popBackStack,
+            )
+        }
+    private val UserSwitcher =
+        ParentScreen(
+            "user_switcher",
+            mapOf(
+                "Single" to UserSwitcherSingleUser,
+                "Three" to UserSwitcherThreeUsers,
+                "Four" to UserSwitcherFourUsers,
+                "Five" to UserSwitcherFiveUsers,
+                "Six" to UserSwitcherSixUsers,
+            )
+        )
 
     val Home =
         ParentScreen(
@@ -66,6 +112,7 @@
                 "Example feature" to ExampleFeature,
                 "Buttons" to Buttons,
                 "People" to People,
+                "User Switcher" to UserSwitcher,
             )
         )
 }
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/UserSwitcherScreen.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/UserSwitcherScreen.kt
new file mode 100644
index 0000000..fe9707d
--- /dev/null
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/UserSwitcherScreen.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.compose.gallery
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+import com.android.systemui.user.Fakes.fakeUserSwitcherViewModel
+import com.android.systemui.user.ui.compose.UserSwitcherScreen
+
+@Composable
+fun UserSwitcherScreen(
+    userCount: Int,
+    onFinished: () -> Unit,
+) {
+    val context = LocalContext.current.applicationContext
+    UserSwitcherScreen(
+        viewModel = fakeUserSwitcherViewModel(context, userCount = userCount),
+        onFinished = onFinished,
+    )
+}
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/user/Fakes.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/user/Fakes.kt
index 02d76f4..91a73ea 100644
--- a/packages/SystemUI/compose/gallery/src/com/android/systemui/user/Fakes.kt
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/user/Fakes.kt
@@ -58,12 +58,29 @@
                                     (0 until userCount).map { index ->
                                         UserModel(
                                             id = index,
-                                            name = Text.Loaded("user_$index"),
+                                            name =
+                                                Text.Loaded(
+                                                    when (index % 6) {
+                                                        0 -> "Ross Geller"
+                                                        1 -> "Phoebe Buffay"
+                                                        2 -> "Monica Geller"
+                                                        3 -> "Rachel Greene"
+                                                        4 -> "Chandler Bing"
+                                                        else -> "Joey Tribbiani"
+                                                    }
+                                                ),
                                             image =
                                                 checkNotNull(
                                                     AppCompatResources.getDrawable(
                                                         context,
-                                                        R.drawable.ic_avatar_guest_user
+                                                        when (index % 6) {
+                                                            0 -> R.drawable.kitten1
+                                                            1 -> R.drawable.kitten2
+                                                            2 -> R.drawable.kitten3
+                                                            3 -> R.drawable.kitten4
+                                                            4 -> R.drawable.kitten5
+                                                            else -> R.drawable.kitten6
+                                                        },
                                                     )
                                                 ),
                                             isSelected = index == 0,
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
index bfbccb8..7839ec8 100644
--- a/packages/SystemUI/ktfmt_includes.txt
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -498,7 +498,6 @@
 -packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherFeatureController.kt
--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
 -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
index 1aaf19e..c50340c 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
@@ -147,10 +147,10 @@
     }
 
     /**
-     * Listener that is alerted when a double tap is required to confirm a single tap.
+     * Listener that is alerted when an additional tap is required to confirm a single tap.
      **/
     interface FalsingTapListener {
-        void onDoubleTapRequired();
+        void onAdditionalTapRequired();
     }
 
     /** Passed to {@link FalsingManager#onProximityEvent}. */
diff --git a/packages/SystemUI/res-keyguard/drawable/kg_bouncer_secondary_button.xml b/packages/SystemUI/res-keyguard/drawable/kg_bouncer_secondary_button.xml
new file mode 100644
index 0000000..732fc57
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/kg_bouncer_secondary_button.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:insetTop="6dp"
+    android:insetBottom="6dp">
+    <ripple android:color="?android:attr/colorControlHighlight">
+        <item android:id="@android:id/mask">
+            <shape android:shape="rectangle">
+                <solid android:color="?android:attr/textColorSecondary"/>
+                <corners android:radius="24dp"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <corners android:radius="24dp"/>
+                <solid android:color="@android:color/transparent"/>
+                <stroke android:color="?androidprv:attr/colorAccentTertiary"
+                    android:width="1dp"
+                    />
+                <padding android:left="16dp"
+                    android:top="12dp"
+                    android:right="16dp"
+                    android:bottom="12dp"/>
+            </shape>
+        </item>
+    </ripple>
+</inset>
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_invert_colors_icon_off.xml b/packages/SystemUI/res-keyguard/drawable/qs_invert_colors_icon_off.xml
new file mode 100644
index 0000000..a347123
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/qs_invert_colors_icon_off.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M7.38 -0.28 C5.69,-2.81 1.5,-8.5 0.01,-7.32 C0.03,-6.22 -0.06,6.16 -0.06,7.78 C1.56,7.81 5.44,7.19 7.37,2.06 C7.37,1.21 7.35,1.69 7.35,1 C7.35,0.09 7.38,0.59 7.38,-0.28c "
+                    android:valueTo="M6 -2.38 C1.81,-6.69 -0.5,-10 -1.72,-7.1 C-1.73,-6.22 -1.73,5.88 -1.7,7.16 C0.25,8.45 3,7.75 5.47,4.91 C6.33,3.91 7.21,2.42 7.24,1.13 C7.26,-0.05 6.87,-1.49 6,-2.38c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="33"
+                    android:propertyName="pathData"
+                    android:startOffset="17"
+                    android:valueFrom="M6 -2.38 C1.81,-6.69 -0.5,-10 -1.72,-7.1 C-1.73,-6.22 -1.73,5.88 -1.7,7.16 C0.25,8.45 3,7.75 5.47,4.91 C6.33,3.91 7.21,2.42 7.24,1.13 C7.26,-0.05 6.87,-1.49 6,-2.38c "
+                    android:valueTo="M4.94 -3.95 C-0.31,-9.06 0.52,-9.42 -5.75,-3.22 C-8.31,-0.69 -7.05,3 -6.94,3.22 C-3.63,9.31 2.63,9.5 5.94,4.59 C6.61,3.6 7.43,1.16 7.12,0 C6.72,-1.45 6.01,-2.9 4.94,-3.95c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="67"
+                    android:propertyName="pathData"
+                    android:startOffset="50"
+                    android:valueFrom="M4.94 -3.95 C-0.31,-9.06 0.52,-9.42 -5.75,-3.22 C-8.31,-0.69 -7.05,3 -6.94,3.22 C-3.63,9.31 2.63,9.5 5.94,4.59 C6.61,3.6 7.43,1.16 7.12,0 C6.72,-1.45 6.01,-2.9 4.94,-3.95c "
+                    android:valueTo="M3.07 -5.83 C-0.44,-10.25 -2.56,-6.87 -6.11,-2.6 C-7.03,-1.49 -7.23,1.85 -7.18,2.06 C-5.84,7.25 -0.33,9.23 3.14,6.75 C3.17,5.1 3.17,3.58 3.22,0 C3.25,-3.04 3.1,-4.1 3.07,-5.83c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="pathData"
+                    android:startOffset="117"
+                    android:valueFrom="M3.07 -5.83 C-0.44,-10.25 -2.56,-6.87 -6.11,-2.6 C-7.03,-1.49 -7.23,1.85 -7.18,2.06 C-5.84,7.25 -0.33,9.23 3.14,6.75 C3.17,5.1 3.17,3.58 3.22,0 C3.25,-3.04 3.1,-4.1 3.07,-5.83c "
+                    android:valueTo="M0 -8.18 C-1.81,-7.06 -3.89,-5.21 -5.95,-2.81 C-7.56,-0.94 -7.37,0.88 -7.37,1.09 C-7.37,6.31 -2.19,7.99 0,7.99 C0,6.34 -0.01,3.91 -0.01,0 C-0.01,-3.91 0,-6 0,-8.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="433"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M7.38 -0.28 C5.69,-2.81 1.5,-8.5 0.01,-7.32 C0.03,-6.22 -0.06,6.16 -0.06,7.78 C1.56,7.81 5.44,7.19 7.37,2.06 C7.37,1.21 7.35,1.69 7.35,1 C7.35,0.09 7.38,0.59 7.38,-0.28c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M0 -7.19 C0,-7.19 2.93,-4.32 4.38,-2.87 C5.25,-2 5.88,-0.62 5.88,1.19 C5.88,4.5 2.8,6.97 0,7 C-2.8,7.03 -6,4.37 -6,1.13 C-6,-0.43 -5.38,-1.9 -4.25,-3.01 C-4.25,-3.01 0,-7.19 0,-7.19  M-5.65 -4.44 C-5.65,-4.44 -5.65,-4.44 -5.65,-4.44 C-7.1,-3.01 -8,-1.04 -8,1.13 C-8,5.48 -4.42,9 0,9 C4.42,9 8,5.48 8,1.13 C8,-1.04 7.1,-3.01 5.65,-4.44 C5.65,-4.44 5.65,-4.44 5.65,-4.44 C5.65,-4.44 0,-10 0,-10 C0,-10 -5.65,-4.44 -5.65,-4.44c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_invert_colors_icon_on.xml b/packages/SystemUI/res-keyguard/drawable/qs_invert_colors_icon_on.xml
new file mode 100644
index 0000000..c5609d8
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/qs_invert_colors_icon_on.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="100"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M0 -7.49 C-2.58,-7.49 -7.47,-2.59 -7.47,0.57 C-7.47,0.77 -7.37,0.88 -7.37,1.09 C-7.37,6.31 -2.19,7.55 0,7.55 C0,5.91 -0.01,3.91 -0.01,0 C-0.01,-3.91 0,-5.31 0,-7.49c "
+                    android:valueTo="M3.11 -6.83 C-1.37,-10.12 -6.04,-3.87 -7.22,0.09 C-7.26,0.29 -7.23,1.85 -7.18,2.06 C-5.84,7.25 -0.33,9.23 3.14,6.75 C3.17,5.1 3.17,3.58 3.22,0 C3.25,-3.04 3.14,-5.1 3.11,-6.83c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="67"
+                    android:propertyName="pathData"
+                    android:startOffset="100"
+                    android:valueFrom="M3.11 -6.83 C-1.37,-10.12 -6.04,-3.87 -7.22,0.09 C-7.26,0.29 -7.23,1.85 -7.18,2.06 C-5.84,7.25 -0.33,9.23 3.14,6.75 C3.17,5.1 3.17,3.58 3.22,0 C3.25,-3.04 3.14,-5.1 3.11,-6.83c "
+                    android:valueTo="M5 -3.95 C-0.25,-9.87 -0.47,-8.74 -5,-3.63 C-7.94,-0.31 -7.05,3 -6.94,3.22 C-3.63,9.31 2.94,9.19 7,3.59 C7.06,1.94 7,3.19 7.12,0 C7.19,-2 5.06,-2.75 5,-3.95c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="67"
+                    android:propertyName="pathData"
+                    android:startOffset="167"
+                    android:valueFrom="M5 -3.95 C-0.25,-9.87 -0.47,-8.74 -5,-3.63 C-7.94,-0.31 -7.05,3 -6.94,3.22 C-3.63,9.31 2.94,9.19 7,3.59 C7.06,1.94 7,3.19 7.12,0 C7.19,-2 5.06,-2.75 5,-3.95c "
+                    android:valueTo="M4.82 -3.81 C1,-7.87 0.75,-9.37 -1.72,-7.1 C-1.73,-6.22 -1.73,5.88 -1.7,7.16 C0.25,8.45 4.38,7.38 6.4,3.22 C6.77,2.46 7,1.69 6.74,0 C6.56,-1.16 5.85,-2.71 4.82,-3.81c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="100"
+                    android:propertyName="pathData"
+                    android:startOffset="233"
+                    android:valueFrom="M4.82 -3.81 C1,-7.87 0.75,-9.37 -1.72,-7.1 C-1.73,-6.22 -1.73,5.88 -1.7,7.16 C0.25,8.45 4.38,7.38 6.4,3.22 C6.77,2.46 7,1.69 6.74,0 C6.56,-1.16 5.85,-2.71 4.82,-3.81c "
+                    android:valueTo="M5.63 -2.97 C3.65,-4.93 0.75,-8.37 0.01,-7.32 C0.03,-6.22 -0.03,5.66 -0.03,7.28 C1.59,7.31 4.13,7.94 6.31,3.44 C6.68,2.66 7,1.37 6.87,0.06 C6.77,-0.84 6.13,-2.47 5.63,-2.97c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="433"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M0 -7.49 C-2.58,-7.49 -7.47,-2.59 -7.47,0.57 C-7.47,0.77 -7.37,0.88 -7.37,1.09 C-7.37,6.31 -2.19,7.55 0,7.55 C0,5.91 -0.01,3.91 -0.01,0 C-0.01,-3.91 0,-5.31 0,-7.49c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M0 -7.19 C0,-7.19 2.93,-4.32 4.38,-2.87 C5.25,-2 5.88,-0.62 5.88,1.19 C5.88,4.5 2.8,6.97 0,7 C-2.8,7.03 -6,4.37 -6,1.13 C-6,-0.43 -5.38,-1.9 -4.25,-3.01 C-4.25,-3.01 0,-7.19 0,-7.19  M-5.65 -4.44 C-5.65,-4.44 -5.65,-4.44 -5.65,-4.44 C-7.1,-3.01 -8,-1.04 -8,1.13 C-8,5.48 -4.42,9 0,9 C4.42,9 8,5.48 8,1.13 C8,-1.04 7.1,-3.01 5.65,-4.44 C5.65,-4.44 5.65,-4.44 5.65,-4.44 C5.65,-4.44 0,-10 0,-10 C0,-10 -5.65,-4.44 -5.65,-4.44c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
index db508c9..67fd5b9 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
@@ -17,15 +17,17 @@
 */
 -->
 
-<!-- This contains disable esim buttonas shared by sim_pin/sim_puk screens -->
-<com.android.keyguard.KeyguardEsimArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<!-- This contains disable eSim buttons shared by sim_pin/sim_puk screens -->
+<com.android.keyguard.KeyguardEsimArea xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_disable_esim"
+    style="@style/Keyguard.TextView"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:id="@+id/keyguard_disable_esim"
-    android:visibility="gone"
+    android:background="@drawable/kg_bouncer_secondary_button"
+    android:drawablePadding="10dp"
+    android:drawableStart="@drawable/ic_no_sim"
+    android:drawableTint="?android:attr/textColorPrimary"
     android:text="@string/disable_carrier_button_text"
-    style="@style/Keyguard.TextView"
-    android:textAppearance="?android:attr/textAppearanceMedium"
+    android:textColor="?android:attr/textColorPrimary"
     android:textSize="@dimen/kg_status_line_font_size"
-    android:textAllCaps="@bool/kg_use_all_caps" />
+    android:visibility="gone" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
index f2fe520..7db0fe9 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
@@ -47,8 +47,7 @@
         <include layout="@layout/keyguard_esim_area"
              android:id="@+id/keyguard_esim_area"
              android:layout_width="wrap_content"
-             android:layout_height="wrap_content"
-             android:layout_marginTop="@dimen/eca_overlap" />
+             android:layout_height="wrap_content" />
         <RelativeLayout
                 android:id="@+id/row0"
                 android:layout_width="match_parent"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
index a21ec29..422bd4c 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
@@ -51,8 +51,7 @@
         <include layout="@layout/keyguard_esim_area"
             android:id="@+id/keyguard_esim_area"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/eca_overlap" />
+            android:layout_height="wrap_content" />
 
         <RelativeLayout
                 android:id="@+id/row0"
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index dcc9050..ae8680a0 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -20,9 +20,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Introduceți codul PIN"</string>
-    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Introduceți modelul"</string>
-    <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Introduceți parola"</string>
+    <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Introdu codul PIN"</string>
+    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Introdu modelul"</string>
+    <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Introdu parola"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Card nevalid"</string>
     <string name="keyguard_charged" msgid="5478247181205188995">"Încărcată"</string>
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă wireless"</string>
@@ -31,11 +31,11 @@
     <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă rapid"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă lent"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1709413803451065875">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Încărcarea s-a întrerupt pentru a proteja bateria"</string>
-    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Apăsați pe Meniu pentru a debloca."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Apasă pe Meniu pentru a debloca."</string>
     <string name="keyguard_network_locked_message" msgid="407096292844868608">"Rețea blocată"</string>
     <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Niciun card SIM"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Introduceți un card SIM."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Cardul SIM lipsește sau nu poate fi citit. Introduceți un card SIM."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Introdu un card SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Cardul SIM lipsește sau nu poate fi citit. Introdu un card SIM."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Card SIM inutilizabil."</string>
     <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"Cardul dvs. SIM este dezactivat definitiv.\n Contactați furnizorul de servicii wireless pentru a obține un alt card SIM."</string>
     <string name="keyguard_sim_locked_message" msgid="4343544458476911044">"Cardul SIM este blocat."</string>
@@ -45,24 +45,24 @@
     <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Parola dispozitivului"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"Zona codului PIN pentru cardul SIM"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"Zona codului PUK pentru cardul SIM"</string>
-    <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Ștergeți"</string>
+    <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Șterge"</string>
     <string name="disable_carrier_button_text" msgid="7153361131709275746">"Dezactivați cardul eSIM"</string>
     <string name="error_disable_esim_title" msgid="3802652622784813119">"Nu se poate dezactiva cardul eSIM"</string>
     <string name="error_disable_esim_msg" msgid="2441188596467999327">"Cardul eSIM nu poate fi dezactivat din cauza unei erori."</string>
-    <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Introduceți"</string>
+    <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Introdu"</string>
     <string name="kg_wrong_pattern" msgid="5907301342430102842">"Model greșit"</string>
     <string name="kg_wrong_password" msgid="4143127991071670512">"Parolă greșită"</string>
     <string name="kg_wrong_pin" msgid="4160978845968732624">"Cod PIN greșit"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Reîncercați peste o secundă.}few{Reîncercați peste # secunde.}other{Reîncercați peste # de secunde.}}"</string>
-    <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Introduceți codul PIN al cardului SIM."</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Introduceți codul PIN al cardului SIM pentru „<xliff:g id="CARRIER">%1$s</xliff:g>”."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Reîncearcă peste o secundă.}few{Reîncearcă peste # secunde.}other{Reîncearcă peste # de secunde.}}"</string>
+    <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Introdu codul PIN al cardului SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Introdu codul PIN al cardului SIM pentru „<xliff:g id="CARRIER">%1$s</xliff:g>”."</string>
     <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Dezactivați cardul eSIM pentru a folosi dispozitivul fără serviciu mobil."</string>
     <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"Cardul SIM este acum dezactivat. Pentru a continua, introduceți codul PUK. Pentru detalii, contactați operatorul."</string>
     <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"Cardul SIM „<xliff:g id="CARRIER">%1$s</xliff:g>\" este acum dezactivat. Pentru a continua, introduceți codul PUK. Pentru detalii, contactați operatorul."</string>
-    <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Introduceți codul PIN dorit"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Introdu codul PIN dorit"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Confirmați codul PIN dorit"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"Se deblochează cardul SIM…"</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Introduceți un cod PIN alcătuit din 4 până la 8 cifre."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Introdu un cod PIN alcătuit din 4 până la 8 cifre."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Codul PUK trebuie să aibă minimum 8 cifre."</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Ați introdus incorect codul PIN de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori.\n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> secunde."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Ați introdus incorect parola de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> secunde."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw600dp/dimens.xml b/packages/SystemUI/res-keyguard/values-sw600dp/dimens.xml
index e80cfaf..a1068c6 100644
--- a/packages/SystemUI/res-keyguard/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-sw600dp/dimens.xml
@@ -31,8 +31,4 @@
     <!-- Overload default clock widget parameters -->
     <dimen name="widget_big_font_size">100dp</dimen>
     <dimen name="widget_label_font_size">18sp</dimen>
-
-    <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text.
-         Should be 0 on devices with plenty of room (e.g. tablets) -->
-    <dimen name="eca_overlap">0dip</dimen>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index ac131ae..46f6ab2 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -44,10 +44,6 @@
     <dimen name="keyguard_eca_top_margin">18dp</dimen>
     <dimen name="keyguard_eca_bottom_margin">12dp</dimen>
 
-    <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text.
-         Should be 0 on devices with plenty of room (e.g. tablets) -->
-    <dimen name="eca_overlap">-10dip</dimen>
-
     <!-- Slice header -->
     <dimen name="widget_title_font_size">20dp</dimen>
     <dimen name="widget_title_line_height">24dp</dimen>
diff --git a/packages/SystemUI/res/drawable/ic_magnification_menu_large.xml b/packages/SystemUI/res/drawable/ic_magnification_menu_large.xml
index 1ab0d4d..92c9527 100644
--- a/packages/SystemUI/res/drawable/ic_magnification_menu_large.xml
+++ b/packages/SystemUI/res/drawable/ic_magnification_menu_large.xml
@@ -14,12 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:viewportWidth="24"
-    android:viewportHeight="24"
-    android:width="24dp"
-    android:height="24dp">
-    <path
-        android:pathData="M3 21L21 21C22.1 21 23 20.1 23 19L23 5C23 3.9 22.1 3 21 3L3 3C1.9 3 1 3.9 1 5L1 19C1 20.1 1.9 21 3 21ZM3 5L21 5L21 19L3 19L3 5ZM4 15L16.75 15L16.75 6L4 6L4 15Z"
-        android:fillType="evenOdd"
-        android:fillColor="#000000" />
-</vector>
\ No newline at end of file
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M9.7,29.6H33.75V13.7H9.7ZM7,40Q5.8,40 4.9,39.1Q4,38.2 4,37V11Q4,9.8 4.9,8.9Q5.8,8 7,8H41Q42.2,8 43.1,8.9Q44,9.8 44,11V37Q44,38.2 43.1,39.1Q42.2,40 41,40ZM7,37H41Q41,37 41,37Q41,37 41,37V11Q41,11 41,11Q41,11 41,11H7Q7,11 7,11Q7,11 7,11V37Q7,37 7,37Q7,37 7,37ZM7,37Q7,37 7,37Q7,37 7,37V11Q7,11 7,11Q7,11 7,11Q7,11 7,11Q7,11 7,11V37Q7,37 7,37Q7,37 7,37Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_magnification_menu_medium.xml b/packages/SystemUI/res/drawable/ic_magnification_menu_medium.xml
index 6fc89a6..209681f 100644
--- a/packages/SystemUI/res/drawable/ic_magnification_menu_medium.xml
+++ b/packages/SystemUI/res/drawable/ic_magnification_menu_medium.xml
@@ -14,12 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:viewportWidth="24"
-    android:viewportHeight="24"
-    android:width="24dp"
-    android:height="24dp">
-    <path
-        android:pathData="M3 21L21 21C22.1 21 23 20.1 23 19L23 5C23 3.9 22.1 3 21 3L3 3C1.9 3 1 3.9 1 5L1 19C1 20.1 1.9 21 3 21ZM3 5L21 5L21 19L3 19L3 5ZM4 12.75L13.75 12.75L13.75 6L4 6L4 12.75Z"
-        android:fillType="evenOdd"
-        android:fillColor="#000000" />
-</vector>
\ No newline at end of file
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M9.7,27.6H27.75V13.7H9.7ZM7,40Q5.8,40 4.9,39.1Q4,38.2 4,37V11Q4,9.8 4.9,8.9Q5.8,8 7,8H41Q42.2,8 43.1,8.9Q44,9.8 44,11V37Q44,38.2 43.1,39.1Q42.2,40 41,40ZM7,37H41Q41,37 41,37Q41,37 41,37V11Q41,11 41,11Q41,11 41,11H7Q7,11 7,11Q7,11 7,11V37Q7,37 7,37Q7,37 7,37ZM7,37Q7,37 7,37Q7,37 7,37V11Q7,11 7,11Q7,11 7,11Q7,11 7,11Q7,11 7,11V37Q7,37 7,37Q7,37 7,37Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_magnification_menu_small.xml b/packages/SystemUI/res/drawable/ic_magnification_menu_small.xml
index fd73574..a3dc816 100644
--- a/packages/SystemUI/res/drawable/ic_magnification_menu_small.xml
+++ b/packages/SystemUI/res/drawable/ic_magnification_menu_small.xml
@@ -14,12 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:viewportWidth="24"
-    android:viewportHeight="24"
-    android:width="24dp"
-    android:height="24dp">
-    <path
-        android:pathData="M3 21L21 21C22.1 21 23 20.1 23 19L23 5C23 3.9 22.1 3 21 3L3 3C1.9 3 1 3.9 1 5L1 19C1 20.1 1.9 21 3 21ZM3 5L21 5L21 19L3 19L3 5ZM4 10.5L8.5 10.5L8.5 6L4 6L4 10.5Z"
-        android:fillType="evenOdd"
-        android:fillColor="#000000" />
-</vector>
\ No newline at end of file
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M9.7,21.6H17.75V13.7H9.7ZM7,40Q5.8,40 4.9,39.1Q4,38.2 4,37V11Q4,9.8 4.9,8.9Q5.8,8 7,8H41Q42.2,8 43.1,8.9Q44,9.8 44,11V37Q44,38.2 43.1,39.1Q42.2,40 41,40ZM7,37H41Q41,37 41,37Q41,37 41,37V11Q41,11 41,11Q41,11 41,11H7Q7,11 7,11Q7,11 7,11V37Q7,37 7,37Q7,37 7,37ZM7,37Q7,37 7,37Q7,37 7,37V11Q7,11 7,11Q7,11 7,11Q7,11 7,11Q7,11 7,11V37Q7,37 7,37Q7,37 7,37Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_move_magnification.xml b/packages/SystemUI/res/drawable/ic_move_magnification.xml
index 1bff559..dfedd28 100644
--- a/packages/SystemUI/res/drawable/ic_move_magnification.xml
+++ b/packages/SystemUI/res/drawable/ic_move_magnification.xml
@@ -1,43 +1,25 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2020 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) 2020 The Android Open Source Project
 
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <shape android:shape="rectangle">
-            <solid
-                android:color="@color/magnification_drag_handle_color" />
-            <size
-                android:height="@dimen/magnification_drag_view_size"
-                android:width="@dimen/magnification_drag_view_size"/>
-            <corners android:topLeftRadius="12dp"/>
+     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
 
-        </shape>
-    </item>
-    <item
-        android:gravity="center">
+          http://www.apache.org/licenses/LICENSE-2.0
 
-        <vector xmlns:android="http://schemas.android.com/apk/res/android"
-            android:viewportWidth="24"
-            android:viewportHeight="24"
-            android:width="24dp"
-            android:height="24dp">
-            <path
-                android:pathData="M13.2217 21.7734C12.8857 22.1094 12.288 22.712 12 23C12 23 11.1143 22.1094 10.7783 21.7734L8.33494 19.3301L9.55662 18.1084L12 20.5518L14.4434 18.1084L15.665 19.3301L13.2217 21.7734ZM19.3301 15.665L18.1084 14.4433L20.5518 12L18.1084 9.5566L19.3301 8.33492L21.7735 10.7783C22.1094 11.1142 22.4241 11.4241 23 12C22.4241 12.5759 22.3963 12.5988 21.7735 13.2217L19.3301 15.665ZM14.4434 14.4433C13.7714 15.1153 12.957 15.4512 12 15.4512C11.043 15.4512 10.2285 15.1153 9.55662 14.4433C8.88469 13.7714 8.54873 12.957 8.54873 12C8.54873 11.043 8.88469 10.2285 9.55662 9.5566C10.2285 8.88468 11.043 8.54871 12 8.54871C12.957 8.54871 13.7714 8.88467 14.4434 9.5566C15.1153 10.2285 15.4512 11.043 15.4512 12C15.4512 12.957 15.1153 13.7714 14.4434 14.4433ZM4.66988 15.665L2.22651 13.2217C1.89055 12.8857 1.28791 12.288 1 12C1.28791 11.712 1.89055 11.1143 2.22651 10.7783L4.66988 8.33492L5.89157 9.5566L3.4482 12L5.89157 14.4433L4.66988 15.665ZM14.4434 5.89155L12 3.44818L9.55662 5.89155L8.33494 4.66987L10.7783 2.2265C11.1389 1.86592 11.2963 1.70369 12 1C12.5758 1.57585 12.8857 1.89053 13.2217 2.2265L15.665 4.66986L14.4434 5.89155Z"
-                android:fillColor="#ffffff" />
-        </vector>
-    </item>
-</layer-list>
+     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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M12,15Q10.75,15 9.875,14.125Q9,13.25 9,12Q9,10.75 9.875,9.875Q10.75,9 12,9Q13.25,9 14.125,9.875Q15,10.75 15,12Q15,13.25 14.125,14.125Q13.25,15 12,15ZM12,22 L7.75,17.75 9.15,16.35 12,19.15 14.85,16.35 16.25,17.75ZM6.25,16.25 L2,12 6.25,7.75 7.65,9.15 4.85,12 7.65,14.85ZM9.15,7.65 L7.75,6.25 12,2 16.25,6.25 14.85,7.65 12,4.85ZM17.75,16.25 L16.35,14.85 19.15,12 16.35,9.15 17.75,7.75 22,12Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_no_sim.xml b/packages/SystemUI/res/drawable/ic_no_sim.xml
new file mode 100644
index 0000000..ccfb6ea
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_no_sim.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M20,17.175 L18,15.175V4Q18,4 18,4Q18,4 18,4H10.85L8.85,6L7.4,4.6L10,2H18Q18.825,2 19.413,2.587Q20,3.175 20,4ZM20.5,23.3 L6,8.8V20Q6,20 6,20Q6,20 6,20H18Q18,20 18,20Q18,20 18,20V17.975L20,19.975V20Q20,20.825 19.413,21.413Q18.825,22 18,22H6Q5.175,22 4.588,21.413Q4,20.825 4,20V8L4.6,7.4L0.7,3.5L2.125,2.1L21.9,21.875ZM13.525,10.675Q13.525,10.675 13.525,10.675Q13.525,10.675 13.525,10.675ZM11.65,14.475Q11.65,14.475 11.65,14.475Q11.65,14.475 11.65,14.475Q11.65,14.475 11.65,14.475Q11.65,14.475 11.65,14.475Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml b/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml
index f239a8d..420ae70 100644
--- a/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml
+++ b/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml
@@ -15,11 +15,45 @@
   -->
 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#ffffff"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#ffffff"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
     <target android:name="time_group">
         <aapt:attr name="android:animation">
             <set android:ordering="together">
                 <objectAnimator
-                    android:duration="183"
+                    android:duration="333"
                     android:propertyName="translateX"
                     android:startOffset="0"
                     android:valueFrom="0"
@@ -38,13 +72,29 @@
                 <group
                     android:name="_R_G_L_0_G"
                     android:translateX="12"
-                    android:translateY="12">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="#ffffff"
-                        android:fillType="nonZero"
-                        android:pathData=" M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c  M1.5 1.5 C1.5,1.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5c " />
+                    android:translateY="12.469">
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0"
+                        android:scaleX="1"
+                        android:scaleY="1">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_0"
+                            android:fillAlpha="1"
+                            android:fillColor="#000000"
+                            android:fillType="nonZero"
+                            android:pathData=" M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c " />
+                    </group>
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_1_G_0_T_0"
+                        android:scaleX="1"
+                        android:scaleY="1">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_1"
+                            android:fillAlpha="1"
+                            android:fillColor="#000000"
+                            android:fillType="nonZero"
+                            android:pathData=" M1.51 1.5 C1.51,1.5 -1.5,-3.02 -1.5,-3.02 C-1.5,-3.02 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.51,1.5 1.51,1.5c " />
+                    </group>
                 </group>
             </group>
             <group android:name="time_group" />
diff --git a/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml b/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml
index d46fafa..57d7902 100644
--- a/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml
+++ b/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml
@@ -15,35 +15,213 @@
   -->
 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="_R_G_L_1_G">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
         <aapt:attr name="android:animation">
             <set android:ordering="together">
                 <objectAnimator
-                    android:duration="667"
-                    android:pathData="M 12.125,34.75C 12.104,30.958 12.021,15.792 12,12"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="0">
+                    android:duration="250"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#ffffff"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
                     <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_0_G">
+    <target android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0">
         <aapt:attr name="android:animation">
             <set android:ordering="together">
                 <objectAnimator
-                    android:duration="517"
-                    android:pathData="M 12,12C 12.021,8.312 12.104,-6.436999999999999 12.125,-10.125"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="0">
+                    android:duration="383"
+                    android:propertyName="scaleX"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1.1500000000000001"
+                    android:valueType="floatType">
                     <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.4,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="383"
+                    android:propertyName="scaleY"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1.1500000000000001"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.4,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="767"
+                    android:propertyName="scaleX"
+                    android:startOffset="383"
+                    android:valueFrom="1.1500000000000001"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.199,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="767"
+                    android:propertyName="scaleY"
+                    android:startOffset="383"
+                    android:valueFrom="1.1500000000000001"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.199,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="200"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c "
+                    android:valueTo="M-1.74 -2.93 C-1.74,-2.93 -2.06,-7.3 -2.06,-7.3 C-2.14,-8.99 -1.15,-10 0,-10 C1.15,-10 2.08,-8.88 2.09,-7.3 C2.09,-7.3 1.74,-3.09 1.74,-3.09 C1.74,-3.09 9.44,2.79 9.44,2.79 C9.44,2.79 9.44,4.79 9.44,4.79 C9.44,4.79 1.69,1.57 1.69,1.57 C1.69,1.57 -1.74,-2.93 -1.74,-2.93c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="217"
+                    android:propertyName="pathData"
+                    android:startOffset="200"
+                    android:valueFrom="M-1.74 -2.93 C-1.74,-2.93 -2.06,-7.3 -2.06,-7.3 C-2.14,-8.99 -1.15,-10 0,-10 C1.15,-10 2.08,-8.88 2.09,-7.3 C2.09,-7.3 1.74,-3.09 1.74,-3.09 C1.74,-3.09 9.44,2.79 9.44,2.79 C9.44,2.79 9.44,4.79 9.44,4.79 C9.44,4.79 1.69,1.57 1.69,1.57 C1.69,1.57 -1.74,-2.93 -1.74,-2.93c "
+                    android:valueTo="M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="217"
+                    android:propertyName="pathData"
+                    android:startOffset="417"
+                    android:valueFrom="M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c "
+                    android:valueTo="M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.35,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#ffffff"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_1_G_0_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="383"
+                    android:propertyName="scaleX"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1.1500000000000001"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.4,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="383"
+                    android:propertyName="scaleY"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1.1500000000000001"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.4,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="767"
+                    android:propertyName="scaleX"
+                    android:startOffset="383"
+                    android:valueFrom="1.1500000000000001"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.199,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="767"
+                    android:propertyName="scaleY"
+                    android:startOffset="383"
+                    android:valueFrom="1.1500000000000001"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.199,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="200"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M1.51 1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02 C-1.5,-3.02 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.51,1.49 1.51,1.49c "
+                    android:valueTo="M1.69 1.58 C1.69,1.58 -1.74,-2.92 -1.74,-2.92 C-1.74,-2.92 -9.44,2.79 -9.44,2.79 C-9.44,2.79 -9.44,4.79 -9.44,4.79 C-9.44,4.79 -1.67,1.42 -1.67,1.42 C-1.67,1.42 -1.11,7.28 -1.11,7.28 C-1.11,7.28 -2.94,8.78 -2.94,8.78 C-2.94,8.78 -2.92,10 -2.92,10 C-2.92,10 0,9 0,9 C0,9 2.92,10 2.92,10 C2.92,10 2.91,8.78 2.91,8.78 C2.91,8.78 1.08,7.28 1.08,7.28 C1.08,7.28 1.69,1.58 1.69,1.58c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="217"
+                    android:propertyName="pathData"
+                    android:startOffset="200"
+                    android:valueFrom="M1.69 1.58 C1.69,1.58 -1.74,-2.92 -1.74,-2.92 C-1.74,-2.92 -9.44,2.79 -9.44,2.79 C-9.44,2.79 -9.44,4.79 -9.44,4.79 C-9.44,4.79 -1.67,1.42 -1.67,1.42 C-1.67,1.42 -1.11,7.28 -1.11,7.28 C-1.11,7.28 -2.94,8.78 -2.94,8.78 C-2.94,8.78 -2.92,10 -2.92,10 C-2.92,10 0,9 0,9 C0,9 2.92,10 2.92,10 C2.92,10 2.91,8.78 2.91,8.78 C2.91,8.78 1.08,7.28 1.08,7.28 C1.08,7.28 1.69,1.58 1.69,1.58c "
+                    android:valueTo="M1.51 1.5 C1.51,1.5 -1.5,-3.02 -1.5,-3.02 C-1.5,-3.02 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.51,1.5 1.51,1.5c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="217"
+                    android:propertyName="pathData"
+                    android:startOffset="417"
+                    android:valueFrom="M1.51 1.5 C1.51,1.5 -1.5,-3.02 -1.5,-3.02 C-1.5,-3.02 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.51,1.5 1.51,1.5c "
+                    android:valueTo="M1.51 1.5 C1.51,1.5 -1.5,-3.02 -1.5,-3.02 C-1.5,-3.02 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.51,1.5 1.51,1.5c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.35,1 1.0,1.0" />
                     </aapt:attr>
                 </objectAnimator>
             </set>
@@ -53,7 +231,7 @@
         <aapt:attr name="android:animation">
             <set android:ordering="together">
                 <objectAnimator
-                    android:duration="683"
+                    android:duration="1167"
                     android:propertyName="translateX"
                     android:startOffset="0"
                     android:valueFrom="0"
@@ -70,26 +248,31 @@
             android:viewportWidth="24">
             <group android:name="_R_G">
                 <group
-                    android:name="_R_G_L_1_G"
-                    android:translateX="12.125"
-                    android:translateY="34.75">
-                    <path
-                        android:name="_R_G_L_1_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="#ffffff"
-                        android:fillType="nonZero"
-                        android:pathData=" M10 4 C10,4 10,2 10,2 C10,2 1.5,-3 1.5,-3 C1.5,-3 1.5,-8.5 1.5,-8.5 C1.5,-9.33 0.83,-10 0,-10 C-0.83,-10 -1.5,-9.33 -1.5,-8.5 C-1.5,-8.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5 C1.5,1.5 10,4 10,4c " />
-                </group>
-                <group
                     android:name="_R_G_L_0_G"
                     android:translateX="12"
-                    android:translateY="12">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="#ffffff"
-                        android:fillType="nonZero"
-                        android:pathData=" M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c  M1.5 1.5 C1.5,1.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5c " />
+                    android:translateY="12.469">
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0"
+                        android:scaleX="1"
+                        android:scaleY="1">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_0"
+                            android:fillAlpha="1"
+                            android:fillColor="#ffffff"
+                            android:fillType="nonZero"
+                            android:pathData=" M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c " />
+                    </group>
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_1_G_0_T_0"
+                        android:scaleX="1"
+                        android:scaleY="1">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_1"
+                            android:fillAlpha="1"
+                            android:fillColor="#ffffff"
+                            android:fillType="nonZero"
+                            android:pathData=" M1.51 1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02 C-1.5,-3.02 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.51,1.49 1.51,1.49c " />
+                    </group>
                 </group>
             </group>
             <group android:name="time_group" />
diff --git a/packages/SystemUI/res/drawable/qs_data_saver_icon_off.xml b/packages/SystemUI/res/drawable/qs_data_saver_icon_off.xml
new file mode 100644
index 0000000..57777a6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_data_saver_icon_off.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="133"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="150"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:pivotY="1"
+                    android:rotation="180"
+                    android:translateX="12"
+                    android:translateY="10.984">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:rotation="1440"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M9.15 4.05 C9.15,4.05 6.55,2.55 6.55,2.55 C6.7,2.13 6.81,1.71 6.89,1.29 C6.96,0.86 7,0.43 7,0 C7,-1.77 6.43,-3.31 5.3,-4.62 C4.17,-5.94 2.73,-6.72 1,-6.95 C1,-6.95 1,-9.95 1,-9.95 C3.57,-9.7 5.71,-8.62 7.43,-6.72 C9.14,-4.82 10,-2.58 10,0 C10,0.7 9.94,1.39 9.81,2.08 C9.69,2.76 9.47,3.42 9.15,4.05c  M0 10 C-1.38,10 -2.68,9.74 -3.9,9.21 C-5.12,8.69 -6.17,7.98 -7.07,7.08 C-7.97,6.18 -8.69,5.12 -9.21,3.9 C-9.74,2.68 -10,1.38 -10,0 C-10,-2.58 -9.14,-4.82 -7.42,-6.72 C-5.71,-8.62 -3.57,-9.7 -1,-9.95 C-1,-9.95 -1,-6.95 -1,-6.95 C-2.73,-6.72 -4.17,-5.94 -5.3,-4.62 C-6.43,-3.31 -7,-1.77 -7,0 C-7,1.95 -6.32,3.6 -4.96,4.96 C-3.6,6.32 -1.95,7 0,7 C1.07,7 2.08,6.78 3.04,6.33 C4,5.88 4.82,5.23 5.5,4.4 C5.5,4.4 8.1,5.9 8.1,5.9 C7.15,7.2 5.97,8.21 4.55,8.93 C3.13,9.64 1.62,10 0,10c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_data_saver_icon_on.xml b/packages/SystemUI/res/drawable/qs_data_saver_icon_on.xml
new file mode 100644
index 0000000..b376413
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_data_saver_icon_on.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="333"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M1.02 2 C1.02,2 1,2 1,2 C1,2 1,1.98 1,1.98 C1,1.98 -1,1.98 -1,1.98 C-1,1.98 -1,2 -1,2 C-1,2 -1,2 -1,2 C-1,2 -1,0 -1,0 C-1,0 -1,0 -1,0 C-1,0 -1,0 -1,0 C-1,0 1,0 1,0 C1,0 1,0 1,0 C1,0 1.02,0 1.02,0 C1.02,0 1.02,2 1.02,2c "
+                    android:valueTo="M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.2,0.2 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="500"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="613.191"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.086,0.422 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="rotation"
+                    android:startOffset="500"
+                    android:valueFrom="613.191"
+                    android:valueTo="720"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.334,1.012 0.833,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="933"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:translateX="12"
+                    android:translateY="10.75">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M1.02 2 C1.02,2 1,2 1,2 C1,2 1,1.98 1,1.98 C1,1.98 -1,1.98 -1,1.98 C-1,1.98 -1,2 -1,2 C-1,2 -1,2 -1,2 C-1,2 -1,0 -1,0 C-1,0 -1,0 -1,0 C-1,0 -1,0 -1,0 C-1,0 1,0 1,0 C1,0 1,0 1,0 C1,0 1.02,0 1.02,0 C1.02,0 1.02,2 1.02,2c " />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:rotation="0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M9.15 4.05 C9.15,4.05 6.55,2.55 6.55,2.55 C6.7,2.13 6.81,1.71 6.89,1.29 C6.96,0.86 7,0.43 7,0 C7,-1.77 6.43,-3.31 5.3,-4.62 C4.17,-5.94 2.73,-6.72 1,-6.95 C1,-6.95 1,-9.95 1,-9.95 C3.57,-9.7 5.71,-8.62 7.43,-6.72 C9.14,-4.82 10,-2.58 10,0 C10,0.7 9.94,1.39 9.81,2.08 C9.69,2.76 9.47,3.42 9.15,4.05c  M0 10 C-1.38,10 -2.68,9.74 -3.9,9.21 C-5.12,8.69 -6.17,7.98 -7.07,7.08 C-7.97,6.18 -8.69,5.12 -9.21,3.9 C-9.74,2.68 -10,1.38 -10,0 C-10,-2.58 -9.14,-4.82 -7.42,-6.72 C-5.71,-8.62 -3.57,-9.7 -1,-9.95 C-1,-9.95 -1,-6.95 -1,-6.95 C-2.73,-6.72 -4.17,-5.94 -5.3,-4.62 C-6.43,-3.31 -7,-1.77 -7,0 C-7,1.95 -6.32,3.6 -4.96,4.96 C-3.6,6.32 -1.95,7 0,7 C1.07,7 2.08,6.78 3.04,6.33 C4,5.88 4.82,5.23 5.5,4.4 C5.5,4.4 8.1,5.9 8.1,5.9 C7.15,7.2 5.97,8.21 4.55,8.93 C3.13,9.64 1.62,10 0,10c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_extra_dim_icon_off.xml b/packages/SystemUI/res/drawable/qs_extra_dim_icon_off.xml
new file mode 100644
index 0000000..b0f85e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_extra_dim_icon_off.xml
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="strokeColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#ffffff"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#ffffff"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M93 39.5 C93,39.55 93,41.52 93,44 C93,46.49 93,48.58 93,48.5 C90.52,48.5 88.5,46.49 88.5,44 C88.5,41.52 90.52,39.5 93,39.5c M94 37 C94,37 92,37 92,37 C92,37 92,35.44 92,35.44 C92,35.44 94,35.44 94,35.44 C94,35.44 94,37 94,37c M86 43 C86,43 86,45 86,45 C86,45 84.31,45 84.31,45 C84.31,45 84.31,43 84.31,43 C84.31,43 86,43 86,43c M92 51 C92,51 94,51 94,51 C94,51 94,52.69 94,52.69 C94,52.69 92,52.69 92,52.69 C92,52.69 92,51 92,51c M100 45 C100,45 100,43 100,43 C100,43 101.75,43 101.75,43 C101.75,43 101.75,45 101.75,45 C101.75,45 100,45 100,45c M86.07 38.57 C86.07,38.57 87.48,37.16 87.48,37.16 C87.48,37.16 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 86.07,38.57 86.07,38.57c M87.57 50.87 C87.57,50.87 86.16,49.46 86.16,49.46 C86.16,49.46 87.34,48.24 87.34,48.24 C87.34,48.24 88.76,49.66 88.76,49.66 C88.76,49.66 87.57,50.87 87.57,50.87c M99.9 49.43 C99.9,49.43 98.49,50.84 98.49,50.84 C98.49,50.84 97.24,49.66 97.24,49.66 C97.24,49.66 98.66,48.24 98.66,48.24 C98.66,48.24 99.9,49.43 99.9,49.43c M98.52 37.13 C98.52,37.13 99.93,38.54 99.93,38.54 C99.93,38.54 98.66,39.76 98.66,39.76 C98.66,39.76 97.24,38.34 97.24,38.34 C97.24,38.34 98.52,37.13 98.52,37.13c "
+                    android:valueTo="M93 39.5 C95.49,39.5 97.5,41.52 97.5,44 C97.5,46.49 95.49,48.5 93,48.5 C90.52,48.5 88.5,46.49 88.5,44 C88.5,41.52 90.52,39.5 93,39.5c M94 37 C94,37 92,37 92,37 C92,37 92,33 92,33 C92,33 94,33 94,33 C94,33 94,37 94,37c M86 43 C86,43 86,45 86,45 C86,45 82,45 82,45 C82,45 82,43 82,43 C82,43 86,43 86,43c M92 51 C92,51 94,51 94,51 C94,51 94,55 94,55 C94,55 92,55 92,55 C92,55 92,51 92,51c M100 45 C100,45 100,43 100,43 C100,43 104,43 104,43 C104,43 104,45 104,45 C104,45 100,45 100,45c M85.22 37.64 C85.22,37.64 86.64,36.22 86.64,36.22 C86.64,36.22 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 85.22,37.64 85.22,37.64c M86.64 51.78 C86.64,51.78 85.22,50.36 85.22,50.36 C85.22,50.36 87.34,48.24 87.34,48.24 C87.34,48.24 88.76,49.66 88.76,49.66 C88.76,49.66 86.64,51.78 86.64,51.78c M100.78 50.36 C100.78,50.36 99.36,51.78 99.36,51.78 C99.36,51.78 97.24,49.66 97.24,49.66 C97.24,49.66 98.66,48.24 98.66,48.24 C98.66,48.24 100.78,50.36 100.78,50.36c M99.36 36.22 C99.36,36.22 100.78,37.64 100.78,37.64 C100.78,37.64 98.66,39.76 98.66,39.76 C98.66,39.76 97.24,38.34 97.24,38.34 C97.24,38.34 99.36,36.22 99.36,36.22c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#ffffff"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M94 37 C94,37 92,37 92,37 C92,37 92,35.44 92,35.44 C92,35.44 94,35.44 94,35.44 C94,35.44 94,37 94,37c M86 43 C86,43 86,45 86,45 C86,45 84.31,45 84.31,45 C84.31,45 84.31,43 84.31,43 C84.31,43 86,43 86,43c M92 51 C92,51 94,51 94,51 C94,51 94,52.69 94,52.69 C94,52.69 92,52.69 92,52.69 C92,52.69 92,51 92,51c M100 45 C100,45 100,43 100,43 C100,43 101.75,43 101.75,43 C101.75,43 101.75,45 101.75,45 C101.75,45 100,45 100,45c "
+                    android:valueTo="M94 37 C94,37 92,37 92,37 C92,37 92,33 92,33 C92,33 94,33 94,33 C94,33 94,37 94,37c M86 43 C86,43 86,45 86,45 C86,45 82,45 82,45 C82,45 82,43 82,43 C82,43 86,43 86,43c M92 51 C92,51 94,51 94,51 C94,51 94,55 94,55 C94,55 92,55 92,55 C92,55 92,51 92,51c M100 45 C100,45 100,43 100,43 C100,43 104,43 104,43 C104,43 104,45 104,45 C104,45 100,45 100,45c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#ffffff"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M86.07 38.57 C86.07,38.57 87.48,37.16 87.48,37.16 C87.48,37.16 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 86.07,38.57 86.07,38.57c M87.57 50.87 C87.57,50.87 86.16,49.46 86.16,49.46 C86.16,49.46 87.34,48.24 87.34,48.24 C87.34,48.24 88.76,49.66 88.76,49.66 C88.76,49.66 87.57,50.87 87.57,50.87c M99.9 49.43 C99.9,49.43 98.49,50.84 98.49,50.84 C98.49,50.84 97.24,49.66 97.24,49.66 C97.24,49.66 98.66,48.24 98.66,48.24 C98.66,48.24 99.9,49.43 99.9,49.43c M98.52 37.13 C98.52,37.13 99.93,38.54 99.93,38.54 C99.93,38.54 98.66,39.76 98.66,39.76 C98.66,39.76 97.24,38.34 97.24,38.34 C97.24,38.34 98.52,37.13 98.52,37.13c "
+                    android:valueTo="M85.22 37.64 C85.22,37.64 86.64,36.22 86.64,36.22 C86.64,36.22 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 85.22,37.64 85.22,37.64c M86.64 51.78 C86.64,51.78 85.22,50.36 85.22,50.36 C85.22,50.36 87.34,48.24 87.34,48.24 C87.34,48.24 88.76,49.66 88.76,49.66 C88.76,49.66 86.64,51.78 86.64,51.78c M100.78 50.36 C100.78,50.36 99.36,51.78 99.36,51.78 C99.36,51.78 97.24,49.66 97.24,49.66 C97.24,49.66 98.66,48.24 98.66,48.24 C98.66,48.24 100.78,50.36 100.78,50.36c M99.36 36.22 C99.36,36.22 100.78,37.64 100.78,37.64 C100.78,37.64 98.66,39.76 98.66,39.76 C98.66,39.76 97.24,38.34 97.24,38.34 C97.24,38.34 99.36,36.22 99.36,36.22c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="517"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:translateX="-81"
+                    android:translateY="-32">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:pathData=" M93 40 C95.21,40 97,41.79 97,44 C97,46.21 95.21,48 93,48 C90.79,48 89,46.21 89,44 C89,41.79 90.79,40 93,40c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#000000"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="2" />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="-81"
+                    android:translateY="-32">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#000000"
+                        android:fillType="nonZero"
+                        android:pathData=" M93 39.5 C93,39.55 93,41.52 93,44 C93,46.49 93,48.58 93,48.5 C90.52,48.5 88.5,46.49 88.5,44 C88.5,41.52 90.52,39.5 93,39.5c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#000000"
+                        android:fillType="nonZero"
+                        android:pathData=" M94 37 C94,37 92,37 92,37 C92,37 92,35.44 92,35.44 C92,35.44 94,35.44 94,35.44 C94,35.44 94,37 94,37c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#000000"
+                        android:fillType="nonZero"
+                        android:pathData=" M86.07 38.57 C86.07,38.57 87.48,37.16 87.48,37.16 C87.48,37.16 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 86.07,38.57 86.07,38.57c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_extra_dim_icon_on.xml b/packages/SystemUI/res/drawable/qs_extra_dim_icon_on.xml
new file mode 100644
index 0000000..5546b6f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_extra_dim_icon_on.xml
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="strokeColor"
+                    android:startOffset="0"
+                    android:valueFrom="#ffffff"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#ffffff"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M93 39.5 C95.49,39.5 97.5,41.52 97.5,44 C97.5,46.49 95.49,48.5 93,48.5 C90.52,48.5 88.5,46.49 88.5,44 C88.5,41.52 90.52,39.5 93,39.5c M94 37 C94,37 92,37 92,37 C92,37 92,33 92,33 C92,33 94,33 94,33 C94,33 94,37 94,37c M86 43 C86,43 86,45 86,45 C86,45 82,45 82,45 C82,45 82,43 82,43 C82,43 86,43 86,43c M92 51 C92,51 94,51 94,51 C94,51 94,55 94,55 C94,55 92,55 92,55 C92,55 92,51 92,51c M100 45 C100,45 100,43 100,43 C100,43 104,43 104,43 C104,43 104,45 104,45 C104,45 100,45 100,45c M85.22 37.64 C85.22,37.64 86.64,36.22 86.64,36.22 C86.64,36.22 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 85.22,37.64 85.22,37.64c M86.64 51.78 C86.64,51.78 85.22,50.36 85.22,50.36 C85.22,50.36 87.34,48.24 87.34,48.24 C87.34,48.24 88.76,49.66 88.76,49.66 C88.76,49.66 86.64,51.78 86.64,51.78c M100.78 50.36 C100.78,50.36 99.36,51.78 99.36,51.78 C99.36,51.78 97.24,49.66 97.24,49.66 C97.24,49.66 98.66,48.24 98.66,48.24 C98.66,48.24 100.78,50.36 100.78,50.36c M99.36 36.22 C99.36,36.22 100.78,37.64 100.78,37.64 C100.78,37.64 98.66,39.76 98.66,39.76 C98.66,39.76 97.24,38.34 97.24,38.34 C97.24,38.34 99.36,36.22 99.36,36.22c "
+                    android:valueTo="M93 39.5 C93,39.55 93,41.52 93,44 C93,46.49 93,48.58 93,48.5 C90.52,48.5 88.5,46.49 88.5,44 C88.5,41.52 90.52,39.5 93,39.5c M94 37 C94,37 92,37 92,37 C92,37 92,35.44 92,35.44 C92,35.44 94,35.44 94,35.44 C94,35.44 94,37 94,37c M86 43 C86,43 86,45 86,45 C86,45 84.31,45 84.31,45 C84.31,45 84.31,43 84.31,43 C84.31,43 86,43 86,43c M92 51 C92,51 94,51 94,51 C94,51 94,52.69 94,52.69 C94,52.69 92,52.69 92,52.69 C92,52.69 92,51 92,51c M100 45 C100,45 100,43 100,43 C100,43 101.75,43 101.75,43 C101.75,43 101.75,45 101.75,45 C101.75,45 100,45 100,45c M86.07 38.57 C86.07,38.57 87.48,37.16 87.48,37.16 C87.48,37.16 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 86.07,38.57 86.07,38.57c M87.57 50.87 C87.57,50.87 86.16,49.46 86.16,49.46 C86.16,49.46 87.34,48.24 87.34,48.24 C87.34,48.24 88.76,49.66 88.76,49.66 C88.76,49.66 87.57,50.87 87.57,50.87c M99.9 49.43 C99.9,49.43 98.49,50.84 98.49,50.84 C98.49,50.84 97.24,49.66 97.24,49.66 C97.24,49.66 98.66,48.24 98.66,48.24 C98.66,48.24 99.9,49.43 99.9,49.43c M98.52 37.13 C98.52,37.13 99.93,38.54 99.93,38.54 C99.93,38.54 98.66,39.76 98.66,39.76 C98.66,39.76 97.24,38.34 97.24,38.34 C97.24,38.34 98.52,37.13 98.52,37.13c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#ffffff"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M94 37 C94,37 92,37 92,37 C92,37 92,33 92,33 C92,33 94,33 94,33 C94,33 94,37 94,37c M86 43 C86,43 86,45 86,45 C86,45 82,45 82,45 C82,45 82,43 82,43 C82,43 86,43 86,43c M92 51 C92,51 94,51 94,51 C94,51 94,55 94,55 C94,55 92,55 92,55 C92,55 92,51 92,51c M100 45 C100,45 100,43 100,43 C100,43 104,43 104,43 C104,43 104,45 104,45 C104,45 100,45 100,45c "
+                    android:valueTo="M94 37 C94,37 92,37 92,37 C92,37 92,35.44 92,35.44 C92,35.44 94,35.44 94,35.44 C94,35.44 94,37 94,37c M86 43 C86,43 86,45 86,45 C86,45 84.31,45 84.31,45 C84.31,45 84.31,43 84.31,43 C84.31,43 86,43 86,43c M92 51 C92,51 94,51 94,51 C94,51 94,52.69 94,52.69 C94,52.69 92,52.69 92,52.69 C92,52.69 92,51 92,51c M100 45 C100,45 100,43 100,43 C100,43 101.75,43 101.75,43 C101.75,43 101.75,45 101.75,45 C101.75,45 100,45 100,45c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#ffffff"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="350"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M85.22 37.64 C85.22,37.64 86.64,36.22 86.64,36.22 C86.64,36.22 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 85.22,37.64 85.22,37.64c M86.64 51.78 C86.64,51.78 85.22,50.36 85.22,50.36 C85.22,50.36 87.34,48.24 87.34,48.24 C87.34,48.24 88.76,49.66 88.76,49.66 C88.76,49.66 86.64,51.78 86.64,51.78c M100.78 50.36 C100.78,50.36 99.36,51.78 99.36,51.78 C99.36,51.78 97.24,49.66 97.24,49.66 C97.24,49.66 98.66,48.24 98.66,48.24 C98.66,48.24 100.78,50.36 100.78,50.36c M99.36 36.22 C99.36,36.22 100.78,37.64 100.78,37.64 C100.78,37.64 98.66,39.76 98.66,39.76 C98.66,39.76 97.24,38.34 97.24,38.34 C97.24,38.34 99.36,36.22 99.36,36.22c "
+                    android:valueTo="M86.07 38.57 C86.07,38.57 87.48,37.16 87.48,37.16 C87.48,37.16 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 86.07,38.57 86.07,38.57c M87.57 50.87 C87.57,50.87 86.16,49.46 86.16,49.46 C86.16,49.46 87.34,48.24 87.34,48.24 C87.34,48.24 88.76,49.66 88.76,49.66 C88.76,49.66 87.57,50.87 87.57,50.87c M99.9 49.43 C99.9,49.43 98.49,50.84 98.49,50.84 C98.49,50.84 97.24,49.66 97.24,49.66 C97.24,49.66 98.66,48.24 98.66,48.24 C98.66,48.24 99.9,49.43 99.9,49.43c M98.52 37.13 C98.52,37.13 99.93,38.54 99.93,38.54 C99.93,38.54 98.66,39.76 98.66,39.76 C98.66,39.76 97.24,38.34 97.24,38.34 C97.24,38.34 98.52,37.13 98.52,37.13c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="517"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:translateX="-81"
+                    android:translateY="-32">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:pathData=" M93 40 C95.21,40 97,41.79 97,44 C97,46.21 95.21,48 93,48 C90.79,48 89,46.21 89,44 C89,41.79 90.79,40 93,40c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#ffffff"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="2" />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="-81"
+                    android:translateY="-32">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M93 39.5 C95.49,39.5 97.5,41.52 97.5,44 C97.5,46.49 95.49,48.5 93,48.5 C90.52,48.5 88.5,46.49 88.5,44 C88.5,41.52 90.52,39.5 93,39.5c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M94 37 C94,37 92,37 92,37 C92,37 92,33 92,33 C92,33 94,33 94,33 C94,33 94,37 94,37c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M85.22 37.64 C85.22,37.64 86.64,36.22 86.64,36.22 C86.64,36.22 88.76,38.34 88.76,38.34 C88.76,38.34 87.34,39.76 87.34,39.76 C87.34,39.76 85.22,37.64 85.22,37.64c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_flashlight_icon_off.xml b/packages/SystemUI/res/drawable/qs_flashlight_icon_off.xml
new file mode 100644
index 0000000..157e67a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_flashlight_icon_off.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M0 2.02 C0.42,2.02 0.77,1.88 1.05,1.59 C1.35,1.29 1.5,0.94 1.5,0.52 C1.5,0.1 1.35,-0.25 1.05,-0.53 C0.77,-0.83 0.42,-0.98 0,-0.98 C-0.42,-0.98 -0.78,-0.83 -1.08,-0.53 C-1.36,-0.25 -1.5,0.1 -1.5,0.52 C-1.5,0.94 -1.36,1.29 -1.08,1.59 C-0.78,1.88 -0.42,2.02 0,2.02c M0 8.62 C-0.42,8.62 -2.78,8.82 -3.07,8.54 C-3.36,8.24 -3.37,-1.87 -3.37,-2.28 C-4.25,-2.69 -4.29,-5.2 -4.01,-5.48 C-3.71,-5.78 -0.42,-5.75 0,-5.75 C0.42,-5.75 4.39,-5.78 4.36,-5.36 C4.22,-2.97 4.47,-3.03 3.34,-1.78 C3.07,-1.48 3.32,8.21 3.02,8.51 C2.74,8.79 0.42,8.62 0,8.62c "
+                    android:valueTo="M0 3 C0.42,3 0.77,2.86 1.05,2.58 C1.35,2.28 1.5,1.92 1.5,1.5 C1.5,1.08 1.35,0.73 1.05,0.45 C0.77,0.15 0.42,0 0,0 C-0.42,0 -0.78,0.15 -1.08,0.45 C-1.36,0.73 -1.5,1.08 -1.5,1.5 C-1.5,1.92 -1.36,2.28 -1.08,2.58 C-0.78,2.86 -0.42,3 0,3c M0 8.62 C-0.42,8.62 -2.24,8.83 -2.54,8.55 C-2.83,8.25 -2.86,9.1 -2.86,8.69 C-2.86,8.27 -3.02,8.85 -2.74,8.57 C-2.44,8.26 -0.43,8.31 -0.02,8.31 C0.4,8.31 2.4,8.17 2.68,8.47 C2.98,8.75 2.93,8.33 2.93,8.75 C2.93,9.17 3.32,8.21 3.02,8.51 C2.74,8.79 0.42,8.62 0,8.62c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="1000"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:pivotY="24"
+                    android:scaleX="0.33332999999999996"
+                    android:scaleY="0.33332999999999996"
+                    android:translateX="12"
+                    android:translateY="-4">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#1f1f1f"
+                        android:fillType="nonZero"
+                        android:pathData=" M-12 -15 C-12,-15 12,-15 12,-15 C12,-15 12,-13.8 12,-13.8 C12,-13.8 6,-4.8 6,-4.8 C6,-4.8 6,24 6,24 C6,24 -6,24 -6,24 C-6,24 -6,-4.8 -6,-4.8 C-6,-4.8 -12,-13.8 -12,-13.8 C-12,-13.8 -12,-15 -12,-15c  M12 -21 C12,-21 -12,-21 -12,-21 C-12,-21 -12,-24 -12,-24 C-12,-24 12,-24 12,-24 C12,-24 12,-21 12,-21c  M-12 -3 C-12,-3 -12,30 -12,30 C-12,30 12,30 12,30 C12,30 12,-3 12,-3 C12,-3 18,-12 18,-12 C18,-12 18,-30 18,-30 C18,-30 -18,-30 -18,-30 C-18,-30 -18,-12 -18,-12 C-18,-12 -12,-3 -12,-3c " />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#1f1f1f"
+                        android:fillType="nonZero"
+                        android:pathData=" M0 2.02 C0.42,2.02 0.77,1.88 1.05,1.59 C1.35,1.29 1.5,0.94 1.5,0.52 C1.5,0.1 1.35,-0.25 1.05,-0.53 C0.77,-0.83 0.42,-0.98 0,-0.98 C-0.42,-0.98 -0.78,-0.83 -1.08,-0.53 C-1.36,-0.25 -1.5,0.1 -1.5,0.52 C-1.5,0.94 -1.36,1.29 -1.08,1.59 C-0.78,1.88 -0.42,2.02 0,2.02c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_flashlight_icon_on.xml b/packages/SystemUI/res/drawable/qs_flashlight_icon_on.xml
new file mode 100644
index 0000000..22f5e00
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_flashlight_icon_on.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M0 3 C0.42,3 0.77,2.86 1.05,2.58 C1.35,2.28 1.5,1.92 1.5,1.5 C1.5,1.08 1.35,0.73 1.05,0.45 C0.77,0.15 0.42,0 0,0 C-0.42,0 -0.78,0.15 -1.08,0.45 C-1.36,0.73 -1.5,1.08 -1.5,1.5 C-1.5,1.92 -1.36,2.28 -1.08,2.58 C-0.78,2.86 -0.42,3 0,3c M0 8.62 C-0.42,8.62 -2.24,8.83 -2.54,8.55 C-2.83,8.25 -2.86,9.1 -2.86,8.69 C-2.86,8.27 -3.02,8.85 -2.74,8.57 C-2.44,8.26 -0.43,8.31 -0.02,8.31 C0.4,8.31 2.4,8.17 2.68,8.47 C2.98,8.75 2.93,8.33 2.93,8.75 C2.93,9.17 3.32,8.21 3.02,8.51 C2.74,8.79 0.42,8.62 0,8.62c "
+                    android:valueTo="M0 2.02 C0.42,2.02 0.77,1.88 1.05,1.59 C1.35,1.29 1.5,0.94 1.5,0.52 C1.5,0.1 1.35,-0.25 1.05,-0.53 C0.77,-0.83 0.42,-0.98 0,-0.98 C-0.42,-0.98 -0.78,-0.83 -1.08,-0.53 C-1.36,-0.25 -1.5,0.1 -1.5,0.52 C-1.5,0.94 -1.36,1.29 -1.08,1.59 C-0.78,1.88 -0.42,2.02 0,2.02c M0 8.62 C-0.42,8.62 -2.78,8.82 -3.07,8.54 C-3.36,8.24 -3.37,-1.87 -3.37,-2.28 C-4.25,-2.69 -4.29,-5.2 -4.01,-5.48 C-3.71,-5.78 -0.42,-5.75 0,-5.75 C0.42,-5.75 4.39,-5.78 4.36,-5.36 C4.22,-2.97 4.47,-3.03 3.34,-1.78 C3.07,-1.48 3.32,8.21 3.02,8.51 C2.74,8.79 0.42,8.62 0,8.62c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="1000"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:pivotY="24"
+                    android:scaleX="0.33332999999999996"
+                    android:scaleY="0.33332999999999996"
+                    android:translateX="12"
+                    android:translateY="-4">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#1f1f1f"
+                        android:fillType="nonZero"
+                        android:pathData=" M-12 -15 C-12,-15 12,-15 12,-15 C12,-15 12,-13.8 12,-13.8 C12,-13.8 6,-4.8 6,-4.8 C6,-4.8 6,24 6,24 C6,24 -6,24 -6,24 C-6,24 -6,-4.8 -6,-4.8 C-6,-4.8 -12,-13.8 -12,-13.8 C-12,-13.8 -12,-15 -12,-15c  M12 -21 C12,-21 -12,-21 -12,-21 C-12,-21 -12,-24 -12,-24 C-12,-24 12,-24 12,-24 C12,-24 12,-21 12,-21c  M-12 -3 C-12,-3 -12,30 -12,30 C-12,30 12,30 12,30 C12,30 12,-3 12,-3 C12,-3 18,-12 18,-12 C18,-12 18,-30 18,-30 C18,-30 -18,-30 -18,-30 C-18,-30 -18,-12 -18,-12 C-18,-12 -12,-3 -12,-3c " />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#1f1f1f"
+                        android:fillType="nonZero"
+                        android:pathData=" M0 3 C0.42,3 0.77,2.86 1.05,2.58 C1.35,2.28 1.5,1.92 1.5,1.5 C1.5,1.08 1.35,0.73 1.05,0.45 C0.77,0.15 0.42,0 0,0 C-0.42,0 -0.78,0.15 -1.08,0.45 C-1.36,0.73 -1.5,1.08 -1.5,1.5 C-1.5,1.92 -1.36,2.28 -1.08,2.58 C-0.78,2.86 -0.42,3 0,3c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_nightlight_icon_off.xml b/packages/SystemUI/res/drawable/qs_nightlight_icon_off.xml
new file mode 100644
index 0000000..0769a85
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_nightlight_icon_off.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+    Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="283"
+                    android:propertyName="translateY"
+                    android:startOffset="0"
+                    android:valueFrom="12.125"
+                    android:valueTo="12.312"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="283"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="-45"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="300"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G_T_1"
+                    android:rotation="-45"
+                    android:translateX="12.875"
+                    android:translateY="12.125">
+                    <group
+                        android:name="_R_G_L_0_G"
+                        android:translateX="-2.375">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_0"
+                            android:pathData=" M3.33 8.62 C2.09,8.68 0.59,8.47 -0.64,7.95 C-1.65,7.53 -2.75,6.9 -3.59,6.09 C-4.38,5.32 -5.19,4.17 -5.61,3.08 C-6.04,1.99 -6.25,0.83 -6.25,-0.39 C-6.25,-1.72 -5.98,-2.85 -5.55,-3.94 C-5.13,-5.02 -4.37,-6 -3.59,-6.78 C-2.63,-7.75 -1.63,-8.28 -0.52,-8.77 C0.48,-9.2 2.04,-9.41 3.15,-9.38 C4.22,-9.35 4.94,-9.16 5.81,-8.79 C5.95,-8.73 6.28,-8.6 6.18,-8.55 C3.44,-6.63 1.83,-3.66 1.83,-0.39 C1.83,2.53 3.47,5.72 6.15,7.86 C6.16,7.9 6.03,7.97 5.91,8.04 C5.12,8.44 4.31,8.56 3.33,8.62c "
+                            android:strokeAlpha="1"
+                            android:strokeColor="#ffffff"
+                            android:strokeLineCap="round"
+                            android:strokeLineJoin="round"
+                            android:strokeWidth="2" />
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_nightlight_icon_on.xml b/packages/SystemUI/res/drawable/qs_nightlight_icon_on.xml
new file mode 100644
index 0000000..5ffe262
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_nightlight_icon_on.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+    Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="400"
+                    android:propertyName="translateY"
+                    android:startOffset="0"
+                    android:valueFrom="12.312"
+                    android:valueTo="12.125"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="400"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="-45"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G_T_1"
+                    android:rotation="0"
+                    android:translateX="12.875"
+                    android:translateY="12.312">
+                    <group
+                        android:name="_R_G_L_0_G"
+                        android:translateX="-2.375">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_0"
+                            android:pathData=" M3.33 8.62 C2.09,8.68 0.59,8.47 -0.64,7.95 C-1.65,7.53 -2.75,6.9 -3.59,6.09 C-4.38,5.32 -5.19,4.17 -5.61,3.08 C-6.04,1.99 -6.25,0.83 -6.25,-0.39 C-6.25,-1.72 -5.98,-2.85 -5.55,-3.94 C-5.13,-5.02 -4.37,-6 -3.6,-6.78 C-2.63,-7.75 -1.63,-8.28 -0.52,-8.77 C0.48,-9.2 2.04,-9.41 3.14,-9.38 C4.22,-9.35 4.94,-9.16 5.81,-8.79 C5.94,-8.73 6.28,-8.6 6.18,-8.55 C3.44,-6.63 1.83,-3.66 1.83,-0.39 C1.83,2.53 3.47,5.72 6.15,7.86 C6.16,7.9 6.03,7.97 5.91,8.04 C5.13,8.43 4.31,8.56 3.33,8.62c "
+                            android:strokeAlpha="1"
+                            android:strokeColor="#ffffff"
+                            android:strokeLineCap="round"
+                            android:strokeLineJoin="round"
+                            android:strokeWidth="2" />
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_screen_record_icon_off.xml b/packages/SystemUI/res/drawable/qs_screen_record_icon_off.xml
new file mode 100644
index 0000000..b3bdd36
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_screen_record_icon_off.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#edf2eb"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M3.5 -2.5 C3.5,-2.5 3.5,2.5 3.5,2.5 C3.5,3.05 3.05,3.5 2.5,3.5 C2.5,3.5 -2.5,3.5 -2.5,3.5 C-3.05,3.5 -3.5,3.05 -3.5,2.5 C-3.5,2.5 -3.5,-2.5 -3.5,-2.5 C-3.5,-3.05 -3.05,-3.5 -2.5,-3.5 C-2.5,-3.5 2.5,-3.5 2.5,-3.5 C3.05,-3.5 3.5,-3.05 3.5,-2.5c "
+                    android:valueTo="M3.5 0 C3.5,0.97 3.11,1.84 2.48,2.48 C1.84,3.11 0.97,3.5 0,3.5 C-0.97,3.5 -1.84,3.11 -2.47,2.48 C-3.11,1.84 -3.5,0.97 -3.5,0 C-3.5,-0.97 -3.11,-1.84 -2.47,-2.47 C-1.84,-3.11 -0.97,-3.5 0,-3.5 C0.97,-3.5 1.84,-3.11 2.48,-2.47 C3.11,-1.84 3.5,-0.97 3.5,0c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="90"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#edf2eb"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#edf2eb"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_2">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#edf2eb"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_3">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#000000"
+                    android:valueTo="#edf2eb"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="1000"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:rotation="90"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#000000"
+                        android:fillType="nonZero"
+                        android:pathData=" M3.5 -2.5 C3.5,-2.5 3.5,2.5 3.5,2.5 C3.5,3.05 3.05,3.5 2.5,3.5 C2.5,3.5 -2.5,3.5 -2.5,3.5 C-3.05,3.5 -3.5,3.05 -3.5,2.5 C-3.5,2.5 -3.5,-2.5 -3.5,-2.5 C-3.5,-3.05 -3.05,-3.5 -2.5,-3.5 C-2.5,-3.5 2.5,-3.5 2.5,-3.5 C3.05,-3.5 3.5,-3.05 3.5,-2.5c " />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0"
+                        android:rotation="0">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_0"
+                            android:fillAlpha="1"
+                            android:fillColor="#000000"
+                            android:fillType="nonZero"
+                            android:pathData=" M6.6 -4.47 C6.6,-4.47 8.04,-5.91 8.04,-5.91 C9.26,-4.26 9.99,-2.21 10,0.01 C10,2.23 9.26,4.27 8.04,5.93 C8.04,5.93 6.6,4.49 6.6,4.49 C7.47,3.2 7.99,1.66 7.99,0 C7.99,-1.65 7.47,-3.19 6.6,-4.47c " />
+                    </group>
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_1_G_0_T_0"
+                        android:rotation="0">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_1"
+                            android:fillAlpha="1"
+                            android:fillColor="#000000"
+                            android:fillType="nonZero"
+                            android:pathData=" M-8.01 0 C-8.01,1.67 -7.49,3.22 -6.61,4.5 C-6.61,4.5 -8.04,5.93 -8.04,5.93 C-9.27,4.27 -10,2.22 -10,0 C-10,-2.22 -9.27,-4.26 -8.05,-5.92 C-8.05,-5.92 -6.62,-4.49 -6.62,-4.49 C-7.49,-3.21 -8.01,-1.66 -8.01,0c " />
+                    </group>
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_2_G_0_T_0"
+                        android:rotation="0">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_2"
+                            android:fillAlpha="1"
+                            android:fillColor="#000000"
+                            android:fillType="nonZero"
+                            android:pathData=" M-0.01 8 C1.66,8 3.2,7.48 4.48,6.61 C4.48,6.61 5.91,8.05 5.91,8.05 C4.25,9.27 2.21,10 -0.01,10 C-2.22,10 -4.26,9.27 -5.92,8.05 C-5.92,8.05 -4.48,6.61 -4.48,6.61 C-3.21,7.48 -1.67,8 -0.01,8c " />
+                    </group>
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_3_G_0_T_0"
+                        android:rotation="0">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_3"
+                            android:fillAlpha="1"
+                            android:fillColor="#000000"
+                            android:fillType="nonZero"
+                            android:pathData=" M-5.93 -8.04 C-4.27,-9.27 -2.23,-10 -0.01,-10 C2.22,-10 4.26,-9.27 5.94,-8.03 C5.94,-8.03 4.5,-6.59 4.5,-6.59 C3.21,-7.47 1.67,-7.99 0,-7.99 C-1.67,-7.99 -3.21,-7.47 -4.49,-6.6 C-4.49,-6.6 -5.93,-8.04 -5.93,-8.04c " />
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_screen_record_icon_on.xml b/packages/SystemUI/res/drawable/qs_screen_record_icon_on.xml
new file mode 100644
index 0000000..facbef5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_screen_record_icon_on.xml
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#edf2eb"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M3.5 0 C3.5,0.97 3.11,1.84 2.48,2.48 C1.84,3.11 0.97,3.5 0,3.5 C-0.97,3.5 -1.84,3.11 -2.47,2.48 C-3.11,1.84 -3.5,0.97 -3.5,0 C-3.5,-0.97 -3.11,-1.84 -2.47,-2.47 C-1.84,-3.11 -0.97,-3.5 0,-3.5 C0.97,-3.5 1.84,-3.11 2.48,-2.47 C3.11,-1.84 3.5,-0.97 3.5,0c "
+                    android:valueTo="M3.5 -2.5 C3.5,-2.5 3.5,2.5 3.5,2.5 C3.5,3.05 3.05,3.5 2.5,3.5 C2.5,3.5 -2.5,3.5 -2.5,3.5 C-3.05,3.5 -3.5,3.05 -3.5,2.5 C-3.5,2.5 -3.5,-2.5 -3.5,-2.5 C-3.5,-3.05 -3.05,-3.5 -2.5,-3.5 C-2.5,-3.5 2.5,-3.5 2.5,-3.5 C3.05,-3.5 3.5,-3.05 3.5,-2.5c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="90"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#edf2eb"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="833"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,0.53 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#edf2eb"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_1_G_0_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="833"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,0.53 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_2">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#edf2eb"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_2_G_0_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="833"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,0.53 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_3">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="417"
+                    android:propertyName="fillColor"
+                    android:startOffset="0"
+                    android:valueFrom="#edf2eb"
+                    android:valueTo="#000000"
+                    android:valueType="colorType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_3_G_0_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="833"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.7,0 0.2,0.53 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="1000"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:rotation="0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#edf2eb"
+                        android:fillType="nonZero"
+                        android:pathData=" M3.5 0 C3.5,0.97 3.11,1.84 2.48,2.48 C1.84,3.11 0.97,3.5 0,3.5 C-0.97,3.5 -1.84,3.11 -2.47,2.48 C-3.11,1.84 -3.5,0.97 -3.5,0 C-3.5,-0.97 -3.11,-1.84 -2.47,-2.47 C-1.84,-3.11 -0.97,-3.5 0,-3.5 C0.97,-3.5 1.84,-3.11 2.48,-2.47 C3.11,-1.84 3.5,-0.97 3.5,0c " />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0"
+                        android:rotation="0">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_0"
+                            android:fillAlpha="1"
+                            android:fillColor="#edf2eb"
+                            android:fillType="nonZero"
+                            android:pathData=" M6.6 -4.47 C6.6,-4.47 8.04,-5.91 8.04,-5.91 C9.26,-4.26 9.99,-2.21 10,0.01 C10,2.23 9.26,4.27 8.04,5.93 C8.04,5.93 6.6,4.49 6.6,4.49 C7.47,3.2 7.99,1.66 7.99,0 C7.99,-1.65 7.47,-3.19 6.6,-4.47c " />
+                    </group>
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_1_G_0_T_0"
+                        android:rotation="0">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_1"
+                            android:fillAlpha="1"
+                            android:fillColor="#edf2eb"
+                            android:fillType="nonZero"
+                            android:pathData=" M-8.01 0 C-8.01,1.67 -7.49,3.22 -6.61,4.5 C-6.61,4.5 -8.04,5.93 -8.04,5.93 C-9.27,4.27 -10,2.22 -10,0 C-10,-2.22 -9.27,-4.26 -8.05,-5.92 C-8.05,-5.92 -6.62,-4.49 -6.62,-4.49 C-7.49,-3.21 -8.01,-1.66 -8.01,0c " />
+                    </group>
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_2_G_0_T_0"
+                        android:rotation="0">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_2"
+                            android:fillAlpha="1"
+                            android:fillColor="#edf2eb"
+                            android:fillType="nonZero"
+                            android:pathData=" M-0.01 8 C1.66,8 3.2,7.48 4.48,6.61 C4.48,6.61 5.91,8.05 5.91,8.05 C4.25,9.27 2.21,10 -0.01,10 C-2.22,10 -4.26,9.27 -5.92,8.05 C-5.92,8.05 -4.48,6.61 -4.48,6.61 C-3.21,7.48 -1.67,8 -0.01,8c " />
+                    </group>
+                    <group
+                        android:name="_R_G_L_0_G_D_0_P_3_G_0_T_0"
+                        android:rotation="0">
+                        <path
+                            android:name="_R_G_L_0_G_D_0_P_3"
+                            android:fillAlpha="1"
+                            android:fillColor="#edf2eb"
+                            android:fillType="nonZero"
+                            android:pathData=" M-5.93 -8.04 C-4.27,-9.27 -2.23,-10 -0.01,-10 C2.22,-10 4.26,-9.27 5.94,-8.03 C5.94,-8.03 4.5,-6.59 4.5,-6.59 C3.21,-7.47 1.67,-7.99 0,-7.99 C-1.67,-7.99 -3.21,-7.47 -4.49,-6.6 C-4.49,-6.6 -5.93,-8.04 -5.93,-8.04c " />
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
index c972624..006b260 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -40,7 +40,6 @@
         android:layout_height="match_parent"
         android:orientation="horizontal"
         android:gravity="center_vertical"
-        android:layout_marginEnd="@dimen/dream_overlay_status_bar_extra_margin"
         app:layout_constraintEnd_toStartOf="@+id/dream_overlay_system_status" />
 
     <LinearLayout
@@ -48,14 +47,15 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:orientation="horizontal"
-        android:layout_marginStart="@dimen/dream_overlay_status_bar_extra_margin"
+        android:paddingStart="@dimen/dream_overlay_status_bar_extra_margin"
+        android:visibility="gone"
         app:layout_constraintEnd_toEndOf="parent">
 
         <com.android.systemui.statusbar.AlphaOptimizedImageView
             android:id="@+id/dream_overlay_alarm_set"
             android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
             android:src="@drawable/ic_alarm"
             android:tint="@android:color/white"
             android:visibility="gone"
@@ -65,7 +65,7 @@
             android:id="@+id/dream_overlay_priority_mode"
             android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
             android:src="@drawable/ic_qs_dnd_on"
             android:tint="@android:color/white"
             android:visibility="gone"
@@ -75,7 +75,7 @@
             android:id="@+id/dream_overlay_wifi_status"
             android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
             android:src="@drawable/ic_signal_wifi_off"
             android:visibility="gone"
             android:contentDescription="@string/dream_overlay_status_bar_wifi_off" />
@@ -84,7 +84,7 @@
             android:id="@+id/dream_overlay_mic_off"
             android:layout_width="@dimen/dream_overlay_grey_chip_width"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
             android:src="@drawable/dream_overlay_mic_off"
             android:visibility="gone"
             android:contentDescription="@string/dream_overlay_status_bar_mic_off" />
@@ -93,7 +93,7 @@
             android:id="@+id/dream_overlay_camera_off"
             android:layout_width="@dimen/dream_overlay_grey_chip_width"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
             android:src="@drawable/dream_overlay_camera_off"
             android:visibility="gone"
             android:contentDescription="@string/dream_overlay_status_bar_camera_off" />
@@ -102,7 +102,7 @@
             android:id="@+id/dream_overlay_camera_mic_off"
             android:layout_width="@dimen/dream_overlay_grey_chip_width"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+            android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
             android:src="@drawable/dream_overlay_mic_and_camera_off"
             android:visibility="gone"
             android:contentDescription="@string/dream_overlay_status_bar_camera_mic_off" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 11dbe4a..9e8bef0 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -245,6 +245,10 @@
     <color name="dream_overlay_aqi_very_unhealthy">#AD1457</color>
     <color name="dream_overlay_aqi_hazardous">#880E4F</color>
     <color name="dream_overlay_aqi_unknown">#BDC1C6</color>
+
+    <!-- Dream overlay text shadows -->
     <color name="dream_overlay_clock_key_text_shadow_color">#4D000000</color>
     <color name="dream_overlay_clock_ambient_text_shadow_color">#4D000000</color>
+    <color name="dream_overlay_status_bar_key_text_shadow_color">#66000000</color>
+    <color name="dream_overlay_status_bar_ambient_text_shadow_color">#59000000</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index a802723..37549c9 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -611,6 +611,33 @@
          2 - Override the setting to never bypass keyguard -->
     <integer name="config_face_unlock_bypass_override">0</integer>
 
+    <!-- Messages that should NOT be shown to the user during face authentication on keyguard.
+         This includes both lockscreen and bouncer. This should be used to hide messages that may be
+         too chatty or messages that the user can't do much about. Entries are defined in
+         android.hardware.biometrics.face@1.0 types.hal.
+
+         Although not visibly shown to the user, these acquired messages (sent per face auth frame)
+         are still counted towards the total frames to determine whether a deferred message
+         (see config_face_help_msgs_defer_until_timeout) meets the threshold % of frames to show on
+         face timeout. -->
+     <integer-array name="config_face_acquire_device_entry_ignorelist" translatable="false" >
+    </integer-array>
+
+    <!-- Which face help messages to defer until face auth times out. If face auth is cancelled
+         or ends on another error, then the message is never surfaced. May also never surface
+         if it doesn't meet a threshold % of authentication frames specified by.
+         config_face_help_msgs_defer_until_timeout_threshold. -->
+    <integer-array name="config_face_help_msgs_defer_until_timeout">
+    </integer-array>
+
+    <!-- Percentage of face auth frames received required to show a deferred message at
+         FACE_ERROR_TIMEOUT. See config_face_help_msgs_defer_until_timeout for messages
+         that are deferred.-->
+    <item name="config_face_help_msgs_defer_until_timeout_threshold"
+          translatable="false" format="float" type="dimen">
+        .75
+    </item>
+
     <!-- Which face help messages to surface when fingerprint is also enrolled.
          Message ids correspond with the acquired ids in BiometricFaceConstants -->
     <integer-array name="config_face_help_msgs_when_fingerprint_enrolled">
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e76047e..6592e14 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1477,7 +1477,7 @@
     <dimen name="dream_overlay_camera_mic_off_indicator_size">8dp</dimen>
     <dimen name="dream_overlay_notification_indicator_size">6dp</dimen>
     <dimen name="dream_overlay_grey_chip_width">56dp</dimen>
-    <dimen name="dream_overlay_status_bar_extra_margin">16dp</dimen>
+    <dimen name="dream_overlay_status_bar_extra_margin">8dp</dimen>
 
     <!-- Dream overlay complications related dimensions -->
     <dimen name="dream_overlay_complication_clock_time_text_size">86sp</dimen>
@@ -1560,10 +1560,20 @@
     <dimen name="broadcast_dialog_btn_text_size">16sp</dimen>
     <dimen name="broadcast_dialog_btn_minHeight">44dp</dimen>
     <dimen name="broadcast_dialog_margin">16dp</dimen>
+
+    <!-- Shadow for dream overlay clock complication -->
     <dimen name="dream_overlay_clock_key_text_shadow_dx">0dp</dimen>
     <dimen name="dream_overlay_clock_key_text_shadow_dy">0dp</dimen>
-    <dimen name="dream_overlay_clock_key_text_shadow_radius">5dp</dimen>
+    <dimen name="dream_overlay_clock_key_text_shadow_radius">3dp</dimen>
     <dimen name="dream_overlay_clock_ambient_text_shadow_dx">0dp</dimen>
     <dimen name="dream_overlay_clock_ambient_text_shadow_dy">0dp</dimen>
     <dimen name="dream_overlay_clock_ambient_text_shadow_radius">1dp</dimen>
+
+    <!-- Shadow for dream overlay status bar complications -->
+    <dimen name="dream_overlay_status_bar_key_text_shadow_dx">0.5dp</dimen>
+    <dimen name="dream_overlay_status_bar_key_text_shadow_dy">0.5dp</dimen>
+    <dimen name="dream_overlay_status_bar_key_text_shadow_radius">1dp</dimen>
+    <dimen name="dream_overlay_status_bar_ambient_text_shadow_dx">0.5dp</dimen>
+    <dimen name="dream_overlay_status_bar_ambient_text_shadow_dy">0.5dp</dimen>
+    <dimen name="dream_overlay_status_bar_ambient_text_shadow_radius">2dp</dimen>
 </resources>
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
index cbab0a7..fafc774 100644
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
@@ -23,9 +23,11 @@
 /** A [GoldenImagePathManager] that should be used for all SystemUI screenshot tests. */
 class SystemUIGoldenImagePathManager(
     pathConfig: PathConfig,
+    override val assetsPathRelativeToRepo: String = "tests/screenshot/assets"
 ) :
     GoldenImagePathManager(
         appContext = InstrumentationRegistry.getInstrumentation().context,
+        assetsPathRelativeToRepo = assetsPathRelativeToRepo,
         deviceLocalPath =
             InstrumentationRegistry.getInstrumentation()
                 .targetContext
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index 34e2e83..c2e7445 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -23,6 +23,7 @@
 import android.app.compat.ChangeIdStateCache.invalidate
 import android.content.Context
 import android.graphics.Canvas
+import android.text.Layout
 import android.text.TextUtils
 import android.text.format.DateFormat
 import android.util.AttributeSet
@@ -78,6 +79,8 @@
     private var textAnimator: TextAnimator? = null
     private var onTextAnimatorInitialized: Runnable? = null
 
+    @VisibleForTesting var textAnimatorFactory: (Layout, () -> Unit) -> TextAnimator =
+        { layout, invalidateCb -> TextAnimator(layout, invalidateCb) }
     @VisibleForTesting var isAnimationEnabled: Boolean = true
     @VisibleForTesting var timeOverrideInMillis: Long? = null
 
@@ -174,7 +177,7 @@
         super.onMeasure(widthMeasureSpec, heightMeasureSpec)
         val animator = textAnimator
         if (animator == null) {
-            textAnimator = TextAnimator(layout) { invalidate() }
+            textAnimator = textAnimatorFactory(layout, ::invalidate)
             onTextAnimatorInitialized?.run()
             onTextAnimatorInitialized = null
         } else {
@@ -219,9 +222,6 @@
     }
 
     fun animateAppearOnLockscreen() {
-        if (isAnimationEnabled && textAnimator == null) {
-            return
-        }
         setTextStyle(
             weight = dozingWeight,
             textSize = -1f,
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
new file mode 100644
index 0000000..30c062b
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2018 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.shared.system;
+
+import android.graphics.HardwareRenderer;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Handler.Callback;
+import android.os.Message;
+import android.os.Trace;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+import android.view.View;
+import android.view.ViewRootImpl;
+
+import java.util.function.Consumer;
+
+/**
+ * Helper class to apply surface transactions in sync with RenderThread.
+ *
+ * NOTE: This is a modification of {@link android.view.SyncRtSurfaceTransactionApplier}, we can't 
+ *       currently reference that class from the shared lib as it is hidden.
+ */
+public class SyncRtSurfaceTransactionApplierCompat {
+
+    public static final int FLAG_ALL = 0xffffffff;
+    public static final int FLAG_ALPHA = 1;
+    public static final int FLAG_MATRIX = 1 << 1;
+    public static final int FLAG_WINDOW_CROP = 1 << 2;
+    public static final int FLAG_LAYER = 1 << 3;
+    public static final int FLAG_CORNER_RADIUS = 1 << 4;
+    public static final int FLAG_BACKGROUND_BLUR_RADIUS = 1 << 5;
+    public static final int FLAG_VISIBILITY = 1 << 6;
+    public static final int FLAG_RELATIVE_LAYER = 1 << 7;
+    public static final int FLAG_SHADOW_RADIUS = 1 << 8;
+
+    private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0;
+
+    private final SurfaceControl mBarrierSurfaceControl;
+    private final ViewRootImpl mTargetViewRootImpl;
+    private final Handler mApplyHandler;
+
+    private int mSequenceNumber = 0;
+    private int mPendingSequenceNumber = 0;
+    private Runnable mAfterApplyCallback;
+
+    /**
+     * @param targetView The view in the surface that acts as synchronization anchor.
+     */
+    public SyncRtSurfaceTransactionApplierCompat(View targetView) {
+        mTargetViewRootImpl = targetView != null ? targetView.getViewRootImpl() : null;
+        mBarrierSurfaceControl = mTargetViewRootImpl != null
+            ? mTargetViewRootImpl.getSurfaceControl() : null;
+
+        mApplyHandler = new Handler(new Callback() {
+            @Override
+            public boolean handleMessage(Message msg) {
+                if (msg.what == MSG_UPDATE_SEQUENCE_NUMBER) {
+                    onApplyMessage(msg.arg1);
+                    return true;
+                }
+                return false;
+            }
+        });
+    }
+
+    private void onApplyMessage(int seqNo) {
+        mSequenceNumber = seqNo;
+        if (mSequenceNumber == mPendingSequenceNumber && mAfterApplyCallback != null) {
+            Runnable r = mAfterApplyCallback;
+            mAfterApplyCallback = null;
+            r.run();
+        }
+    }
+
+    /**
+     * Schedules applying surface parameters on the next frame.
+     *
+     * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
+     *               this method to avoid synchronization issues.
+     */
+    public void scheduleApply(final SyncRtSurfaceTransactionApplierCompat.SurfaceParams... params) {
+        if (mTargetViewRootImpl == null || mTargetViewRootImpl.getView() == null) {
+            return;
+        }
+
+        mPendingSequenceNumber++;
+        final int toApplySeqNo = mPendingSequenceNumber;
+        mTargetViewRootImpl.registerRtFrameCallback(new HardwareRenderer.FrameDrawingCallback() {
+            @Override
+            public void onFrameDraw(long frame) {
+                if (mBarrierSurfaceControl == null || !mBarrierSurfaceControl.isValid()) {
+                    Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
+                            .sendToTarget();
+                    return;
+                }
+                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Sync transaction frameNumber=" + frame);
+                Transaction t = new Transaction();
+                for (int i = params.length - 1; i >= 0; i--) {
+                    SyncRtSurfaceTransactionApplierCompat.SurfaceParams surfaceParams =
+                            params[i];
+                    surfaceParams.applyTo(t);
+                }
+                if (mTargetViewRootImpl != null) {
+                    mTargetViewRootImpl.mergeWithNextTransaction(t, frame);
+                } else {
+                    t.apply();
+                }
+                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+                Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
+                        .sendToTarget();
+            }
+        });
+
+        // Make sure a frame gets scheduled.
+        mTargetViewRootImpl.getView().invalidate();
+    }
+
+    /**
+     * Calls the runnable when any pending apply calls have completed
+     */
+    public void addAfterApplyCallback(final Runnable afterApplyCallback) {
+        if (mSequenceNumber == mPendingSequenceNumber) {
+            afterApplyCallback.run();
+        } else {
+            if (mAfterApplyCallback == null) {
+                mAfterApplyCallback = afterApplyCallback;
+            } else {
+                final Runnable oldCallback = mAfterApplyCallback;
+                mAfterApplyCallback = new Runnable() {
+                    @Override
+                    public void run() {
+                        afterApplyCallback.run();
+                        oldCallback.run();
+                    }
+                };
+            }
+        }
+    }
+
+    public static void applyParams(TransactionCompat t,
+            SyncRtSurfaceTransactionApplierCompat.SurfaceParams params) {
+        params.applyTo(t.mTransaction);
+    }
+
+    /**
+     * Creates an instance of SyncRtSurfaceTransactionApplier, deferring until the target view is
+     * attached if necessary.
+     */
+    public static void create(final View targetView,
+            final Consumer<SyncRtSurfaceTransactionApplierCompat> callback) {
+        if (targetView == null) {
+            // No target view, no applier
+            callback.accept(null);
+        } else if (targetView.getViewRootImpl() != null) {
+            // Already attached, we're good to go
+            callback.accept(new SyncRtSurfaceTransactionApplierCompat(targetView));
+        } else {
+            // Haven't been attached before we can get the view root
+            targetView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+                @Override
+                public void onViewAttachedToWindow(View v) {
+                    targetView.removeOnAttachStateChangeListener(this);
+                    callback.accept(new SyncRtSurfaceTransactionApplierCompat(targetView));
+                }
+
+                @Override
+                public void onViewDetachedFromWindow(View v) {
+                    // Do nothing
+                }
+            });
+        }
+    }
+
+    public static class SurfaceParams {
+        public static class Builder {
+            final SurfaceControl surface;
+            int flags;
+            float alpha;
+            float cornerRadius;
+            int backgroundBlurRadius;
+            Matrix matrix;
+            Rect windowCrop;
+            int layer;
+            SurfaceControl relativeTo;
+            int relativeLayer;
+            boolean visible;
+            float shadowRadius;
+
+            /**
+             * @param surface The surface to modify.
+             */
+            public Builder(SurfaceControl surface) {
+                this.surface = surface;
+            }
+
+            /**
+             * @param alpha The alpha value to apply to the surface.
+             * @return this Builder
+             */
+            public Builder withAlpha(float alpha) {
+                this.alpha = alpha;
+                flags |= FLAG_ALPHA;
+                return this;
+            }
+
+            /**
+             * @param matrix The matrix to apply to the surface.
+             * @return this Builder
+             */
+            public Builder withMatrix(Matrix matrix) {
+                this.matrix = new Matrix(matrix);
+                flags |= FLAG_MATRIX;
+                return this;
+            }
+
+            /**
+             * @param windowCrop The window crop to apply to the surface.
+             * @return this Builder
+             */
+            public Builder withWindowCrop(Rect windowCrop) {
+                this.windowCrop = new Rect(windowCrop);
+                flags |= FLAG_WINDOW_CROP;
+                return this;
+            }
+
+            /**
+             * @param layer The layer to assign the surface.
+             * @return this Builder
+             */
+            public Builder withLayer(int layer) {
+                this.layer = layer;
+                flags |= FLAG_LAYER;
+                return this;
+            }
+
+            /**
+             * @param relativeTo The surface that's set relative layer to.
+             * @param relativeLayer The relative layer.
+             * @return this Builder
+             */
+            public Builder withRelativeLayerTo(SurfaceControl relativeTo, int relativeLayer) {
+                this.relativeTo = relativeTo;
+                this.relativeLayer = relativeLayer;
+                flags |= FLAG_RELATIVE_LAYER;
+                return this;
+            }
+
+            /**
+             * @param radius the Radius for rounded corners to apply to the surface.
+             * @return this Builder
+             */
+            public Builder withCornerRadius(float radius) {
+                this.cornerRadius = radius;
+                flags |= FLAG_CORNER_RADIUS;
+                return this;
+            }
+
+            /**
+             * @param radius the Radius for the shadows to apply to the surface.
+             * @return this Builder
+             */
+            public Builder withShadowRadius(float radius) {
+                this.shadowRadius = radius;
+                flags |= FLAG_SHADOW_RADIUS;
+                return this;
+            }
+
+            /**
+             * @param radius the Radius for blur to apply to the background surfaces.
+             * @return this Builder
+             */
+            public Builder withBackgroundBlur(int radius) {
+                this.backgroundBlurRadius = radius;
+                flags |= FLAG_BACKGROUND_BLUR_RADIUS;
+                return this;
+            }
+
+            /**
+             * @param visible The visibility to apply to the surface.
+             * @return this Builder
+             */
+            public Builder withVisibility(boolean visible) {
+                this.visible = visible;
+                flags |= FLAG_VISIBILITY;
+                return this;
+            }
+
+            /**
+             * @return a new SurfaceParams instance
+             */
+            public SurfaceParams build() {
+                return new SurfaceParams(surface, flags, alpha, matrix, windowCrop, layer,
+                        relativeTo, relativeLayer, cornerRadius, backgroundBlurRadius, visible,
+                        shadowRadius);
+            }
+        }
+
+        private SurfaceParams(SurfaceControl surface, int flags, float alpha, Matrix matrix,
+                Rect windowCrop, int layer, SurfaceControl relativeTo, int relativeLayer,
+                float cornerRadius, int backgroundBlurRadius, boolean visible, float shadowRadius) {
+            this.flags = flags;
+            this.surface = surface;
+            this.alpha = alpha;
+            this.matrix = matrix;
+            this.windowCrop = windowCrop;
+            this.layer = layer;
+            this.relativeTo = relativeTo;
+            this.relativeLayer = relativeLayer;
+            this.cornerRadius = cornerRadius;
+            this.backgroundBlurRadius = backgroundBlurRadius;
+            this.visible = visible;
+            this.shadowRadius = shadowRadius;
+        }
+
+        private final int flags;
+        private final float[] mTmpValues = new float[9];
+
+        public final SurfaceControl surface;
+        public final float alpha;
+        public final float cornerRadius;
+        public final int backgroundBlurRadius;
+        public final Matrix matrix;
+        public final Rect windowCrop;
+        public final int layer;
+        public final SurfaceControl relativeTo;
+        public final int relativeLayer;
+        public final boolean visible;
+        public final float shadowRadius;
+
+        public void applyTo(SurfaceControl.Transaction t) {
+            if ((flags & FLAG_MATRIX) != 0) {
+                t.setMatrix(surface, matrix, mTmpValues);
+            }
+            if ((flags & FLAG_WINDOW_CROP) != 0) {
+                t.setWindowCrop(surface, windowCrop);
+            }
+            if ((flags & FLAG_ALPHA) != 0) {
+                t.setAlpha(surface, alpha);
+            }
+            if ((flags & FLAG_LAYER) != 0) {
+                t.setLayer(surface, layer);
+            }
+            if ((flags & FLAG_CORNER_RADIUS) != 0) {
+                t.setCornerRadius(surface, cornerRadius);
+            }
+            if ((flags & FLAG_BACKGROUND_BLUR_RADIUS) != 0) {
+                t.setBackgroundBlurRadius(surface, backgroundBlurRadius);
+            }
+            if ((flags & FLAG_VISIBILITY) != 0) {
+                if (visible) {
+                    t.show(surface);
+                } else {
+                    t.hide(surface);
+                }
+            }
+            if ((flags & FLAG_RELATIVE_LAYER) != 0) {
+                t.setRelativeLayer(surface, relativeTo, relativeLayer);
+            }
+            if ((flags & FLAG_SHADOW_RADIUS) != 0) {
+                t.setShadowRadius(surface, shadowRadius);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
new file mode 100644
index 0000000..43a882a5
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 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.shared.system;
+
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+
+public class TransactionCompat {
+
+    final Transaction mTransaction;
+
+    final float[] mTmpValues = new float[9];
+
+    public TransactionCompat() {
+        mTransaction = new Transaction();
+    }
+
+    public void apply() {
+        mTransaction.apply();
+    }
+
+    public TransactionCompat show(SurfaceControl surfaceControl) {
+        mTransaction.show(surfaceControl);
+        return this;
+    }
+
+    public TransactionCompat hide(SurfaceControl surfaceControl) {
+        mTransaction.hide(surfaceControl);
+        return this;
+    }
+
+    public TransactionCompat setPosition(SurfaceControl surfaceControl, float x, float y) {
+        mTransaction.setPosition(surfaceControl, x, y);
+        return this;
+    }
+
+    public TransactionCompat setSize(SurfaceControl surfaceControl, int w, int h) {
+        mTransaction.setBufferSize(surfaceControl, w, h);
+        return this;
+    }
+
+    public TransactionCompat setLayer(SurfaceControl surfaceControl, int z) {
+        mTransaction.setLayer(surfaceControl, z);
+        return this;
+    }
+
+    public TransactionCompat setAlpha(SurfaceControl surfaceControl, float alpha) {
+        mTransaction.setAlpha(surfaceControl, alpha);
+        return this;
+    }
+
+    public TransactionCompat setOpaque(SurfaceControl surfaceControl, boolean opaque) {
+        mTransaction.setOpaque(surfaceControl, opaque);
+        return this;
+    }
+
+    public TransactionCompat setMatrix(SurfaceControl surfaceControl, float dsdx, float dtdx,
+            float dtdy, float dsdy) {
+        mTransaction.setMatrix(surfaceControl, dsdx, dtdx, dtdy, dsdy);
+        return this;
+    }
+
+    public TransactionCompat setMatrix(SurfaceControl surfaceControl, Matrix matrix) {
+        mTransaction.setMatrix(surfaceControl, matrix, mTmpValues);
+        return this;
+    }
+
+    public TransactionCompat setWindowCrop(SurfaceControl surfaceControl, Rect crop) {
+        mTransaction.setWindowCrop(surfaceControl, crop);
+        return this;
+    }
+
+    public TransactionCompat setCornerRadius(SurfaceControl surfaceControl, float radius) {
+        mTransaction.setCornerRadius(surfaceControl, radius);
+        return this;
+    }
+
+    public TransactionCompat setBackgroundBlurRadius(SurfaceControl surfaceControl, int radius) {
+        mTransaction.setBackgroundBlurRadius(surfaceControl, radius);
+        return this;
+    }
+
+    public TransactionCompat setColor(SurfaceControl surfaceControl, float[] color) {
+        mTransaction.setColor(surfaceControl, color);
+        return this;
+    }
+
+    public static void setRelativeLayer(Transaction t, SurfaceControl surfaceControl,
+            SurfaceControl relativeTo, int z) {
+        t.setRelativeLayer(surfaceControl, relativeTo, z);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 0e1e0cb..b444f4c 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -137,6 +137,10 @@
         override fun onThemeChanged() {
             updateFun.updateColors()
         }
+
+        override fun onDensityOrFontScaleChanged() {
+            clock?.events?.onFontSettingChanged()
+        }
     }
 
     private val batteryCallback = object : BatteryStateChangeCallback {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
new file mode 100644
index 0000000..b4bfca1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.ImageView
+import androidx.core.graphics.drawable.DrawableCompat
+import com.android.systemui.R
+
+abstract class KeyguardSimInputView(context: Context, attrs: AttributeSet) :
+    KeyguardPinBasedInputView(context, attrs) {
+    private var simImageView: ImageView? = null
+    private var disableESimButton: KeyguardEsimArea? = null
+
+    override fun onFinishInflate() {
+        simImageView = findViewById(R.id.keyguard_sim)
+        disableESimButton = findViewById(R.id.keyguard_esim_area)
+        super.onFinishInflate()
+    }
+
+    /** Set UI state based on whether there is a locked eSim card */
+    fun setESimLocked(isESimLocked: Boolean, subId: Int) {
+        disableESimButton?.setSubscriptionId(subId)
+        disableESimButton?.visibility = if (isESimLocked) VISIBLE else GONE
+        simImageView?.visibility = if (isESimLocked) GONE else VISIBLE
+    }
+
+    override fun reloadColors() {
+        super.reloadColors()
+        val customAttrs = intArrayOf(android.R.attr.textColorSecondary)
+        val a = context.obtainStyledAttributes(customAttrs)
+        val imageColor = a.getColor(0, 0)
+        a.recycle()
+        simImageView?.let {
+            val wrappedDrawable = DrawableCompat.wrap(it.drawable)
+            DrawableCompat.setTint(wrappedDrawable, imageColor)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index ae9d3df..9d17015 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -18,21 +18,14 @@
 
 import android.content.Context;
 import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-
-import androidx.core.graphics.drawable.DrawableCompat;
 
 import com.android.systemui.R;
 
 /**
  * Displays a PIN pad for unlocking.
  */
-public class KeyguardSimPinView extends KeyguardPinBasedInputView {
-    private ImageView mSimImageView;
+public class KeyguardSimPinView extends KeyguardSimInputView {
     public static final String TAG = "KeyguardSimPinView";
 
     public KeyguardSimPinView(Context context) {
@@ -43,12 +36,6 @@
         super(context, attrs);
     }
 
-    public void setEsimLocked(boolean locked, int subscriptionId) {
-        KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
-        esimButton.setSubscriptionId(subscriptionId);
-        esimButton.setVisibility(locked ? View.VISIBLE : View.GONE);
-    }
-
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
@@ -68,7 +55,6 @@
 
     @Override
     protected void onFinishInflate() {
-        mSimImageView = findViewById(R.id.keyguard_sim);
         super.onFinishInflate();
 
         if (mEcaView instanceof EmergencyCarrierArea) {
@@ -86,17 +72,4 @@
         return getContext().getString(
                 com.android.internal.R.string.keyguard_accessibility_sim_pin_unlock);
     }
-
-    @Override
-    public void reloadColors() {
-        super.reloadColors();
-
-        int[] customAttrs = {android.R.attr.textColorSecondary};
-        TypedArray a = getContext().obtainStyledAttributes(customAttrs);
-        int imageColor = a.getColor(0, 0);
-        a.recycle();
-        Drawable wrappedDrawable = DrawableCompat.wrap(mSimImageView.getDrawable());
-        DrawableCompat.setTint(wrappedDrawable, imageColor);
-    }
 }
-
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index 2a2e9bf..91bf20f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -105,7 +105,7 @@
             showDefaultMessage();
         }
 
-        mView.setEsimLocked(KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId), mSubId);
+        mView.setESimLocked(KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId), mSubId);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index c0971bf..5f45fe3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -19,13 +19,8 @@
 import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
 
 import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.widget.ImageView;
-
-import androidx.core.graphics.drawable.DrawableCompat;
 
 import com.android.systemui.R;
 
@@ -33,8 +28,7 @@
 /**
  * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
  */
-public class KeyguardSimPukView extends KeyguardPinBasedInputView {
-    private ImageView mSimImageView;
+public class KeyguardSimPukView extends KeyguardSimInputView {
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     public static final String TAG = "KeyguardSimPukView";
 
@@ -86,7 +80,6 @@
 
     @Override
     protected void onFinishInflate() {
-        mSimImageView = findViewById(R.id.keyguard_sim);
         super.onFinishInflate();
 
         if (mEcaView instanceof EmergencyCarrierArea) {
@@ -104,18 +97,4 @@
         return getContext().getString(
                 com.android.internal.R.string.keyguard_accessibility_sim_puk_unlock);
     }
-
-    @Override
-    public void reloadColors() {
-        super.reloadColors();
-
-        int[] customAttrs = {android.R.attr.textColorSecondary};
-        TypedArray a = getContext().obtainStyledAttributes(customAttrs);
-        int imageColor = a.getColor(0, 0);
-        a.recycle();
-        Drawable wrappedDrawable = DrawableCompat.wrap(mSimImageView.getDrawable());
-        DrawableCompat.setTint(wrappedDrawable, imageColor);
-    }
 }
-
-
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index 203f9b6..d8cffd7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -30,7 +30,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
-import android.view.View;
 import android.view.WindowManager;
 import android.widget.ImageView;
 
@@ -173,11 +172,9 @@
             if (mShowDefaultMessage) {
                 showDefaultMessage();
             }
-            boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId);
 
-            KeyguardEsimArea esimButton = mView.findViewById(R.id.keyguard_esim_area);
-            esimButton.setSubscriptionId(mSubId);
-            esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
+            mView.setESimLocked(KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId), mSubId);
+
             mPasswordEntry.requestFocus();
         }
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 5ccab54..7e04f04 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -157,6 +157,7 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -167,6 +168,7 @@
 import java.util.TimeZone;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 import javax.inject.Provider;
@@ -266,6 +268,7 @@
     private final AuthController mAuthController;
     private final StatusBarStateController mStatusBarStateController;
     private final UiEventLogger mUiEventLogger;
+    private final Set<Integer> mFaceAcquiredInfoIgnoreList;
     private int mStatusBarState;
     private final StatusBarStateController.StateListener mStatusBarStateControllerListener =
             new StatusBarStateController.StateListener() {
@@ -1008,6 +1011,7 @@
 
     private void handleFaceAuthFailed() {
         Assert.isMainThread();
+        mLogger.d("onFaceAuthFailed");
         mFaceCancelSignal = null;
         setFaceRunningState(BIOMETRIC_STATE_STOPPED);
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1624,6 +1628,9 @@
 
                 @Override
                 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
+                    if (mFaceAcquiredInfoIgnoreList.contains(helpMsgId)) {
+                        return;
+                    }
                     handleFaceHelp(helpMsgId, helpString.toString());
                 }
 
@@ -1916,6 +1923,11 @@
         mActiveUnlockConfig.setKeyguardUpdateMonitor(this);
         mWakeOnFingerprintAcquiredStart = context.getResources()
                         .getBoolean(com.android.internal.R.bool.kg_wake_on_acquire_start);
+        mFaceAcquiredInfoIgnoreList = Arrays.stream(
+                mContext.getResources().getIntArray(
+                        R.array.config_face_acquire_device_entry_ignorelist))
+                .boxed()
+                .collect(Collectors.toSet());
 
         mHandler = new Handler(mainLooper) {
             @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/BiometricMessageDeferralLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/BiometricMessageDeferralLogger.kt
new file mode 100644
index 0000000..2c2ab7b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/logging/BiometricMessageDeferralLogger.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard.logging
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel.DEBUG
+import com.android.systemui.log.dagger.BiometricMessagesLog
+import javax.inject.Inject
+
+/** Helper class for logging for [com.android.systemui.biometrics.FaceHelpMessageDeferral] */
+@SysUISingleton
+class FaceMessageDeferralLogger
+@Inject
+constructor(@BiometricMessagesLog private val logBuffer: LogBuffer) :
+    BiometricMessageDeferralLogger(logBuffer, "FaceMessageDeferralLogger")
+
+open class BiometricMessageDeferralLogger(
+    private val logBuffer: LogBuffer,
+    private val tag: String
+) {
+    fun reset() {
+        logBuffer.log(tag, DEBUG, "reset")
+    }
+
+    fun logUpdateMessage(acquiredInfo: Int, helpString: String) {
+        logBuffer.log(
+            tag,
+            DEBUG,
+            {
+                int1 = acquiredInfo
+                str1 = helpString
+            },
+            { "updateMessage acquiredInfo=$int1 helpString=$str1" }
+        )
+    }
+
+    fun logFrameProcessed(
+        acquiredInfo: Int,
+        totalFrames: Int,
+        mostFrequentAcquiredInfoToDefer: String? // may not meet the threshold
+    ) {
+        logBuffer.log(
+            tag,
+            DEBUG,
+            {
+                int1 = acquiredInfo
+                int2 = totalFrames
+                str1 = mostFrequentAcquiredInfoToDefer
+            },
+            {
+                "frameProcessed acquiredInfo=$int1 totalFrames=$int2 " +
+                    "messageToShowOnTimeout=$str1"
+            }
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 7fc8123..a5fdc68 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -103,7 +103,6 @@
 import com.android.systemui.statusbar.phone.SystemUIDialogManager;
 import com.android.systemui.statusbar.policy.AccessibilityController;
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
-import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -253,7 +252,6 @@
     @Inject Lazy<UserInfoController> mUserInfoController;
     @Inject Lazy<KeyguardStateController> mKeyguardMonitor;
     @Inject Lazy<KeyguardUpdateMonitor> mKeyguardUpdateMonitor;
-    @Inject Lazy<BatteryController> mBatteryController;
     @Inject Lazy<NightDisplayListener> mNightDisplayListener;
     @Inject Lazy<ReduceBrightColorsController> mReduceBrightColorsController;
     @Inject Lazy<ManagedProfileController> mManagedProfileController;
@@ -404,8 +402,6 @@
 
         mProviders.put(UserInfoController.class, mUserInfoController::get);
 
-        mProviders.put(BatteryController.class, mBatteryController::get);
-
         mProviders.put(NightDisplayListener.class, mNightDisplayListener::get);
 
         mProviders.put(ReduceBrightColorsController.class, mReduceBrightColorsController::get);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index b976181..e3c04a3 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -689,7 +689,7 @@
         if (Float.isNaN(centerX)) {
             centerX = mMagnificationFrame.centerX();
         }
-        if (Float.isNaN(centerX)) {
+        if (Float.isNaN(centerY)) {
             centerY = mMagnificationFrame.centerY();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 436b756..8f5cbb7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -54,6 +54,8 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
@@ -127,6 +129,7 @@
     private final float mTranslationY;
     @ContainerState private int mContainerState = STATE_UNKNOWN;
     private final Set<Integer> mFailedModalities = new HashSet<Integer>();
+    private final OnBackInvokedCallback mBackCallback = this::onBackInvoked;
 
     private final @Background DelayableExecutor mBackgroundExecutor;
     private int mOrientation;
@@ -362,8 +365,7 @@
                 return false;
             }
             if (event.getAction() == KeyEvent.ACTION_UP) {
-                sendEarlyUserCanceled();
-                animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
+                onBackInvoked();
             }
             return true;
         });
@@ -373,6 +375,11 @@
         requestFocus();
     }
 
+    private void onBackInvoked() {
+        sendEarlyUserCanceled();
+        animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
+    }
+
     void sendEarlyUserCanceled() {
         mConfig.mCallback.onSystemEvent(
                 BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL, getRequestId());
@@ -520,6 +527,11 @@
                         .start();
             });
         }
+        OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
+        if (dispatcher != null) {
+            dispatcher.registerOnBackInvokedCallback(
+                    OnBackInvokedDispatcher.PRIORITY_DEFAULT, mBackCallback);
+        }
     }
 
     private Animator.AnimatorListener getJankListener(View v, String type, long timeout) {
@@ -618,6 +630,10 @@
 
     @Override
     public void onDetachedFromWindow() {
+        OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
+        if (dispatcher != null) {
+            findOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mBackCallback);
+        }
         super.onDetachedFromWindow();
         mWakefulnessLifecycle.removeObserver(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 163e3ab..29b0088 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -57,6 +57,7 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserManager;
+import android.util.DisplayUtils;
 import android.util.Log;
 import android.util.RotationUtils;
 import android.util.SparseBooleanArray;
@@ -120,8 +121,6 @@
     private final Provider<UdfpsController> mUdfpsControllerFactory;
     private final Provider<SidefpsController> mSidefpsControllerFactory;
 
-    @NonNull private Point mStableDisplaySize = new Point();
-
     private final Display mDisplay;
     private float mScaleFactor = 1f;
     // sensor locations without any resolution scaling nor rotation adjustments:
@@ -188,7 +187,10 @@
         public void onReceive(Context context, Intent intent) {
             if (mCurrentDialog != null
                     && Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
-                Log.w(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received");
+                String reason = intent.getStringExtra("reason");
+                reason = (reason != null) ? reason : "unknown";
+                Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received, reason: " + reason);
+
                 mCurrentDialog.dismissWithoutCallback(true /* animate */);
                 mCurrentDialog = null;
 
@@ -287,7 +289,6 @@
                 }
             });
             mUdfpsController.setAuthControllerUpdateUdfpsLocation(this::updateUdfpsLocation);
-            mUdfpsController.setHalControlsIllumination(mUdfpsProps.get(0).halControlsIllumination);
             mUdfpsBounds = mUdfpsProps.get(0).getLocation().getRect();
         }
 
@@ -532,10 +533,11 @@
      */
     private void updateSensorLocations() {
         mDisplay.getDisplayInfo(mCachedDisplayInfo);
-
+        final Display.Mode maxDisplayMode =
+                DisplayUtils.getMaximumResolutionDisplayMode(mCachedDisplayInfo.supportedModes);
         final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio(
-                mStableDisplaySize.x, mStableDisplaySize.y, mCachedDisplayInfo.getNaturalWidth(),
-                mCachedDisplayInfo.getNaturalHeight());
+                maxDisplayMode.getPhysicalWidth(), maxDisplayMode.getPhysicalHeight(),
+                mCachedDisplayInfo.getNaturalWidth(), mCachedDisplayInfo.getNaturalHeight());
         if (scaleFactor == Float.POSITIVE_INFINITY) {
             mScaleFactor = 1f;
         } else {
@@ -813,7 +815,6 @@
             );
         }
 
-        mStableDisplaySize = mDisplayManager.getStableDisplaySize();
         mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
         mOrientationListener.enable();
         updateSensorLocations();
@@ -1197,7 +1198,6 @@
     @Override
     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
         final AuthDialog dialog = mCurrentDialog;
-        pw.println("  stableDisplaySize=" + mStableDisplaySize);
         pw.println("  mCachedDisplayInfo=" + mCachedDisplayInfo);
         pw.println("  mScaleFactor=" + mScaleFactor);
         pw.println("  faceAuthSensorLocationDefault=" + mFaceSensorLocationDefault);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 35d96c9..31e1fb4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -23,7 +23,6 @@
 import android.graphics.Point
 import android.hardware.biometrics.BiometricFingerprintConstants
 import android.hardware.biometrics.BiometricSourceType
-import android.util.Log
 import androidx.annotation.VisibleForTesting
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
@@ -95,7 +94,6 @@
     public override fun onViewAttached() {
         authController.addCallback(authControllerCallback)
         updateRippleColor()
-        updateSensorLocation()
         updateUdfpsDependentParams()
         udfpsController?.addCallback(udfpsControllerCallback)
         configurationController.addCallback(configurationChangedListener)
@@ -237,7 +235,11 @@
     }
 
     private fun showDwellRipple() {
-        mView.startDwellRipple(statusBarStateController.isDozing)
+        updateSensorLocation()
+        fingerprintSensorLocation?.let {
+            mView.setFingerprintSensorLocation(it, udfpsRadius)
+            mView.startDwellRipple(statusBarStateController.isDozing)
+        }
     }
 
     private val keyguardUpdateMonitorCallback =
@@ -264,7 +266,7 @@
             acquireInfo: Int
         ) {
             if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
-                    BiometricFingerprintConstants.shouldTurnOffHbm(acquireInfo) &&
+                    BiometricFingerprintConstants.shouldDisableUdfpsDisplayMode(acquireInfo) &&
                     acquireInfo != BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
                 // received an 'acquiredBad' message, so immediately retract
                 mView.retractDwellRipple()
@@ -291,13 +293,6 @@
     private val udfpsControllerCallback =
         object : UdfpsController.Callback {
             override fun onFingerDown() {
-                if (fingerprintSensorLocation == null) {
-                    Log.e("AuthRipple", "fingerprintSensorLocation=null onFingerDown. " +
-                            "Skip showing dwell ripple")
-                    return
-                }
-
-                mView.setFingerprintSensorLocation(fingerprintSensorLocation!!, udfpsRadius)
                 showDwellRipple()
             }
 
@@ -310,12 +305,10 @@
         object : AuthController.Callback {
             override fun onAllAuthenticatorsRegistered(modality: Int) {
                 updateUdfpsDependentParams()
-                updateSensorLocation()
             }
 
             override fun onUdfpsLocationChanged() {
                 updateUdfpsDependentParams()
-                updateSensorLocation()
             }
         }
 
@@ -345,13 +338,11 @@
                                 "\n\tudfpsRadius=$udfpsRadius")
                     }
                     "fingerprint" -> {
-                        updateSensorLocation()
                         pw.println("fingerprint ripple sensorLocation=$fingerprintSensorLocation")
                         showUnlockRipple(BiometricSourceType.FINGERPRINT)
                     }
                     "face" -> {
                         // note: only shows when about to proceed to the home screen
-                        updateSensorLocation()
                         pw.println("face ripple sensorLocation=$faceSensorLocation")
                         showUnlockRipple(BiometricSourceType.FACE)
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricMessageDeferral.kt b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricMessageDeferral.kt
deleted file mode 100644
index f2d8aaa..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricMessageDeferral.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics
-
-/**
- * Provides whether an acquired error message should be shown immediately when its received (see
- * [shouldDefer]) or should be shown when the biometric error is received [getDeferredMessage].
- * @property excludedMessages messages that are excluded from counts
- * @property messagesToDefer messages that shouldn't show immediately when received, but may be
- * shown later if the message is the most frequent message processed and meets [THRESHOLD]
- * percentage of all messages (excluding [excludedMessages])
- */
-class BiometricMessageDeferral(
-    private val excludedMessages: Set<Int>,
-    private val messagesToDefer: Set<Int>
-) {
-    private val msgCounts: MutableMap<Int, Int> = HashMap() // msgId => frequency of msg
-    private val msgIdToCharSequence: MutableMap<Int, CharSequence> = HashMap() // msgId => message
-    private var totalRelevantMessages = 0
-    private var mostFrequentMsgIdToDefer: Int? = null
-
-    /** Reset all saved counts. */
-    fun reset() {
-        totalRelevantMessages = 0
-        msgCounts.clear()
-        msgIdToCharSequence.clear()
-    }
-
-    /** Whether the given message should be deferred instead of being shown immediately. */
-    fun shouldDefer(acquiredMsgId: Int): Boolean {
-        return messagesToDefer.contains(acquiredMsgId)
-    }
-
-    /**
-     * Adds the acquiredMsgId to the counts if it's not in [excludedMessages]. We still count
-     * messages that shouldn't be deferred in these counts.
-     */
-    fun processMessage(acquiredMsgId: Int, helpString: CharSequence) {
-        if (excludedMessages.contains(acquiredMsgId)) {
-            return
-        }
-
-        totalRelevantMessages++
-        msgIdToCharSequence[acquiredMsgId] = helpString
-
-        val newAcquiredMsgCount = msgCounts.getOrDefault(acquiredMsgId, 0) + 1
-        msgCounts[acquiredMsgId] = newAcquiredMsgCount
-        if (
-            messagesToDefer.contains(acquiredMsgId) &&
-                (mostFrequentMsgIdToDefer == null ||
-                    newAcquiredMsgCount > msgCounts.getOrDefault(mostFrequentMsgIdToDefer!!, 0))
-        ) {
-            mostFrequentMsgIdToDefer = acquiredMsgId
-        }
-    }
-
-    /**
-     * Get the most frequent deferred message that meets the [THRESHOLD] percentage of processed
-     * messages excluding [excludedMessages].
-     * @return null if no messages have been deferred OR deferred messages didn't meet the
-     * [THRESHOLD] percentage of messages to show.
-     */
-    fun getDeferredMessage(): CharSequence? {
-        mostFrequentMsgIdToDefer?.let {
-            if (msgCounts.getOrDefault(it, 0) > (THRESHOLD * totalRelevantMessages)) {
-                return msgIdToCharSequence[mostFrequentMsgIdToDefer]
-            }
-        }
-
-        return null
-    }
-    companion object {
-        const val THRESHOLD = .5f
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt
new file mode 100644
index 0000000..fabc1c1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics
+
+import android.content.res.Resources
+import com.android.keyguard.logging.BiometricMessageDeferralLogger
+import com.android.keyguard.logging.FaceMessageDeferralLogger
+import com.android.systemui.Dumpable
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
+import java.io.PrintWriter
+import java.util.*
+import javax.inject.Inject
+
+/**
+ * Provides whether a face acquired help message should be shown immediately when its received or
+ * should be shown when face auth times out. See [updateMessage] and [getDeferredMessage].
+ */
+@SysUISingleton
+class FaceHelpMessageDeferral
+@Inject
+constructor(
+    @Main resources: Resources,
+    logBuffer: FaceMessageDeferralLogger,
+    dumpManager: DumpManager
+) :
+    BiometricMessageDeferral(
+        resources.getIntArray(R.array.config_face_help_msgs_defer_until_timeout).toHashSet(),
+        resources.getFloat(R.dimen.config_face_help_msgs_defer_until_timeout_threshold),
+        logBuffer,
+        dumpManager
+    )
+
+/**
+ * @property messagesToDefer messages that shouldn't show immediately when received, but may be
+ * shown later if the message is the most frequent acquiredInfo processed and meets [threshold]
+ * percentage of all passed acquired frames.
+ */
+open class BiometricMessageDeferral(
+    private val messagesToDefer: Set<Int>,
+    private val threshold: Float,
+    private val logBuffer: BiometricMessageDeferralLogger,
+    dumpManager: DumpManager
+) : Dumpable {
+    private val acquiredInfoToFrequency: MutableMap<Int, Int> = HashMap()
+    private val acquiredInfoToHelpString: MutableMap<Int, String> = HashMap()
+    private var mostFrequentAcquiredInfoToDefer: Int? = null
+    private var totalFrames = 0
+
+    init {
+        dumpManager.registerDumpable(this.javaClass.name, this)
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("messagesToDefer=$messagesToDefer")
+        pw.println("totalFrames=$totalFrames")
+        pw.println("threshold=$threshold")
+    }
+
+    /** Reset all saved counts. */
+    fun reset() {
+        totalFrames = 0
+        mostFrequentAcquiredInfoToDefer = null
+        acquiredInfoToFrequency.clear()
+        acquiredInfoToHelpString.clear()
+        logBuffer.reset()
+    }
+
+    /** Updates the message associated with the acquiredInfo if it's a message we may defer. */
+    fun updateMessage(acquiredInfo: Int, helpString: String) {
+        if (!messagesToDefer.contains(acquiredInfo)) {
+            return
+        }
+        if (!Objects.equals(acquiredInfoToHelpString[acquiredInfo], helpString)) {
+            logBuffer.logUpdateMessage(acquiredInfo, helpString)
+            acquiredInfoToHelpString[acquiredInfo] = helpString
+        }
+    }
+
+    /** Whether the given message should be deferred instead of being shown immediately. */
+    fun shouldDefer(acquiredMsgId: Int): Boolean {
+        return messagesToDefer.contains(acquiredMsgId)
+    }
+
+    /** Adds the acquiredInfo frame to the counts. We account for all frames. */
+    fun processFrame(acquiredInfo: Int) {
+        if (messagesToDefer.isEmpty()) {
+            return
+        }
+
+        totalFrames++
+
+        val newAcquiredInfoCount = acquiredInfoToFrequency.getOrDefault(acquiredInfo, 0) + 1
+        acquiredInfoToFrequency[acquiredInfo] = newAcquiredInfoCount
+        if (
+            messagesToDefer.contains(acquiredInfo) &&
+                (mostFrequentAcquiredInfoToDefer == null ||
+                    newAcquiredInfoCount >
+                        acquiredInfoToFrequency.getOrDefault(mostFrequentAcquiredInfoToDefer!!, 0))
+        ) {
+            mostFrequentAcquiredInfoToDefer = acquiredInfo
+        }
+
+        logBuffer.logFrameProcessed(
+            acquiredInfo,
+            totalFrames,
+            mostFrequentAcquiredInfoToDefer?.toString()
+        )
+    }
+
+    /**
+     * Get the most frequent deferred message that meets the [threshold] percentage of processed
+     * frames.
+     * @return null if no acquiredInfo have been deferred OR deferred messages didn't meet the
+     * [threshold] percentage.
+     */
+    fun getDeferredMessage(): CharSequence? {
+        mostFrequentAcquiredInfoToDefer?.let {
+            if (acquiredInfoToFrequency.getOrDefault(it, 0) > (threshold * totalFrames)) {
+                return acquiredInfoToHelpString[it]
+            }
+        }
+        return null
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
index 9281eb8..ad96612 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
@@ -54,13 +54,13 @@
         getDrawable().onSensorRectUpdated(bounds);
     }
 
-    void onIlluminationStarting() {
-        getDrawable().setIlluminationShowing(true);
+    void onDisplayConfiguring() {
+        getDrawable().setDisplayConfigured(true);
         getDrawable().invalidateSelf();
     }
 
-    void onIlluminationStopped() {
-        getDrawable().setIlluminationShowing(false);
+    void onDisplayUnconfigured() {
+        getDrawable().setDisplayConfigured(false);
         getDrawable().invalidateSelf();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
index 742c65c..3ad2bef 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
@@ -31,10 +31,10 @@
 /**
  * Handles:
  * 1. registering for listeners when its view is attached and unregistering on view detached
- * 2. pausing udfps when fingerprintManager may still be running but we temporarily want to hide
+ * 2. pausing UDFPS when FingerprintManager may still be running but we temporarily want to hide
  * the affordance. this allows us to fade the view in and out nicely (see shouldPauseAuth)
  * 3. sending events to its view including:
- * - illumination events
+ * - enabling and disabling of the UDFPS display mode
  * - sensor position changes
  * - doze time event
  */
@@ -167,19 +167,20 @@
     }
 
     /**
-     * Udfps has started illuminating and the fingerprint manager is working on authenticating.
+     * The display began transitioning into the UDFPS mode and the fingerprint manager started
+     * authenticating.
      */
-    fun onIlluminationStarting() {
-        view.onIlluminationStarting()
+    fun onDisplayConfiguring() {
+        view.onDisplayConfiguring()
         view.postInvalidate()
     }
 
     /**
-     * Udfps has stopped illuminating and the fingerprint manager is no longer attempting to
-     * authenticate.
+     * The display transitioned away from the UDFPS mode and the fingerprint manager stopped
+     * authenticating.
      */
-    fun onIlluminationStopped() {
-        view.onIlluminationStopped()
+    fun onDisplayUnconfigured() {
+        view.onDisplayUnconfigured()
         view.postInvalidate()
     }
 
@@ -197,4 +198,4 @@
      * Called when a view should announce an accessibility event.
      */
     open fun doAnnounceForAccessibility(str: String) {}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 7f2680b..27e9af9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -86,7 +86,7 @@
 
 /**
  * Shows and hides the under-display fingerprint sensor (UDFPS) overlay, handles UDFPS touch events,
- * and coordinates triggering of the high-brightness mode (HBM).
+ * and toggles the UDFPS display mode.
  *
  * Note that the current architecture is designed so that a single {@link UdfpsController}
  * controls/manages all UDFPS sensors. In other words, a single controller is registered with
@@ -123,7 +123,7 @@
     @NonNull private final PowerManager mPowerManager;
     @NonNull private final AccessibilityManager mAccessibilityManager;
     @NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
-    @Nullable private final UdfpsHbmProvider mHbmProvider;
+    @Nullable private final UdfpsDisplayModeProvider mUdfpsDisplayMode;
     @NonNull private final ConfigurationController mConfigurationController;
     @NonNull private final SystemClock mSystemClock;
     @NonNull private final UnlockedScreenOffAnimationController
@@ -135,7 +135,6 @@
     // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
     // sensors, this, in addition to a lot of the code here, will be updated.
     @VisibleForTesting int mSensorId;
-    private boolean mHalControlsIllumination;
     @VisibleForTesting @NonNull UdfpsOverlayParams mOverlayParams = new UdfpsOverlayParams();
     // TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this.
     @Nullable private Runnable mAuthControllerUpdateUdfpsLocation;
@@ -147,10 +146,9 @@
     private int mActivePointerId = -1;
     // The timestamp of the most recent touch log.
     private long mTouchLogTime;
-    // Sensor has a capture (good or bad) for this touch. Do not need to illuminate for this
-    // particular touch event anymore. In other words, do not illuminate until user lifts and
-    // touches the sensor area again.
-    // TODO: We should probably try to make touch/illumination things more of a FSM
+    // Sensor has a capture (good or bad) for this touch. No need to enable the UDFPS display mode
+    // anymore for this particular touch event. In other words, do not enable the UDFPS mode until
+    // the user touches the sensor area again.
     private boolean mAcquiredReceived;
 
     // The current request from FingerprintService. Null if no current request.
@@ -211,8 +209,8 @@
                             mKeyguardUpdateMonitor, mDialogManager, mDumpManager,
                             mLockscreenShadeTransitionController, mConfigurationController,
                             mSystemClock, mKeyguardStateController,
-                            mUnlockedScreenOffAnimationController, mHalControlsIllumination,
-                            mHbmProvider, requestId, reason, callback,
+                            mUnlockedScreenOffAnimationController,
+                            mUdfpsDisplayMode, requestId, reason, callback,
                             (view, event, fromUdfpsView) -> onTouch(requestId, event,
                                     fromUdfpsView), mActivityLaunchAnimator)));
         }
@@ -236,7 +234,7 @@
                 int sensorId,
                 @BiometricFingerprintConstants.FingerprintAcquired int acquiredInfo
         ) {
-            if (BiometricFingerprintConstants.shouldTurnOffHbm(acquiredInfo)) {
+            if (BiometricFingerprintConstants.shouldDisableUdfpsDisplayMode(acquiredInfo)) {
                 boolean acquiredGood = acquiredInfo == FINGERPRINT_ACQUIRED_GOOD;
                 mFgExecutor.execute(() -> {
                     if (mOverlay == null) {
@@ -247,7 +245,7 @@
                     mAcquiredReceived = true;
                     final UdfpsView view = mOverlay.getOverlayView();
                     if (view != null) {
-                        view.stopIllumination(); // turn off HBM
+                        view.unconfigureDisplay();
                     }
                     if (acquiredGood) {
                         mOverlay.onAcquiredGood();
@@ -292,7 +290,7 @@
     /**
      * Updates the overlay parameters and reconstructs or redraws the overlay, if necessary.
      *
-     * @param sensorId sensor for which the overlay is getting updated.
+     * @param sensorId      sensor for which the overlay is getting updated.
      * @param overlayParams See {@link UdfpsOverlayParams}.
      */
     public void updateOverlayParams(int sensorId, @NonNull UdfpsOverlayParams overlayParams) {
@@ -321,11 +319,6 @@
         mAuthControllerUpdateUdfpsLocation = r;
     }
 
-    // TODO(b/229290039): UDFPS controller should manage its properties on its own. Remove this.
-    public void setHalControlsIllumination(boolean value) {
-        mHalControlsIllumination = value;
-    }
-
     /**
      * Calculate the pointer speed given a velocity tracker and the pointer id.
      * This assumes that the velocity tracker has already been passed all relevant motion events.
@@ -349,8 +342,11 @@
             if (mOverlay != null
                     && mOverlay.getRequestReason() != REASON_AUTH_KEYGUARD
                     && Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
-                Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received, mRequestReason: "
-                        + mOverlay.getRequestReason());
+                String reason = intent.getStringExtra("reason");
+                reason = (reason != null) ? reason : "unknown";
+                Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received, reason: " + reason
+                        + ", mRequestReason: " + mOverlay.getRequestReason());
+
                 mOverlay.cancel();
                 hideUdfpsOverlay();
             }
@@ -369,8 +365,8 @@
     }
 
     /**
-     * @param x coordinate
-     * @param y coordinate
+     * @param x                   coordinate
+     * @param y                   coordinate
      * @param relativeToUdfpsView true if the coordinates are relative to the udfps view; else,
      *                            calculate from the display dimensions in portrait orientation
      */
@@ -423,7 +419,7 @@
         }
 
         final UdfpsView udfpsView = mOverlay.getOverlayView();
-        final boolean isIlluminationRequested = udfpsView.isIlluminationRequested();
+        final boolean isDisplayConfigured = udfpsView.isDisplayConfigured();
         boolean handled = false;
         switch (event.getActionMasked()) {
             case MotionEvent.ACTION_OUTSIDE:
@@ -507,7 +503,7 @@
                                 "minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b",
                                 minor, major, v, exceedsVelocityThreshold);
                         final long sinceLastLog = mSystemClock.elapsedRealtime() - mTouchLogTime;
-                        if (!isIlluminationRequested && !mAcquiredReceived
+                        if (!isDisplayConfigured && !mAcquiredReceived
                                 && !exceedsVelocityThreshold) {
 
                             final float scale = mOverlayParams.getScaleFactor();
@@ -598,7 +594,7 @@
             @NonNull VibratorHelper vibrator,
             @NonNull UdfpsHapticsSimulator udfpsHapticsSimulator,
             @NonNull UdfpsShell udfpsShell,
-            @NonNull Optional<UdfpsHbmProvider> hbmProvider,
+            @NonNull Optional<UdfpsDisplayModeProvider> udfpsDisplayMode,
             @NonNull KeyguardStateController keyguardStateController,
             @NonNull DisplayManager displayManager,
             @Main Handler mainHandler,
@@ -630,7 +626,7 @@
         mPowerManager = powerManager;
         mAccessibilityManager = accessibilityManager;
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
-        mHbmProvider = hbmProvider.orElse(null);
+        mUdfpsDisplayMode = udfpsDisplayMode.orElse(null);
         screenLifecycle.addObserver(mScreenObserver);
         mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
         mConfigurationController = configurationController;
@@ -804,15 +800,14 @@
     }
 
     /**
-     * Cancel updfs scan affordances - ability to hide the HbmSurfaceView (white circle) before
-     * user explicitly lifts their finger. Generally, this should be called whenever udfps fails
-     * or errors.
+     * Cancel UDFPS affordances - ability to hide the UDFPS overlay before the user explicitly
+     * lifts their finger. Generally, this should be called on errors in the authentication flow.
      *
      * The sensor that triggers an AOD fingerprint interrupt (see onAodInterrupt) doesn't give
      * ACTION_UP/ACTION_CANCEL events, so and AOD interrupt scan needs to be cancelled manually.
      * This should be called when authentication either succeeds or fails. Failing to cancel the
-     * scan will leave the screen in high brightness mode and will show the HbmSurfaceView until
-     * the user lifts their finger.
+     * scan will leave the display in the UDFPS mode until the user lifts their finger. On optical
+     * sensors, this can result in illumination persisting for longer than necessary.
      */
     void onCancelUdfps() {
         if (mOverlay != null && mOverlay.getOverlayView() != null) {
@@ -874,7 +869,7 @@
         Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
         final UdfpsView view = mOverlay.getOverlayView();
         if (view != null) {
-            view.startIllumination(() -> {
+            view.configureDisplay(() -> {
                 if (mAlternateTouchProvider != null) {
                     mBiometricExecutor.execute(() -> {
                         mAlternateTouchProvider.onUiReady();
@@ -914,8 +909,8 @@
             }
         }
         mOnFingerDown = false;
-        if (view.isIlluminationRequested()) {
-            view.stopIllumination();
+        if (view.isDisplayConfigured()) {
+            view.unconfigureDisplay();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index ec72057..1c62f8a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -77,8 +77,7 @@
     private val systemClock: SystemClock,
     private val keyguardStateController: KeyguardStateController,
     private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
-    private val halControlsIllumination: Boolean,
-    private var hbmProvider: UdfpsHbmProvider,
+    private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider,
     val requestId: Long,
     @ShowReason val requestReason: Int,
     private val controllerCallback: IUdfpsOverlayControllerCallback,
@@ -102,8 +101,8 @@
         fitInsetsTypes = 0
         gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
         layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
-        flags =
-            (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
+        flags = (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or
+          WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
         privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
         // Avoid announcing window title.
         accessibilityTitle = " "
@@ -140,8 +139,7 @@
                     R.layout.udfps_view, null, false
                 ) as UdfpsView).apply {
                     overlayParams = params
-                    halControlsIllumination = this@UdfpsControllerOverlay.halControlsIllumination
-                    setHbmProvider(hbmProvider)
+                    setUdfpsDisplayModeProvider(udfpsDisplayModeProvider)
                     val animation = inflateUdfpsAnimation(this, controller)
                     if (animation != null) {
                         animation.init()
@@ -250,8 +248,8 @@
         val wasShowing = isShowing
 
         overlayView?.apply {
-            if (isIlluminationRequested) {
-                stopIllumination()
+            if (isDisplayConfigured) {
+                unconfigureDisplay()
             }
             windowManager.removeView(this)
             setOnTouchListener(null)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDisplayModeProvider.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDisplayModeProvider.java
new file mode 100644
index 0000000..c6957ac
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDisplayModeProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics;
+
+import android.annotation.Nullable;
+
+/**
+ * Interface for toggling the optimal display mode for the under-display fingerprint sensor
+ * (UDFPS). For example, the implementation might change the refresh rate and activate a
+ * high-brightness mode.
+ */
+public interface UdfpsDisplayModeProvider {
+
+    /**
+     * Enables the optimal display mode for UDFPS. The mode will persist until
+     * {@link #disable(Runnable)} is called.
+     *
+     * This call must be made from the UI thread. The callback, if provided, will also be invoked
+     * from the UI thread.
+     *
+     * @param onEnabled A runnable that will be executed once the mode is enabled.
+     */
+    void enable(@Nullable Runnable onEnabled);
+
+    /**
+     * Disables the mode that was enabled by {@link #enable(Runnable)}.
+     *
+     * The call must be made from the UI thread. The callback, if provided, will also be invoked
+     * from the UI thread.
+     *
+     * @param onDisabled A runnable that will be executed once mode is disabled.
+     */
+    void disable(@Nullable Runnable onDisabled);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
index ee112b4..511b4e3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
@@ -51,7 +51,7 @@
             invalidateSelf()
         }
 
-    var isIlluminationShowing: Boolean = false
+    var isDisplayConfigured: Boolean = false
         set(showing) {
             if (field == showing) {
                 return
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java
index 1317492..1e35958 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java
@@ -197,7 +197,7 @@
 
     @Override
     public void draw(@NonNull Canvas canvas) {
-        if (isIlluminationShowing()) {
+        if (isDisplayConfigured()) {
             return;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.kt
index 1afa36b..9f6b6d7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.kt
@@ -23,7 +23,7 @@
  */
 class UdfpsFpDrawable(context: Context) : UdfpsDrawable(context) {
     override fun draw(canvas: Canvas) {
-        if (isIlluminationShowing) {
+        if (isDisplayConfigured) {
             return
         }
         fingerprintDrawable.draw(canvas)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java
deleted file mode 100644
index f26dd5f..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.annotation.Nullable;
-
-/**
- * Interface for controlling the high-brightness mode (HBM). UdfpsView can use this callback to
- * enable the HBM while showing the fingerprint illumination, and to disable the HBM after the
- * illumination is no longer necessary.
- */
-public interface UdfpsHbmProvider {
-
-    /**
-     * UdfpsView will call this to enable the HBM when the fingerprint illumination is needed.
-     *
-     * This method is a no-op when some type of HBM is already enabled.
-     *
-     * This method must be called from the UI thread. The callback, if provided, will also be
-     * invoked from the UI thread.
-     *
-     * @param onHbmEnabled A runnable that will be executed once HBM is enabled.
-     *
-     * TODO(b/231335067): enableHbm with halControlsIllumination=true shouldn't make sense.
-     *     This only makes sense now because vendor code may rely on the side effects of enableHbm.
-     */
-    void enableHbm(boolean halControlsIllumination, @Nullable Runnable onHbmEnabled);
-
-    /**
-     * UdfpsView will call this to disable HBM when illumination is no longer needed.
-     *
-     * This method will disable HBM if HBM is enabled. Otherwise, if HBM is already disabled,
-     * this method is a no-op.
-     *
-     * The call must be made from the UI thread. The callback, if provided, will also be invoked
-     * from the UI thread.
-     *
-     * @param onHbmDisabled A runnable that will be executed once HBM is disabled.
-     */
-    void disableHbm(@Nullable Runnable onHbmDisabled);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsIlluminator.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsIlluminator.java
deleted file mode 100644
index f85e936..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsIlluminator.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.annotation.Nullable;
-
-/**
- * Interface that should be implemented by UI's that need to coordinate user touches,
- * views/animations, and modules that start/stop display illumination.
- */
-interface UdfpsIlluminator {
-    /**
-     * @param hbmProvider Invoked when HBM should be enabled or disabled.
-     */
-    void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider);
-
-    /**
-     * Invoked when illumination should start.
-     * @param onIlluminatedRunnable Invoked when the display has been illuminated.
-     */
-    void startIllumination(@Nullable Runnable onIlluminatedRunnable);
-
-    /**
-     * Invoked when illumination should end.
-     */
-    void stopIllumination();
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index f28fedb..bc274a0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -101,11 +101,11 @@
     }
 
     @Override
-    void onIlluminationStarting() {
+    void onDisplayConfiguring() {
     }
 
     @Override
-    void onIlluminationStopped() {
+    void onDisplayUnconfigured() {
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
index 245c225..a15456d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
@@ -36,12 +36,12 @@
 class UdfpsView(
     context: Context,
     attrs: AttributeSet?
-) : FrameLayout(context, attrs), DozeReceiver, UdfpsIlluminator {
+) : FrameLayout(context, attrs), DozeReceiver {
 
     // sensorRect may be bigger than the sensor. True sensor dimensions are defined in
     // overlayParams.sensorBounds
     private val sensorRect = RectF()
-    private var hbmProvider: UdfpsHbmProvider? = null
+    private var mUdfpsDisplayMode: UdfpsDisplayModeProvider? = null
     private val debugTextPaint = Paint().apply {
         isAntiAlias = true
         color = Color.BLUE
@@ -56,19 +56,12 @@
             a.getFloat(R.styleable.UdfpsView_sensorTouchAreaCoefficient, 0f)
         }
 
-    private val onIlluminatedDelayMs = context.resources.getInteger(
-        com.android.internal.R.integer.config_udfps_illumination_transition_ms
-    ).toLong()
-
     /** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */
     var animationViewController: UdfpsAnimationViewController<*>? = null
 
     /** Parameters that affect the position and size of the overlay. */
     var overlayParams = UdfpsOverlayParams()
 
-    /** Whether the HAL is responsible for enabling and disabling of LHBM. */
-    var halControlsIllumination: Boolean = true
-
     /** Debug message. */
     var debugMessage: String? = null
         set(value) {
@@ -76,12 +69,12 @@
             postInvalidate()
         }
 
-    /** When [startIllumination] has been called but not stopped via [stopIllumination]. */
-    var isIlluminationRequested: Boolean = false
+    /** True after the call to [configureDisplay] and before the call to [unconfigureDisplay]. */
+    var isDisplayConfigured: Boolean = false
         private set
 
-    override fun setHbmProvider(provider: UdfpsHbmProvider?) {
-        hbmProvider = provider
+    fun setUdfpsDisplayModeProvider(udfpsDisplayModeProvider: UdfpsDisplayModeProvider?) {
+        mUdfpsDisplayMode = udfpsDisplayModeProvider
     }
 
     // Don't propagate any touch events to the child views.
@@ -124,7 +117,7 @@
 
     override fun onDraw(canvas: Canvas) {
         super.onDraw(canvas)
-        if (!isIlluminationRequested) {
+        if (!isDisplayConfigured) {
             if (!debugMessage.isNullOrEmpty()) {
                 canvas.drawText(debugMessage!!, 0f, 160f, debugTextPaint)
             }
@@ -147,36 +140,15 @@
             !(animationViewController?.shouldPauseAuth() ?: false)
     }
 
-    /**
-     * Start and run [onIlluminatedRunnable] when the first illumination frame reaches the panel.
-     */
-    override fun startIllumination(onIlluminatedRunnable: Runnable?) {
-        isIlluminationRequested = true
-        animationViewController?.onIlluminationStarting()
-        doIlluminate(onIlluminatedRunnable)
+    fun configureDisplay(onDisplayConfigured: Runnable) {
+        isDisplayConfigured = true
+        animationViewController?.onDisplayConfiguring()
+        mUdfpsDisplayMode?.enable(onDisplayConfigured)
     }
 
-    private fun doIlluminate(onIlluminatedRunnable: Runnable?) {
-        // TODO(b/231335067): enableHbm with halControlsIllumination=true shouldn't make sense.
-        // This only makes sense now because vendor code may rely on the side effects of enableHbm.
-        hbmProvider?.enableHbm(halControlsIllumination) {
-            if (onIlluminatedRunnable != null) {
-                if (halControlsIllumination) {
-                    onIlluminatedRunnable.run()
-                } else {
-                    // No framework API can reliably tell when a frame reaches the panel. A timeout
-                    // is the safest solution.
-                    postDelayed(onIlluminatedRunnable, onIlluminatedDelayMs)
-                }
-            } else {
-                Log.w(TAG, "doIlluminate | onIlluminatedRunnable is null")
-            }
-        }
-    }
-
-    override fun stopIllumination() {
-        isIlluminationRequested = false
-        animationViewController?.onIlluminationStopped()
-        hbmProvider?.disableHbm(null /* onHbmDisabled */)
+    fun unconfigureDisplay() {
+        isDisplayConfigured = false
+        animationViewController?.onDisplayUnconfigured()
+        mUdfpsDisplayMode?.disable(null /* onDisabled */)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BluetoothLogger.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/BluetoothLogger.kt
new file mode 100644
index 0000000..96af42b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BluetoothLogger.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.BluetoothLog
+import javax.inject.Inject
+
+/** Helper class for logging bluetooth events. */
+@SysUISingleton
+class BluetoothLogger @Inject constructor(@BluetoothLog private val logBuffer: LogBuffer) {
+    fun logActiveDeviceChanged(address: String?, profileId: Int) =
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = address
+                int1 = profileId
+            },
+            { "ActiveDeviceChanged. address=$str1 profileId=$int1" }
+        )
+
+    fun logDeviceConnectionStateChanged(address: String?, state: String) =
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = address
+                str2 = state
+            },
+            { "DeviceConnectionStateChanged. address=$str1 state=$str2" }
+        )
+
+    fun logAclConnectionStateChanged(address: String, state: String) =
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = address
+                str2 = state
+            },
+            { "AclConnectionStateChanged. address=$str1 state=$str2" }
+        )
+
+    fun logProfileConnectionStateChanged(address: String?, state: String, profileId: Int) =
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = address
+                str2 = state
+                int1 = profileId
+            },
+            { "ProfileConnectionStateChanged. address=$str1 state=$str2 profileId=$int1" }
+        )
+
+    fun logStateChange(state: String) =
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { str1 = state },
+            { "BluetoothStateChanged. state=$str1" }
+        )
+
+    fun logBondStateChange(address: String, state: Int) =
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = address
+                int1 = state
+            },
+            { "DeviceBondStateChanged. address=$str1 state=$int1" }
+        )
+
+    fun logDeviceAdded(address: String) =
+        logBuffer.log(TAG, LogLevel.DEBUG, { str1 = address }, { "DeviceAdded. address=$str1" })
+
+    fun logDeviceDeleted(address: String) =
+        logBuffer.log(TAG, LogLevel.DEBUG, { str1 = address }, { "DeviceDeleted. address=$str1" })
+
+    fun logDeviceAttributesChanged() =
+        logBuffer.log(TAG, LogLevel.DEBUG, {}, { "DeviceAttributesChanged." })
+}
+
+private const val TAG = "BluetoothLog"
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 31a2134..bfbf37a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -291,7 +291,7 @@
                         FalsingClassifier.Result.falsed(
                                 0, getClass().getSimpleName(), "bad history"));
                 logDebug("False Single Tap: true (bad history)");
-                mFalsingTapListeners.forEach(FalsingTapListener::onDoubleTapRequired);
+                mFalsingTapListeners.forEach(FalsingTapListener::onAdditionalTapRequired);
                 return true;
             } else {
                 mPriorResults = getPassedResult(0.1);
@@ -321,7 +321,7 @@
                 mHistoryTracker.falseBelief(),
                 mHistoryTracker.falseConfidence());
         mPriorResults = Collections.singleton(result);
-        logDebug("False Double Tap: " + result.isFalse());
+        logDebug("False Double Tap: " + result.isFalse() + " reason=" + result.getReason());
         return result.isFalse();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index 23d87ff..f5f9655 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -303,9 +303,7 @@
 
     @Override
     public void onTouchEvent(MotionEvent ev) {
-        if (!mKeyguardStateController.isShowing()
-                || (mStatusBarStateController.isDozing()
-                    && !mStatusBarStateController.isPulsing())) {
+        if (!mKeyguardStateController.isShowing()) {
             avoidGesture();
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index c21e36a..7e499eb 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -119,15 +119,12 @@
  */
 public class ClipboardOverlayController {
     private static final String TAG = "ClipboardOverlayCtrlr";
-    private static final String REMOTE_COPY_ACTION = "android.intent.action.REMOTE_COPY";
 
     /** Constants for screenshot/copy deconflicting */
     public static final String SCREENSHOT_ACTION = "com.android.systemui.SCREENSHOT";
     public static final String SELF_PERMISSION = "com.android.systemui.permission.SELF";
     public static final String COPY_OVERLAY_ACTION = "com.android.systemui.COPY";
 
-    private static final String EXTRA_EDIT_SOURCE_CLIPBOARD = "edit_source_clipboard";
-
     private static final int CLIPBOARD_DEFAULT_TIMEOUT_MILLIS = 6000;
     private static final int SWIPE_PADDING_DP = 12; // extra padding around views to allow swipe
     private static final int FONT_SEARCH_STEP_PX = 4;
@@ -383,7 +380,7 @@
                     mTextPreview);
             accessibilityAnnouncement = mContext.getString(R.string.clipboard_content_copied);
         }
-        Intent remoteCopyIntent = getRemoteCopyIntent(clipData);
+        Intent remoteCopyIntent = IntentCreator.getRemoteCopyIntent(clipData, mContext);
         // Only show remote copy if it's available.
         PackageManager packageManager = mContext.getPackageManager();
         if (packageManager.resolveActivity(
@@ -500,41 +497,19 @@
 
     private void editImage(Uri uri) {
         mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_EDIT_TAPPED);
-        String editorPackage = mContext.getString(R.string.config_screenshotEditor);
-        Intent editIntent = new Intent(Intent.ACTION_EDIT);
-        if (!TextUtils.isEmpty(editorPackage)) {
-            editIntent.setComponent(ComponentName.unflattenFromString(editorPackage));
-        }
-        editIntent.setDataAndType(uri, "image/*");
-        editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        editIntent.putExtra(EXTRA_EDIT_SOURCE_CLIPBOARD, true);
-        mContext.startActivity(editIntent);
+        mContext.startActivity(IntentCreator.getImageEditIntent(uri, mContext));
         animateOut();
     }
 
     private void editText() {
         mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_EDIT_TAPPED);
-        Intent editIntent = new Intent(mContext, EditTextActivity.class);
-        editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        mContext.startActivity(editIntent);
+        mContext.startActivity(IntentCreator.getTextEditorIntent(mContext));
         animateOut();
     }
 
     private void shareContent(ClipData clip) {
         mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_SHARE_TAPPED);
-        Intent shareIntent = new Intent(Intent.ACTION_SEND);
-        shareIntent.setDataAndType(
-                clip.getItemAt(0).getUri(), clip.getDescription().getMimeType(0));
-        shareIntent.putExtra(Intent.EXTRA_TEXT, clip.getItemAt(0).getText().toString());
-        if (clip.getItemAt(0).getUri() != null) {
-            shareIntent.putExtra(Intent.EXTRA_STREAM, clip.getItemAt(0).getUri());
-            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        }
-        Intent chooserIntent = Intent.createChooser(shareIntent, null)
-                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
-                .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        mContext.startActivity(chooserIntent);
+        mContext.startActivity(IntentCreator.getShareIntent(clip, mContext));
         animateOut();
     }
 
@@ -667,20 +642,6 @@
                 mContext.getString(R.string.clipboard_edit), null);
     }
 
-    private Intent getRemoteCopyIntent(ClipData clipData) {
-        Intent nearbyIntent = new Intent(REMOTE_COPY_ACTION);
-
-        String remoteCopyPackage = mContext.getString(R.string.config_remoteCopyPackage);
-        if (!TextUtils.isEmpty(remoteCopyPackage)) {
-            nearbyIntent.setComponent(ComponentName.unflattenFromString(remoteCopyPackage));
-        }
-
-        nearbyIntent.setClipData(clipData);
-        nearbyIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        return nearbyIntent;
-    }
-
     private void animateIn() {
         if (mAccessibilityManager.isEnabled()) {
             mDismissButton.setVisibility(View.VISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
new file mode 100644
index 0000000..3d5e601
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.clipboardoverlay;
+
+import android.content.ClipData;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.text.TextUtils;
+
+import com.android.systemui.R;
+
+class IntentCreator {
+    private static final String EXTRA_EDIT_SOURCE_CLIPBOARD = "edit_source_clipboard";
+    private static final String REMOTE_COPY_ACTION = "android.intent.action.REMOTE_COPY";
+
+    static Intent getTextEditorIntent(Context context) {
+        Intent intent = new Intent(context, EditTextActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        return intent;
+    }
+
+    static Intent getShareIntent(ClipData clipData, Context context) {
+        Intent shareIntent = new Intent(Intent.ACTION_SEND);
+
+        // From the ACTION_SEND docs:
+        //   "If using EXTRA_TEXT, the MIME type should be "text/plain"; otherwise it should be the
+        //    MIME type of the data in EXTRA_STREAM"
+        if (clipData.getItemAt(0).getUri() != null) {
+            shareIntent.setDataAndType(
+                    clipData.getItemAt(0).getUri(), clipData.getDescription().getMimeType(0));
+            shareIntent.putExtra(Intent.EXTRA_STREAM, clipData.getItemAt(0).getUri());
+            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        } else {
+            shareIntent.putExtra(Intent.EXTRA_TEXT, clipData.getItemAt(0).coerceToText(context));
+            shareIntent.setType("text/plain");
+        }
+        Intent chooserIntent = Intent.createChooser(shareIntent, null)
+                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
+                .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+        return chooserIntent;
+    }
+
+    static Intent getImageEditIntent(Uri uri, Context context) {
+        String editorPackage = context.getString(R.string.config_screenshotEditor);
+        Intent editIntent = new Intent(Intent.ACTION_EDIT);
+        if (!TextUtils.isEmpty(editorPackage)) {
+            editIntent.setComponent(ComponentName.unflattenFromString(editorPackage));
+        }
+        editIntent.setDataAndType(uri, "image/*");
+        editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        editIntent.putExtra(EXTRA_EDIT_SOURCE_CLIPBOARD, true);
+        return editIntent;
+    }
+
+    static Intent getRemoteCopyIntent(ClipData clipData, Context context) {
+        Intent nearbyIntent = new Intent(REMOTE_COPY_ACTION);
+
+        String remoteCopyPackage = context.getString(R.string.config_remoteCopyPackage);
+        if (!TextUtils.isEmpty(remoteCopyPackage)) {
+            nearbyIntent.setComponent(ComponentName.unflattenFromString(remoteCopyPackage));
+        }
+
+        nearbyIntent.setClipData(clipData);
+        nearbyIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        return nearbyIntent;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/drawable/CircularDrawable.kt b/packages/SystemUI/src/com/android/systemui/common/ui/drawable/CircularDrawable.kt
new file mode 100644
index 0000000..ec71c38
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/drawable/CircularDrawable.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.common.ui.drawable
+
+import android.graphics.Canvas
+import android.graphics.Path
+import android.graphics.Rect
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.DrawableWrapper
+import kotlin.math.min
+
+/** Renders the wrapped [Drawable] as a circle. */
+class CircularDrawable(
+    drawable: Drawable,
+) : DrawableWrapper(drawable) {
+    private val path: Path by lazy { Path() }
+
+    override fun onBoundsChange(bounds: Rect) {
+        super.onBoundsChange(bounds)
+        updateClipPath()
+    }
+
+    override fun draw(canvas: Canvas) {
+        canvas.save()
+        canvas.clipPath(path)
+        drawable?.draw(canvas)
+        canvas.restore()
+    }
+
+    private fun updateClipPath() {
+        path.reset()
+        path.addCircle(
+            bounds.centerX().toFloat(),
+            bounds.centerY().toFloat(),
+            min(bounds.width(), bounds.height()) / 2f,
+            Path.Direction.CW
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index fbfc94a..a996699 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -35,6 +35,7 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
 import com.android.systemui.doze.DozeHost;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.dagger.MediaModule;
 import com.android.systemui.navigationbar.gestural.GestureModule;
 import com.android.systemui.plugins.qs.QSFactory;
@@ -126,6 +127,7 @@
             PowerManager powerManager,
             BroadcastDispatcher broadcastDispatcher,
             DemoModeController demoModeController,
+            DumpManager dumpManager,
             @Main Handler mainHandler,
             @Background Handler bgHandler) {
         BatteryController bC = new BatteryControllerImpl(
@@ -134,6 +136,7 @@
                 powerManager,
                 broadcastDispatcher,
                 demoModeController,
+                dumpManager,
                 mainHandler,
                 bgHandler);
         bC.init();
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 318529b..0469152 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -30,7 +30,7 @@
 import com.android.systemui.appops.dagger.AppOpsModule;
 import com.android.systemui.assist.AssistModule;
 import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
-import com.android.systemui.biometrics.UdfpsHbmProvider;
+import com.android.systemui.biometrics.UdfpsDisplayModeProvider;
 import com.android.systemui.biometrics.dagger.BiometricsModule;
 import com.android.systemui.classifier.FalsingModule;
 import com.android.systemui.controls.dagger.ControlsModule;
@@ -197,7 +197,7 @@
     abstract CentralSurfaces optionalCentralSurfaces();
 
     @BindsOptionalOf
-    abstract UdfpsHbmProvider optionalUdfpsHbmProvider();
+    abstract UdfpsDisplayModeProvider optionalUdfpsDisplayModeProvider();
 
     @BindsOptionalOf
     abstract AlternateUdfpsTouchProvider optionalUdfpsTouchProvider();
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
index 823255c..f244cb0 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
@@ -61,6 +61,7 @@
 
     private final Map<Integer, View> mStatusIcons = new HashMap<>();
     private ViewGroup mSystemStatusViewGroup;
+    private ViewGroup mExtraSystemStatusViewGroup;
 
     public DreamOverlayStatusBarView(Context context) {
         this(context, null);
@@ -98,7 +99,8 @@
         mStatusIcons.put(STATUS_ICON_PRIORITY_MODE_ON,
                 fetchStatusIconForResId(R.id.dream_overlay_priority_mode));
 
-        mSystemStatusViewGroup = findViewById(R.id.dream_overlay_extra_items);
+        mSystemStatusViewGroup = findViewById(R.id.dream_overlay_system_status);
+        mExtraSystemStatusViewGroup = findViewById(R.id.dream_overlay_extra_items);
     }
 
     void showIcon(@StatusIconType int iconType, boolean show, @Nullable String contentDescription) {
@@ -110,11 +112,12 @@
             icon.setContentDescription(contentDescription);
         }
         icon.setVisibility(show ? View.VISIBLE : View.GONE);
+        mSystemStatusViewGroup.setVisibility(areAnyStatusIconsVisible() ? View.VISIBLE : View.GONE);
     }
 
     void setExtraStatusBarItemViews(List<View> views) {
-        removeAllStatusBarItemViews();
-        views.forEach(view -> mSystemStatusViewGroup.addView(view));
+        removeAllExtraStatusBarItemViews();
+        views.forEach(view -> mExtraSystemStatusViewGroup.addView(view));
     }
 
     private View fetchStatusIconForResId(int resId) {
@@ -122,7 +125,16 @@
         return Objects.requireNonNull(statusIcon);
     }
 
-    void removeAllStatusBarItemViews() {
-        mSystemStatusViewGroup.removeAllViews();
+    void removeAllExtraStatusBarItemViews() {
+        mExtraSystemStatusViewGroup.removeAllViews();
+    }
+
+    private boolean areAnyStatusIconsVisible() {
+        for (int i = 0; i < mSystemStatusViewGroup.getChildCount(); i++) {
+            if (mSystemStatusViewGroup.getChildAt(i).getVisibility() == View.VISIBLE) {
+                return true;
+            }
+        }
+        return false;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index 6f50550..aa59cc6 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -192,7 +192,7 @@
         mDreamOverlayNotificationCountProvider.ifPresent(
                 provider -> provider.removeCallback(mNotificationCountCallback));
         mStatusBarItemsProvider.removeCallback(mStatusBarItemsProviderCallback);
-        mView.removeAllStatusBarItemViews();
+        mView.removeAllExtraStatusBarItemViews();
         mTouchInsetSession.clear();
 
         mIsAttached = false;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextClock.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextClock.java
index 653f4dc..789ebc5 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextClock.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextClock.java
@@ -17,24 +17,21 @@
 package com.android.systemui.dreams.complication;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.util.AttributeSet;
 import android.widget.TextClock;
 
 import com.android.systemui.R;
+import com.android.systemui.dreams.complication.DoubleShadowTextHelper.ShadowInfo;
+
+import kotlin.Unit;
 
 /**
  * Extension of {@link TextClock} which draws two shadows on the text (ambient and key shadows)
  */
 public class DoubleShadowTextClock extends TextClock {
-    private final float mAmbientShadowBlur;
-    private final int mAmbientShadowColor;
-    private final float mKeyShadowBlur;
-    private final float mKeyShadowOffsetX;
-    private final float mKeyShadowOffsetY;
-    private final int mKeyShadowColor;
-    private final float mAmbientShadowOffsetX;
-    private final float mAmbientShadowOffsetY;
+    private final DoubleShadowTextHelper mShadowHelper;
 
     public DoubleShadowTextClock(Context context) {
         this(context, null);
@@ -46,38 +43,28 @@
 
     public DoubleShadowTextClock(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mKeyShadowBlur = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_radius);
-        mKeyShadowOffsetX = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dx);
-        mKeyShadowOffsetY = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dy);
-        mKeyShadowColor = context.getResources().getColor(
-                R.color.dream_overlay_clock_key_text_shadow_color);
-        mAmbientShadowBlur = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_radius);
-        mAmbientShadowColor = context.getResources().getColor(
-                R.color.dream_overlay_clock_ambient_text_shadow_color);
-        mAmbientShadowOffsetX = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dx);
-        mAmbientShadowOffsetY = context.getResources()
-                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dy);
+
+        final Resources resources = context.getResources();
+        final ShadowInfo keyShadowInfo = new ShadowInfo(
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_radius),
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dx),
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dy),
+                resources.getColor(R.color.dream_overlay_clock_key_text_shadow_color));
+
+        final ShadowInfo ambientShadowInfo = new ShadowInfo(
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_clock_ambient_text_shadow_radius),
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dx),
+                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dy),
+                resources.getColor(R.color.dream_overlay_clock_ambient_text_shadow_color));
+        mShadowHelper = new DoubleShadowTextHelper(keyShadowInfo, ambientShadowInfo);
     }
 
     @Override
     public void onDraw(Canvas canvas) {
-        // We enhance the shadow by drawing the shadow twice
-        getPaint().setShadowLayer(mAmbientShadowBlur, mAmbientShadowOffsetX, mAmbientShadowOffsetY,
-                mAmbientShadowColor);
-        super.onDraw(canvas);
-        canvas.save();
-        canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
-                getScrollX() + getWidth(),
-                getScrollY() + getHeight());
-
-        getPaint().setShadowLayer(
-                mKeyShadowBlur, mKeyShadowOffsetX, mKeyShadowOffsetY, mKeyShadowColor);
-        super.onDraw(canvas);
-        canvas.restore();
+        mShadowHelper.applyShadows(this, canvas, () -> {
+            super.onDraw(canvas);
+            return Unit.INSTANCE;
+        });
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextHelper.kt b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextHelper.kt
new file mode 100644
index 0000000..b1dc5a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextHelper.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams.complication
+
+import android.graphics.Canvas
+import android.widget.TextView
+import androidx.annotation.ColorInt
+
+class DoubleShadowTextHelper
+constructor(
+    private val keyShadowInfo: ShadowInfo,
+    private val ambientShadowInfo: ShadowInfo,
+) {
+    data class ShadowInfo(
+        val blur: Float,
+        val offsetX: Float = 0f,
+        val offsetY: Float = 0f,
+        @ColorInt val color: Int
+    )
+
+    fun applyShadows(view: TextView, canvas: Canvas, onDrawCallback: () -> Unit) {
+        // We enhance the shadow by drawing the shadow twice
+        view.paint.setShadowLayer(
+            ambientShadowInfo.blur,
+            ambientShadowInfo.offsetX,
+            ambientShadowInfo.offsetY,
+            ambientShadowInfo.color
+        )
+        onDrawCallback()
+        canvas.save()
+        canvas.clipRect(
+            view.scrollX,
+            view.scrollY + view.extendedPaddingTop,
+            view.scrollX + view.width,
+            view.scrollY + view.height
+        )
+
+        view.paint.setShadowLayer(
+            keyShadowInfo.blur,
+            keyShadowInfo.offsetX,
+            keyShadowInfo.offsetY,
+            keyShadowInfo.color
+        )
+        onDrawCallback()
+        canvas.restore()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextView.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextView.java
new file mode 100644
index 0000000..cf7e312
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DoubleShadowTextView.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams.complication;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+import kotlin.Unit;
+
+/**
+ * Extension of {@link TextView} which draws two shadows on the text (ambient and key shadows}
+ */
+public class DoubleShadowTextView extends TextView {
+    private final DoubleShadowTextHelper mShadowHelper;
+
+    public DoubleShadowTextView(Context context) {
+        this(context, null);
+    }
+
+    public DoubleShadowTextView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public DoubleShadowTextView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        final Resources resources = context.getResources();
+        final DoubleShadowTextHelper.ShadowInfo
+                keyShadowInfo = new DoubleShadowTextHelper.ShadowInfo(
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_key_text_shadow_radius),
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_key_text_shadow_dx),
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_key_text_shadow_dy),
+                resources.getColor(R.color.dream_overlay_status_bar_key_text_shadow_color));
+
+        final DoubleShadowTextHelper.ShadowInfo
+                ambientShadowInfo = new DoubleShadowTextHelper.ShadowInfo(
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_radius),
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_dx),
+                resources.getDimensionPixelSize(
+                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_dy),
+                resources.getColor(R.color.dream_overlay_status_bar_ambient_text_shadow_color));
+        mShadowHelper = new DoubleShadowTextHelper(keyShadowInfo, ambientShadowInfo);
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        mShadowHelper.applyShadows(this, canvas, () -> {
+            super.onDraw(canvas);
+            return Unit.INSTANCE;
+        });
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 3695df5..2540035 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -187,6 +187,9 @@
     // 802 - wallpaper rendering
     public static final UnreleasedFlag USE_CANVAS_RENDERER = new UnreleasedFlag(802);
 
+    // 803 - screen contents translation
+    public static final UnreleasedFlag SCREEN_CONTENTS_TRANSLATION = new UnreleasedFlag(803);
+
     /***************************************/
     // 900 - media
     public static final ReleasedFlag MEDIA_TAP_TO_TRANSFER = new ReleasedFlag(900);
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index a3dc779..568143c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -42,6 +42,8 @@
 import android.util.Slog;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
+
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -601,13 +603,14 @@
 
     private final class BluetoothCallbackHandler implements BluetoothCallback {
         @Override
-        public void onBluetoothStateChanged(int bluetoothState) {
+        public void onBluetoothStateChanged(@BluetoothCallback.AdapterState int bluetoothState) {
             mHandler.obtainMessage(MSG_ON_BLUETOOTH_STATE_CHANGED,
                     bluetoothState, 0).sendToTarget();
         }
 
         @Override
-        public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
+        public void onDeviceBondStateChanged(
+                @NonNull CachedBluetoothDevice cachedDevice, int bondState) {
             mHandler.obtainMessage(MSG_ON_DEVICE_BOND_STATE_CHANGED,
                     bondState, 0, cachedDevice).sendToTarget();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index ee5ef99..1c6cec2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -173,7 +173,8 @@
         }
     }
 
-    // Wrap Keyguard going away animation
+    // Wrap Keyguard going away animation.
+    // Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy).
     private static IRemoteTransition wrap(IRemoteAnimationRunner runner) {
         return new IRemoteTransition.Stub() {
             final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
@@ -353,6 +354,27 @@
         f = new TransitionFilter();
         f.mTypeSet = new int[]{TRANSIT_KEYGUARD_UNOCCLUDE};
         mShellTransitions.registerRemote(f, unoccludeTransition);
+
+        Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_OCCLUDE for DREAM");
+        // Register for occluding by Dream
+        f = new TransitionFilter();
+        f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED;
+        f.mRequirements = new TransitionFilter.Requirement[]{
+                new TransitionFilter.Requirement(), new TransitionFilter.Requirement()};
+        // First require at-least one app of type DREAM showing that occludes.
+        f.mRequirements[0].mActivityType = WindowConfiguration.ACTIVITY_TYPE_DREAM;
+        f.mRequirements[0].mMustBeIndependent = false;
+        f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD;
+        f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
+        // Then require that we aren't closing any occludes (because this would mean a
+        // regular task->task or activity->activity animation not involving keyguard).
+        f.mRequirements[1].mNot = true;
+        f.mRequirements[1].mMustBeIndependent = false;
+        f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD;
+        f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
+        mShellTransitions.registerRemote(f, new RemoteTransition(
+                wrap(mKeyguardViewMediator.getOccludeByDreamAnimationRunner()),
+                getIApplicationThread()));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 8eca1ba..c135b3c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -241,9 +241,8 @@
      */
     @VisibleForTesting
     var surfaceTransactionApplier: SyncRtSurfaceTransactionApplier? = null
-    private var surfaceBehindRemoteAnimationTarget: RemoteAnimationTarget? = null
+    private var surfaceBehindRemoteAnimationTargets: Array<RemoteAnimationTarget>? = null
     private var surfaceBehindRemoteAnimationStartTime: Long = 0
-    private var surfaceBehindParams: SyncRtSurfaceTransactionApplier.SurfaceParams? = null
 
     /**
      * Alpha value applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
@@ -458,7 +457,7 @@
      * (fingerprint, tap, etc.) and the keyguard is going away.
      */
     fun notifyStartSurfaceBehindRemoteAnimation(
-        target: RemoteAnimationTarget,
+        targets: Array<RemoteAnimationTarget>,
         startTime: Long,
         requestedShowSurfaceBehindKeyguard: Boolean
     ) {
@@ -467,10 +466,7 @@
                     keyguardViewController.viewRootImpl.view)
         }
 
-        // New animation, new params.
-        surfaceBehindParams = null
-
-        surfaceBehindRemoteAnimationTarget = target
+        surfaceBehindRemoteAnimationTargets = targets
         surfaceBehindRemoteAnimationStartTime = startTime
 
         // If we specifically requested that the surface behind be made visible (vs. it being made
@@ -597,7 +593,7 @@
      * keyguard dismiss amount and the method of dismissal.
      */
     private fun updateSurfaceBehindAppearAmount() {
-        if (surfaceBehindRemoteAnimationTarget == null) {
+        if (surfaceBehindRemoteAnimationTargets == null) {
             return
         }
 
@@ -710,63 +706,60 @@
      * cancelled).
      */
     fun setSurfaceBehindAppearAmount(amount: Float) {
-        if (surfaceBehindRemoteAnimationTarget == null) {
-            return
-        }
+        surfaceBehindRemoteAnimationTargets?.forEach { surfaceBehindRemoteAnimationTarget ->
+            val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget.screenSpaceBounds.height()
 
-        // Otherwise, animate in the surface's scale/transltion.
-        val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.height()
+            var scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
+                    (1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
+                    MathUtils.clamp(amount, 0f, 1f))
 
-        var scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
-                (1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
-                MathUtils.clamp(amount, 0f, 1f))
-
-        // If we're dismissing via swipe to the Launcher, we'll play in-window scale animations, so
-        // don't also scale the window.
-        if (keyguardStateController.isDismissingFromSwipe &&
-                willUnlockWithInWindowLauncherAnimations) {
-            scaleFactor = 1f
-        }
-
-        // Scale up from a point at the center-bottom of the surface.
-        surfaceBehindMatrix.setScale(
-            scaleFactor,
-            scaleFactor,
-            surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.width() / 2f,
-            surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
-        )
-
-        // Translate up from the bottom.
-        surfaceBehindMatrix.postTranslate(
-            0f,
-            surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
-        )
-
-        // If we're snapping the keyguard back, immediately begin fading it out.
-        val animationAlpha =
-            if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
-            else surfaceBehindAlpha
-
-        // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is unable
-        // to draw
-        val sc: SurfaceControl? = surfaceBehindRemoteAnimationTarget?.leash
-        if (keyguardViewController.viewRootImpl.view?.visibility != View.VISIBLE &&
-            sc?.isValid == true) {
-            with(SurfaceControl.Transaction()) {
-                setMatrix(sc, surfaceBehindMatrix, tmpFloat)
-                setCornerRadius(sc, roundedCornerRadius)
-                setAlpha(sc, animationAlpha)
-                apply()
+            // If we're dismissing via swipe to the Launcher, we'll play in-window scale animations,
+            // so don't also scale the window.
+            if (keyguardStateController.isDismissingFromSwipe &&
+                    willUnlockWithInWindowLauncherAnimations) {
+                scaleFactor = 1f
             }
-        } else {
-            applyParamsToSurface(
-                SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
-                    surfaceBehindRemoteAnimationTarget!!.leash)
-                    .withMatrix(surfaceBehindMatrix)
-                    .withCornerRadius(roundedCornerRadius)
-                    .withAlpha(animationAlpha)
-                    .build()
+
+            // Translate up from the bottom.
+            surfaceBehindMatrix.setTranslate(
+                    surfaceBehindRemoteAnimationTarget.screenSpaceBounds.left.toFloat(),
+                    surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
             )
+
+            // Scale up from a point at the center-bottom of the surface.
+            surfaceBehindMatrix.postScale(
+                    scaleFactor,
+                    scaleFactor,
+                    keyguardViewController.viewRootImpl.width / 2f,
+                    surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
+            )
+
+            // If we're snapping the keyguard back, immediately begin fading it out.
+            val animationAlpha =
+                    if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
+                    else surfaceBehindAlpha
+
+            // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
+            // unable to draw
+            val sc: SurfaceControl? = surfaceBehindRemoteAnimationTarget.leash
+            if (keyguardViewController.viewRootImpl.view?.visibility != View.VISIBLE &&
+                    sc?.isValid == true) {
+                with(SurfaceControl.Transaction()) {
+                    setMatrix(sc, surfaceBehindMatrix, tmpFloat)
+                    setCornerRadius(sc, roundedCornerRadius)
+                    setAlpha(sc, animationAlpha)
+                    apply()
+                }
+            } else {
+                applyParamsToSurface(
+                        SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
+                                surfaceBehindRemoteAnimationTarget.leash)
+                                .withMatrix(surfaceBehindMatrix)
+                                .withCornerRadius(roundedCornerRadius)
+                                .withAlpha(animationAlpha)
+                                .build()
+                )
+            }
         }
     }
 
@@ -791,8 +784,7 @@
         launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
 
         // That target is no longer valid since the animation finished, null it out.
-        surfaceBehindRemoteAnimationTarget = null
-        surfaceBehindParams = null
+        surfaceBehindRemoteAnimationTargets = null
 
         playingCannedUnlockAnimation = false
         willUnlockWithInWindowLauncherAnimations = false
@@ -824,7 +816,6 @@
 
     private fun applyParamsToSurface(params: SyncRtSurfaceTransactionApplier.SurfaceParams) {
         surfaceTransactionApplier!!.scheduleApply(params)
-        surfaceBehindParams = params
     }
 
     private fun fadeInSurfaceBehind() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index dc03436..26db3ee4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -831,7 +831,7 @@
                 public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {}
 
                 @Override
-                public void onLaunchAnimationCancelled() {
+                public void onLaunchAnimationCancelled(@Nullable Boolean newKeyguardOccludedState) {
                     Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: "
                             + mOccluded);
                 }
@@ -2580,18 +2580,10 @@
                 mInteractionJankMonitor.begin(
                         createInteractionJankMonitorConf("DismissPanel"));
 
-                // Apply the opening animation on root task if exists
-                RemoteAnimationTarget aniTarget = apps[0];
-                for (RemoteAnimationTarget tmpTarget : apps) {
-                    if (tmpTarget.taskId != -1 && !tmpTarget.hasAnimatingParent) {
-                        aniTarget = tmpTarget;
-                        break;
-                    }
-                }
                 // Pass the surface and metadata to the unlock animation controller.
                 mKeyguardUnlockAnimationControllerLazy.get()
                         .notifyStartSurfaceBehindRemoteAnimation(
-                                aniTarget, startTime, mSurfaceBehindRemoteAnimationRequested);
+                                apps, startTime, mSurfaceBehindRemoteAnimationRequested);
             } else {
                 mInteractionJankMonitor.begin(
                         createInteractionJankMonitorConf("RemoteAnimationDisabled"));
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/BiometricMessagesLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/BiometricMessagesLog.java
new file mode 100644
index 0000000..7f1ad6d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/BiometricMessagesLog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Qualifier;
+
+/**
+ * A {@link com.android.systemui.log.LogBuffer} for BiometricMessages processing such as
+ * {@link com.android.systemui.biometrics.FaceHelpMessageDeferral}
+ */
+@Qualifier
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BiometricMessagesLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/BluetoothLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/BluetoothLog.kt
new file mode 100644
index 0000000..4887b6a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/BluetoothLog.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger
+
+import javax.inject.Qualifier
+
+/** A [com.android.systemui.log.LogBuffer] for bluetooth. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class BluetoothLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardUpdateMonitorLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardUpdateMonitorLog.kt
index 323ee21..b551125 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardUpdateMonitorLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardUpdateMonitorLog.kt
@@ -1,4 +1,9 @@
 package com.android.systemui.log.dagger
 
+import javax.inject.Qualifier
+
 /** A [com.android.systemui.log.LogBuffer] for KeyguardUpdateMonitor. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
 annotation class KeyguardUpdateMonitorLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index c2a8764..29e2c1c 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -76,6 +76,14 @@
         return factory.create("NotifInterruptLog", 100);
     }
 
+    /** Provides a logging buffer for notification rendering events. */
+    @Provides
+    @SysUISingleton
+    @NotificationRenderLog
+    public static LogBuffer provideNotificationRenderLogBuffer(LogBufferFactory factory) {
+        return factory.create("NotifRenderLog", 100);
+    }
+
     /** Provides a logging buffer for all logs for lockscreen to shade transition events. */
     @Provides
     @SysUISingleton
@@ -287,6 +295,17 @@
     }
 
     /**
+     * Provides a {@link LogBuffer} for use by
+     * {@link com.android.systemui.biometrics.FaceHelpMessageDeferral}.
+     */
+    @Provides
+    @SysUISingleton
+    @BiometricMessagesLog
+    public static LogBuffer provideBiometricMessagesLogBuffer(LogBufferFactory factory) {
+        return factory.create("BiometricMessagesLog", 150);
+    }
+
+    /**
      * Provides a {@link LogBuffer} for use by the status bar network controller.
      */
     @Provides
@@ -305,4 +324,14 @@
     public static LogBuffer provideKeyguardUpdateMonitorLogBuffer(LogBufferFactory factory) {
         return factory.create("KeyguardUpdateMonitorLog", 200);
     }
+
+    /**
+     * Provides a {@link LogBuffer} for bluetooth-related logs.
+     */
+    @Provides
+    @SysUISingleton
+    @BluetoothLog
+    public static LogBuffer providerBluetoothLogBuffer(LogBufferFactory factory) {
+        return factory.create("BluetoothLog", 50);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationRenderLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationRenderLog.java
new file mode 100644
index 0000000..8c8753a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationRenderLog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/** A {@link LogBuffer} for notification rendering logging. */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface NotificationRenderLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java
index f03fbcb..b237f2d 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java
@@ -19,7 +19,6 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.android.systemui.log.LogBuffer;
-import com.android.systemui.statusbar.pipeline.ConnectivityInfoProcessor;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
@@ -27,7 +26,7 @@
 import javax.inject.Qualifier;
 
 /**
- * A {@link LogBuffer} for events processed by {@link ConnectivityInfoProcessor}
+ * A {@link LogBuffer} for status bar connectivity events.
  */
 @Qualifier
 @Documented
diff --git a/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt b/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
index d082655..556560c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
@@ -34,7 +34,7 @@
  * is triggered.
  */
 interface ColorTransition {
-    fun updateColorScheme(scheme: ColorScheme?)
+    fun updateColorScheme(scheme: ColorScheme?): Boolean
 }
 
 /**
@@ -64,14 +64,16 @@
         applyColor(currentColor)
     }
 
-    override fun updateColorScheme(scheme: ColorScheme?) {
+    override fun updateColorScheme(scheme: ColorScheme?): Boolean {
         val newTargetColor = if (scheme == null) defaultColor else extractColor(scheme)
         if (newTargetColor != targetColor) {
             sourceColor = currentColor
             targetColor = newTargetColor
             valueAnimator.cancel()
             valueAnimator.start()
+            return true
         }
+        return false
     }
 
     init {
@@ -198,8 +200,10 @@
         return Utils.getColorAttr(context, id).defaultColor
     }
 
-    fun updateColorScheme(colorScheme: ColorScheme?) {
-        colorTransitions.forEach { it.updateColorScheme(colorScheme) }
+    fun updateColorScheme(colorScheme: ColorScheme?): Boolean {
+        var anyChanged = false
+        colorTransitions.forEach { anyChanged = it.updateColorScheme(colorScheme) || anyChanged }
         colorScheme?.let { mediaViewHolder.gutsViewHolder.colorScheme = colorScheme }
+        return anyChanged
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index cc77ed1..b36f33b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -202,6 +202,7 @@
      * It will be called when the container is out of view.
      */
     lateinit var updateUserVisibility: () -> Unit
+    lateinit var updateHostVisibility: () -> Unit
 
     private val isReorderingAllowed: Boolean
         get() = visualStabilityProvider.isReorderingAllowed
@@ -225,7 +226,13 @@
                 reorderAllPlayers(previousVisiblePlayerKey = null)
             }
 
-            keysNeedRemoval.forEach { removePlayer(it) }
+            keysNeedRemoval.forEach {
+                removePlayer(it)
+            }
+            if (keysNeedRemoval.size > 0) {
+                // Carousel visibility may need to be updated after late removals
+                updateHostVisibility()
+            }
             keysNeedRemoval.clear()
 
             // Update user visibility so that no extra impression will be logged when
@@ -247,6 +254,7 @@
                 receivedSmartspaceCardLatency: Int,
                 isSsReactivated: Boolean
             ) {
+                debugLogger.logMediaLoaded(key)
                 if (addOrUpdatePlayer(key, oldKey, data, isSsReactivated)) {
                     // Log card received if a new resumable media card is added
                     MediaPlayerData.getMediaPlayer(key)?.let {
@@ -315,7 +323,7 @@
                 data: SmartspaceMediaData,
                 shouldPrioritize: Boolean
             ) {
-                if (DEBUG) Log.d(TAG, "Loading Smartspace media update")
+                debugLogger.logRecommendationLoaded(key)
                 // Log the case where the hidden media carousel with the existed inactive resume
                 // media is shown by the Smartspace signal.
                 if (data.isActive) {
@@ -370,13 +378,21 @@
             }
 
             override fun onMediaDataRemoved(key: String) {
+                debugLogger.logMediaRemoved(key)
                 removePlayer(key)
             }
 
             override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) {
-                if (DEBUG) Log.d(TAG, "My Smartspace media removal request is received")
+                debugLogger.logRecommendationRemoved(key, immediately)
                 if (immediately || isReorderingAllowed) {
-                    onMediaDataRemoved(key)
+                    removePlayer(key)
+                    if (!immediately) {
+                        // Although it wasn't requested, we were able to process the removal
+                        // immediately since reordering is allowed. So, notify hosts to update
+                        if (this@MediaCarouselController::updateHostVisibility.isInitialized) {
+                            updateHostVisibility()
+                        }
+                    }
                 } else {
                     keysNeedRemoval.add(key)
                 }
@@ -458,7 +474,7 @@
         val existingPlayer = MediaPlayerData.getMediaPlayer(key)
         val curVisibleMediaKey = MediaPlayerData.playerKeys()
                 .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
-        val isCurVisibleMediaPlaying = MediaPlayerData.getMediaData(curVisibleMediaKey)?.isPlaying
+        val isCurVisibleMediaPlaying = curVisibleMediaKey?.data?.isPlaying
         if (existingPlayer == null) {
             val newPlayer = mediaControlPanelFactory.get()
             newPlayer.attachPlayer(MediaViewHolder.create(
@@ -1046,15 +1062,6 @@
         }
     }
 
-    fun getMediaData(mediaSortKey: MediaSortKey?): MediaData? {
-        mediaData.forEach { (key, value) ->
-            if (value == mediaSortKey) {
-                return mediaData[key]?.data
-            }
-        }
-        return null
-    }
-
     fun getMediaPlayer(key: String): MediaControlPanel? {
         return mediaData.get(key)?.let { mediaPlayers.get(it) }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselControllerLogger.kt
index 04ebd5a..b1018f9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselControllerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselControllerLogger.kt
@@ -40,6 +40,37 @@
                     "Removing control panel for $str1 from map without calling #onDestroy"
         }
     )
+
+    fun logMediaLoaded(key: String) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        { str1 = key },
+        { "add player $str1" }
+    )
+
+    fun logMediaRemoved(key: String) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        { str1 = key },
+        { "removing player $str1" }
+    )
+
+    fun logRecommendationLoaded(key: String) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        { str1 = key },
+        { "add recommendation $str1" }
+    )
+
+    fun logRecommendationRemoved(key: String, immediately: Boolean) = buffer.log(
+        TAG,
+        LogLevel.DEBUG,
+        {
+            str1 = key
+            bool1 = immediately
+        },
+        { "removing recommendation $str1, immediate=$bool1" }
+    )
 }
 
 private const val TAG = "MediaCarouselCtlrLog"
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index b02393b..759795f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -741,10 +741,14 @@
                 }
                 mArtworkBoundId = reqId;
 
+                // Transition Colors to current color scheme
+                boolean colorSchemeChanged = mColorSchemeTransition.updateColorScheme(colorScheme);
+
                 // Bind the album view to the artwork or a transition drawable
                 ImageView albumView = mMediaViewHolder.getAlbumView();
                 albumView.setPadding(0, 0, 0, 0);
-                if (updateBackground || (!mIsArtworkBound && isArtworkBound)) {
+                if (updateBackground || colorSchemeChanged
+                        || (!mIsArtworkBound && isArtworkBound)) {
                     if (mPrevArtwork == null) {
                         albumView.setImageDrawable(artwork);
                     } else {
@@ -767,9 +771,6 @@
                     mIsArtworkBound = isArtworkBound;
                 }
 
-                // Transition Colors to current color scheme
-                mColorSchemeTransition.updateColorScheme(colorScheme);
-
                 // App icon - use notification icon
                 ImageView appIconView = mMediaViewHolder.getAppIcon();
                 appIconView.clearColorFilter();
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index c48271e..896fb47 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -1322,6 +1322,7 @@
             println("externalListeners: ${mediaDataFilter.listeners}")
             println("mediaEntries: $mediaEntries")
             println("useMediaResumption: $useMediaResumption")
+            println("allowMediaRecommendations: $allowMediaRecommendations")
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 6baf6e1..e0b6d1f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -546,6 +546,11 @@
         mediaCarouselController.updateUserVisibility = {
             mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
         }
+        mediaCarouselController.updateHostVisibility = {
+            mediaHosts.forEach {
+                it?.updateViewVisibility()
+            }
+        }
 
         panelEventsEvents.registerListener(object : NotifPanelEvents.Listener {
             override fun onExpandImmediateChanged(isExpandImmediateEnabled: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
index de2b5c9..8645922 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
@@ -167,7 +167,11 @@
         }
     }
 
-    private fun updateViewVisibility() {
+    /**
+     * Updates this host's state based on the current media data's status, and invokes listeners if
+     * the visibility has changed
+     */
+    fun updateViewVisibility() {
         state.visible = if (showsOnlyActiveMedia) {
             mediaDataManager.hasActiveMediaOrRecommendation()
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
index 8e4ca5a..731e348 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
@@ -380,7 +380,7 @@
         type: TYPE
     ) = traceSection("MediaViewController#attach") {
         updateMediaViewControllerType(type)
-        logger.logMediaLocation("attach", currentStartLocation, currentEndLocation)
+        logger.logMediaLocation("attach $type", currentStartLocation, currentEndLocation)
         this.transitionLayout = transitionLayout
         layoutController.attach(transitionLayout)
         if (currentEndLocation == -1) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt b/packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt
index 88f6f3d..6bc94cd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt
@@ -60,6 +60,8 @@
             linePaint.strokeWidth = value
         }
 
+    // Enables a transition region where the amplitude
+    // of the wave is reduced linearly across it.
     var transitionEnabled = true
         set(value) {
             field = value
@@ -116,44 +118,40 @@
         }
 
         val progress = level / 10_000f
-        val totalProgressPx = bounds.width() * progress
-        val waveProgressPx = bounds.width() * (
+        val totalWidth = bounds.width().toFloat()
+        val totalProgressPx = totalWidth * progress
+        val waveProgressPx = totalWidth * (
             if (!transitionEnabled || progress > matchedWaveEndpoint) progress else
             lerp(minWaveEndpoint, matchedWaveEndpoint, lerpInv(0f, matchedWaveEndpoint, progress)))
 
         // Build Wiggly Path
-        val waveStart = -phaseOffset
-        val waveEnd = waveProgressPx
-        val transitionLength = if (transitionEnabled) transitionPeriods * waveLength else 0.01f
+        val waveStart = -phaseOffset - waveLength / 2f
+        val waveEnd = if (transitionEnabled) totalWidth else waveProgressPx
 
         // helper function, computes amplitude for wave segment
         val computeAmplitude: (Float, Float) -> Float = { x, sign ->
-            sign * heightFraction * lineAmplitude *
-                    lerpInvSat(waveEnd, waveEnd - transitionLength, x)
+            if (transitionEnabled) {
+                val length = transitionPeriods * waveLength
+                val coeff = lerpInvSat(
+                    waveProgressPx + length / 2f,
+                    waveProgressPx - length / 2f,
+                    x)
+                sign * heightFraction * lineAmplitude * coeff
+            } else {
+                sign * heightFraction * lineAmplitude
+            }
         }
 
-        var currentX = waveEnd
-        var waveSign = if (phaseOffset < waveLength / 2) 1f else -1f
+        // Reset path object to the start
         path.rewind()
+        path.moveTo(waveStart, 0f)
 
-        // Draw flat line from end to wave endpoint
-        path.moveTo(bounds.width().toFloat(), 0f)
-        path.lineTo(waveEnd, 0f)
-
-        // First wave has shortened wavelength
-        // approx quarter wave gets us to first wave peak
-        // shouldn't be big enough to notice it's not a sin wave
-        currentX -= phaseOffset % (waveLength / 2)
-        val controlRatio = 0.25f
+        // Build the wave, incrementing by half the wavelength each time
+        var currentX = waveStart
+        var waveSign = 1f
         var currentAmp = computeAmplitude(currentX, waveSign)
-        path.cubicTo(
-            waveEnd, currentAmp * controlRatio,
-            lerp(currentX, waveEnd, controlRatio), currentAmp,
-            currentX, currentAmp)
-
-        // Other waves have full wavelength
-        val dist = -1 * waveLength / 2f
-        while (currentX > waveStart) {
+        val dist = waveLength / 2f
+        while (currentX < waveEnd) {
             waveSign = -waveSign
             val nextX = currentX + dist
             val midX = currentX + dist / 2
@@ -166,34 +164,35 @@
             currentX = nextX
         }
 
-        // Draw path; clip to progress position
+        // translate to the start position of the progress bar for all draw commands
+        val clipTop = lineAmplitude + strokeWidth
         canvas.save()
         canvas.translate(bounds.left.toFloat(), bounds.centerY().toFloat())
-        canvas.clipRect(
-                0f,
-                -lineAmplitude - strokeWidth,
-                totalProgressPx,
-                lineAmplitude + strokeWidth)
+
+        // Draw path up to progress position
+        canvas.save()
+        canvas.clipRect(0f, -1f * clipTop, totalProgressPx, clipTop)
         canvas.drawPath(path, wavePaint)
         canvas.restore()
 
-        // Draw path; clip between progression position & far edge
-        canvas.save()
-        canvas.translate(bounds.left.toFloat(), bounds.centerY().toFloat())
-        canvas.clipRect(
-                totalProgressPx,
-                -lineAmplitude - strokeWidth,
-                bounds.width().toFloat(),
-                lineAmplitude + strokeWidth)
-        canvas.drawPath(path, linePaint)
-        canvas.restore()
+        if (transitionEnabled) {
+            // If there's a smooth transition, we draw the rest of the
+            // path in a different color (using different clip params)
+            canvas.save()
+            canvas.clipRect(totalProgressPx, -1f * clipTop, totalWidth, clipTop)
+            canvas.drawPath(path, linePaint)
+            canvas.restore()
+        } else {
+            // No transition, just draw a flat line to the end of the region.
+            // The discontinuity is hidden by the progress bar thumb shape.
+            canvas.drawLine(totalProgressPx, 0f, totalWidth, 0f, linePaint)
+        }
 
         // Draw round line cap at the beginning of the wave
-        val startAmp = cos(abs(waveEnd - phaseOffset) / waveLength * TWO_PI)
-        canvas.drawPoint(
-                bounds.left.toFloat(),
-                bounds.centerY() + startAmp * lineAmplitude * heightFraction,
-                wavePaint)
+        val startAmp = cos(abs(waveStart) / waveLength * TWO_PI)
+        canvas.drawPoint(0f, startAmp * lineAmplitude * heightFraction, wavePaint)
+
+        canvas.restore()
     }
 
     override fun getOpacity(): Int {
@@ -233,4 +232,4 @@
         linePaint.color = ColorUtils.setAlphaComponent(tintColor,
                 (DISABLED_ALPHA * (alpha / 255f)).toInt())
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputMetricLogger.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputMetricLogger.java
index 6fe06e0..7d3e82c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputMetricLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputMetricLogger.java
@@ -107,7 +107,8 @@
         SysUiStatsLog.write(
                 SysUiStatsLog.MEDIAOUTPUT_OP_INTERACTION_REPORT,
                 SysUiStatsLog.MEDIA_OUTPUT_OP_INTERACTION_REPORTED__INTERACTION_TYPE__ADJUST_VOLUME,
-                getInteractionDeviceType(source));
+                getInteractionDeviceType(source),
+                getLoggingPackageName());
     }
 
     /**
@@ -121,7 +122,8 @@
         SysUiStatsLog.write(
                 SysUiStatsLog.MEDIAOUTPUT_OP_INTERACTION_REPORT,
                 SysUiStatsLog.MEDIA_OUTPUT_OP_INTERACTION_REPORTED__INTERACTION_TYPE__STOP_CASTING,
-                SysUiStatsLog.MEDIA_OUTPUT_OP_INTERACTION_REPORTED__TARGET__UNKNOWN_TYPE);
+                SysUiStatsLog.MEDIA_OUTPUT_OP_INTERACTION_REPORTED__TARGET__UNKNOWN_TYPE,
+                getLoggingPackageName());
     }
 
     /**
@@ -135,7 +137,8 @@
         SysUiStatsLog.write(
                 SysUiStatsLog.MEDIAOUTPUT_OP_INTERACTION_REPORT,
                 SysUiStatsLog.MEDIA_OUTPUT_OP_INTERACTION_REPORTED__INTERACTION_TYPE__EXPANSION,
-                getInteractionDeviceType(source));
+                getInteractionDeviceType(source),
+                getLoggingPackageName());
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
index aa10f7e..b565f3c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
@@ -18,38 +18,57 @@
 
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel
+import com.android.systemui.temporarydisplay.TemporaryViewLogger
 
 /**
  * A logger for media tap-to-transfer events.
  *
- * @property deviceTypeTag the type of device triggering the logs -- "Sender" or "Receiver".
+ * @param deviceTypeTag the type of device triggering the logs -- "Sender" or "Receiver".
  */
 class MediaTttLogger(
-    private val deviceTypeTag: String,
-    private val buffer: LogBuffer
-){
+    deviceTypeTag: String,
+    buffer: LogBuffer
+) : TemporaryViewLogger(buffer, BASE_TAG + deviceTypeTag) {
     /** Logs a change in the chip state for the given [mediaRouteId]. */
-    fun logStateChange(stateName: String, mediaRouteId: String) {
+    fun logStateChange(stateName: String, mediaRouteId: String, packageName: String?) {
         buffer.log(
-            BASE_TAG + deviceTypeTag,
+            tag,
             LogLevel.DEBUG,
             {
                 str1 = stateName
                 str2 = mediaRouteId
+                str3 = packageName
             },
-            { "State changed to $str1 for ID=$str2" }
+            { "State changed to $str1 for ID=$str2 package=$str3" }
         )
     }
 
-    /** Logs that we removed the chip for the given [reason]. */
-    fun logChipRemoval(reason: String) {
+    /** Logs that we couldn't find information for [packageName]. */
+    fun logPackageNotFound(packageName: String) {
         buffer.log(
-            BASE_TAG + deviceTypeTag,
+            tag,
             LogLevel.DEBUG,
-            { str1 = reason },
-            { "Chip removed due to $str1" }
+            { str1 = packageName },
+            { "Package $str1 could not be found" }
         )
     }
+
+    /**
+     * Logs that a removal request has been bypassed (ignored).
+     *
+     * @param removalReason the reason that the chip removal was requested.
+     * @param bypassReason the reason that the request was bypassed.
+     */
+    fun logRemovalBypass(removalReason: String, bypassReason: String) {
+        buffer.log(
+            tag,
+            LogLevel.DEBUG,
+            {
+                str1 = removalReason
+                str2 = bypassReason
+            },
+            { "Chip removal requested due to $str1; however, removal was ignored because $str2" })
+    }
 }
 
 private const val BASE_TAG = "MediaTtt"
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
new file mode 100644
index 0000000..792ae7c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.taptotransfer.common
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.graphics.drawable.Drawable
+import com.android.internal.widget.CachingIconView
+import com.android.settingslib.Utils
+import com.android.systemui.R
+
+/** Utility methods for media tap-to-transfer. */
+class MediaTttUtils {
+    companion object {
+        // Used in CTS tests UpdateMediaTapToTransferSenderDisplayTest and
+        // UpdateMediaTapToTransferReceiverDisplayTest
+        const val WINDOW_TITLE = "Media Transfer Chip View"
+        const val WAKE_REASON = "MEDIA_TRANSFER_ACTIVATED"
+
+        /**
+         * Returns the information needed to display the icon.
+         *
+         * The information will either contain app name and icon of the app playing media, or a
+         * default name and icon if we can't find the app name/icon.
+         *
+         * @param appPackageName the package name of the app playing the media.
+         * @param logger the logger to use for any errors.
+         */
+        fun getIconInfoFromPackageName(
+            context: Context,
+            appPackageName: String?,
+            logger: MediaTttLogger
+        ): IconInfo {
+            if (appPackageName != null) {
+                try {
+                    val contentDescription =
+                        context.packageManager
+                            .getApplicationInfo(
+                                appPackageName,
+                                PackageManager.ApplicationInfoFlags.of(0)
+                            )
+                            .loadLabel(context.packageManager)
+                            .toString()
+                    return IconInfo(
+                        contentDescription,
+                        drawable = context.packageManager.getApplicationIcon(appPackageName),
+                        isAppIcon = true
+                    )
+                } catch (e: PackageManager.NameNotFoundException) {
+                    logger.logPackageNotFound(appPackageName)
+                }
+            }
+            return IconInfo(
+                contentDescription =
+                    context.getString(R.string.media_output_dialog_unknown_launch_app_name),
+                drawable =
+                    context.resources.getDrawable(R.drawable.ic_cast).apply {
+                        this.setTint(
+                            Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
+                        )
+                    },
+                isAppIcon = false
+            )
+        }
+
+        /**
+         * Sets an icon to be displayed by the given view.
+         *
+         * @param iconSize the size in pixels that the icon should be. If null, the size of
+         * [appIconView] will not be adjusted.
+         */
+        fun setIcon(
+            appIconView: CachingIconView,
+            icon: Drawable,
+            iconContentDescription: CharSequence,
+            iconSize: Int? = null,
+        ) {
+            iconSize?.let { size ->
+                val lp = appIconView.layoutParams
+                lp.width = size
+                lp.height = size
+                appIconView.layoutParams = lp
+            }
+
+            appIconView.contentDescription = iconContentDescription
+            appIconView.setImageDrawable(icon)
+        }
+    }
+}
+
+data class IconInfo(
+    val contentDescription: String,
+    val drawable: Drawable,
+    /**
+     * True if [drawable] is the app's icon, and false if [drawable] is some generic default icon.
+     */
+    val isAppIcon: Boolean
+)
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 5d6d683..dfd9e22 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,6 +35,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
+import com.android.systemui.media.taptotransfer.common.MediaTttUtils
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.temporarydisplay.DEFAULT_TIMEOUT_MILLIS
@@ -61,7 +62,7 @@
         powerManager: PowerManager,
         @Main private val mainHandler: Handler,
         private val uiEventLogger: MediaTttReceiverUiEventLogger,
-) : TemporaryViewDisplayController<ChipReceiverInfo>(
+) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttLogger>(
         context,
         logger,
         windowManager,
@@ -70,6 +71,8 @@
         configurationController,
         powerManager,
         R.layout.media_ttt_chip_receiver,
+        MediaTttUtils.WINDOW_TITLE,
+        MediaTttUtils.WAKE_REASON,
 ) {
     @SuppressLint("WrongConstant") // We're allowed to use LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
     override val windowLayoutParams = commonWindowLayoutParams.apply {
@@ -107,7 +110,7 @@
     ) {
         val chipState: ChipStateReceiver? = ChipStateReceiver.getReceiverStateFromId(displayState)
         val stateName = chipState?.name ?: "Invalid"
-        logger.logStateChange(stateName, routeInfo.id)
+        logger.logStateChange(stateName, routeInfo.id, routeInfo.clientPackageName)
 
         if (chipState == null) {
             Log.e(RECEIVER_TAG, "Unhandled MediaTransferReceiverState $displayState")
@@ -137,13 +140,26 @@
 
     override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) {
         super.updateView(newInfo, currentView)
-        val iconName = setIcon(
-                currentView,
-                newInfo.routeInfo.clientPackageName,
-                newInfo.appIconDrawableOverride,
-                newInfo.appNameOverride
+
+        val iconInfo = MediaTttUtils.getIconInfoFromPackageName(
+            context, newInfo.routeInfo.clientPackageName, logger
         )
-        currentView.contentDescription = iconName
+        val iconDrawable = newInfo.appIconDrawableOverride ?: iconInfo.drawable
+        val iconContentDescription = newInfo.appNameOverride ?: iconInfo.contentDescription
+        val iconSize = context.resources.getDimensionPixelSize(
+            if (iconInfo.isAppIcon) {
+                R.dimen.media_ttt_icon_size_receiver
+            } else {
+                R.dimen.media_ttt_generic_icon_size_receiver
+            }
+        )
+
+        MediaTttUtils.setIcon(
+            currentView.requireViewById(R.id.app_icon),
+            iconDrawable,
+            iconContentDescription,
+            iconSize,
+        )
     }
 
     override fun animateViewIn(view: ViewGroup) {
@@ -161,15 +177,6 @@
         startRipple(view.requireViewById(R.id.ripple))
     }
 
-    override fun getIconSize(isAppIcon: Boolean): Int? =
-        context.resources.getDimensionPixelSize(
-            if (isAppIcon) {
-                R.dimen.media_ttt_icon_size_receiver
-            } else {
-                R.dimen.media_ttt_generic_icon_size_receiver
-            }
-        )
-
     /** Returns the amount that the chip will be translated by in its intro animation. */
     private fun getTranslationAmount(): Int {
         return context.resources.getDimensionPixelSize(R.dimen.media_ttt_receiver_vert_translation)
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 bde588c..4379d25 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
@@ -34,8 +34,7 @@
  * @property stateInt the integer from [StatusBarManager] corresponding with this state.
  * @property stringResId the res ID of the string that should be displayed in the chip. Null if the
  *   state should not have the chip be displayed.
- * @property isMidTransfer true if the state represents that a transfer is currently ongoing.
- * @property isTransferFailure true if the state represents that the transfer has failed.
+ * @property transferStatus the transfer status that the chip state represents.
  * @property timeout the amount of time this chip should display on the screen before it times out
  *   and disappears.
  */
@@ -43,8 +42,7 @@
     @StatusBarManager.MediaTransferSenderState val stateInt: Int,
     val uiEvent: UiEventLogger.UiEventEnum,
     @StringRes val stringResId: Int?,
-    val isMidTransfer: Boolean = false,
-    val isTransferFailure: Boolean = false,
+    val transferStatus: TransferStatus,
     val timeout: Long = DEFAULT_TIMEOUT_MILLIS
 ) {
     /**
@@ -56,6 +54,7 @@
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST,
         R.string.media_move_closer_to_start_cast,
+        transferStatus = TransferStatus.NOT_STARTED,
     ),
 
     /**
@@ -68,6 +67,7 @@
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST,
         R.string.media_move_closer_to_end_cast,
+        transferStatus = TransferStatus.NOT_STARTED,
     ),
 
     /**
@@ -78,7 +78,7 @@
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED,
         R.string.media_transfer_playing_different_device,
-        isMidTransfer = true,
+        transferStatus = TransferStatus.IN_PROGRESS,
         timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
     ),
 
@@ -90,7 +90,7 @@
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
         R.string.media_transfer_playing_this_device,
-        isMidTransfer = true,
+        transferStatus = TransferStatus.IN_PROGRESS,
         timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
     ),
 
@@ -100,7 +100,8 @@
     TRANSFER_TO_RECEIVER_SUCCEEDED(
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED,
-        R.string.media_transfer_playing_different_device
+        R.string.media_transfer_playing_different_device,
+        transferStatus = TransferStatus.SUCCEEDED,
     ) {
         override fun undoClickListener(
             controllerSender: MediaTttChipControllerSender,
@@ -135,7 +136,8 @@
     TRANSFER_TO_THIS_DEVICE_SUCCEEDED(
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
-        R.string.media_transfer_playing_this_device
+        R.string.media_transfer_playing_this_device,
+        transferStatus = TransferStatus.SUCCEEDED,
     ) {
         override fun undoClickListener(
             controllerSender: MediaTttChipControllerSender,
@@ -169,7 +171,7 @@
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED,
         R.string.media_transfer_failed,
-        isTransferFailure = true
+        transferStatus = TransferStatus.FAILED,
     ),
 
     /** A state representing that a transfer back to this device has failed. */
@@ -177,14 +179,15 @@
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED,
         R.string.media_transfer_failed,
-        isTransferFailure = true
+        transferStatus = TransferStatus.FAILED,
     ),
 
     /** A state representing that this device is far away from any receiver device. */
     FAR_FROM_RECEIVER(
         StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
         MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER,
-        stringResId = null
+        stringResId = null,
+        transferStatus = TransferStatus.TOO_FAR,
     );
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
index 0c1ebd7..e539f3f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
+import com.android.systemui.media.taptotransfer.common.MediaTttUtils
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.temporarydisplay.TemporaryDisplayRemovalReason
@@ -57,7 +58,7 @@
         configurationController: ConfigurationController,
         powerManager: PowerManager,
         private val uiEventLogger: MediaTttSenderUiEventLogger
-) : TemporaryViewDisplayController<ChipSenderInfo>(
+) : TemporaryViewDisplayController<ChipSenderInfo, MediaTttLogger>(
         context,
         logger,
         windowManager,
@@ -66,6 +67,8 @@
         configurationController,
         powerManager,
         R.layout.media_ttt_chip,
+        MediaTttUtils.WINDOW_TITLE,
+        MediaTttUtils.WAKE_REASON,
 ) {
     override val windowLayoutParams = commonWindowLayoutParams.apply {
         gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
@@ -94,7 +97,7 @@
     ) {
         val chipState: ChipStateSender? = ChipStateSender.getSenderStateFromId(displayState)
         val stateName = chipState?.name ?: "Invalid"
-        logger.logStateChange(stateName, routeInfo.id)
+        logger.logStateChange(stateName, routeInfo.id, routeInfo.clientPackageName)
 
         if (chipState == null) {
             Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState")
@@ -103,7 +106,7 @@
         uiEventLogger.logSenderStateChange(chipState)
 
         if (chipState == ChipStateSender.FAR_FROM_RECEIVER) {
-            removeView(removalReason = ChipStateSender.FAR_FROM_RECEIVER::class.simpleName!!)
+            removeView(removalReason = ChipStateSender.FAR_FROM_RECEIVER.name)
         } else {
             displayView(ChipSenderInfo(chipState, routeInfo, undoCallback))
         }
@@ -118,7 +121,14 @@
         val chipState = newInfo.state
 
         // App icon
-        val iconName = setIcon(currentView, newInfo.routeInfo.clientPackageName)
+        val iconInfo = MediaTttUtils.getIconInfoFromPackageName(
+            context, newInfo.routeInfo.clientPackageName, logger
+        )
+        MediaTttUtils.setIcon(
+            currentView.requireViewById(R.id.app_icon),
+            iconInfo.drawable,
+            iconInfo.contentDescription
+        )
 
         // Text
         val otherDeviceName = newInfo.routeInfo.name.toString()
@@ -127,7 +137,7 @@
 
         // Loading
         currentView.requireViewById<View>(R.id.loading).visibility =
-            chipState.isMidTransfer.visibleIfTrue()
+            (chipState.transferStatus == TransferStatus.IN_PROGRESS).visibleIfTrue()
 
         // Undo
         val undoView = currentView.requireViewById<View>(R.id.undo)
@@ -139,12 +149,12 @@
 
         // Failure
         currentView.requireViewById<View>(R.id.failure_icon).visibility =
-            chipState.isTransferFailure.visibleIfTrue()
+            (chipState.transferStatus == TransferStatus.FAILED).visibleIfTrue()
 
         // For accessibility
         currentView.requireViewById<ViewGroup>(
                 R.id.media_ttt_sender_chip_inner
-        ).contentDescription = "$iconName $chipText"
+        ).contentDescription = "${iconInfo.contentDescription} $chipText"
     }
 
     override fun animateViewIn(view: ViewGroup) {
@@ -162,10 +172,17 @@
     }
 
     override fun removeView(removalReason: String) {
-        // Don't remove the chip if we're mid-transfer since the user should still be able to
-        // see the status of the transfer. (But do remove it if it's finally timed out.)
-        if (info?.state?.isMidTransfer == true &&
-                removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT) {
+        // Don't remove the chip if we're in progress or succeeded, since the user should still be
+        // able to see the status of the transfer. (But do remove it if it's finally timed out.)
+        val transferStatus = info?.state?.transferStatus
+        if (
+            (transferStatus == TransferStatus.IN_PROGRESS ||
+                transferStatus == TransferStatus.SUCCEEDED) &&
+            removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT
+        ) {
+            logger.logRemovalBypass(
+                removalReason, bypassReason = "transferStatus=${transferStatus.name}"
+            )
             return
         }
         super.removeView(removalReason)
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/TransferStatus.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/TransferStatus.kt
new file mode 100644
index 0000000..f15720d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/TransferStatus.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.taptotransfer.sender
+
+/** Represents the different possible transfer states that we could be in. */
+enum class TransferStatus {
+    /** The transfer hasn't started yet. */
+    NOT_STARTED,
+    /** The transfer is currently ongoing but hasn't completed yet. */
+    IN_PROGRESS,
+    /** The transfer has completed successfully. */
+    SUCCEEDED,
+    /** The transfer has completed with a failure. */
+    FAILED,
+    /** The device is too far away to do a transfer. */
+    TOO_FAR,
+}
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 7c4c64c..d605c1a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -955,9 +955,9 @@
             updateDisabledForQuickstep(newConfig);
         }
 
-        if (DEBUG_MISSING_GESTURE) {
-            Log.d(DEBUG_MISSING_GESTURE_TAG, "Config changed: config=" + newConfig);
-        }
+        // TODO(b/243765256): Disable this logging once b/243765256 is fixed.
+        Log.d(DEBUG_MISSING_GESTURE_TAG, "Config changed: newConfig=" + newConfig
+                + " lastReportedConfig=" + mLastReportedConfig);
         mLastReportedConfig.updateFrom(newConfig);
         updateDisplaySize();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 57bea67..6e4c858 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -24,6 +24,7 @@
 import android.content.ComponentName;
 import android.content.res.Configuration;
 import android.metrics.LogMaker;
+import android.util.Log;
 import android.view.View;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -61,6 +62,7 @@
  */
 public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewController<T>
         implements Dumpable{
+    private static final String TAG = "QSPanelControllerBase";
     protected final QSTileHost mHost;
     private final QSCustomizerController mQsCustomizerController;
     private final boolean mUsingMediaPlayer;
@@ -90,6 +92,13 @@
                 public void onConfigurationChange(Configuration newConfig) {
                     mShouldUseSplitNotificationShade =
                             LargeScreenUtils.shouldUseSplitNotificationShade(getResources());
+                    // Logging to aid the investigation of b/216244185.
+                    Log.d(TAG,
+                            "onConfigurationChange: "
+                                    + "mShouldUseSplitNotificationShade="
+                                    + mShouldUseSplitNotificationShade + ", "
+                                    + "newConfig.windowConfiguration="
+                                    + newConfig.windowConfiguration);
                     mQSLogger.logOnConfigurationChanged(mLastOrientation, newConfig.orientation,
                             mView.getDumpableTag());
                     onConfigurationChanged();
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 5842665..e9a6c25 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -50,6 +50,7 @@
     protected int mIconSizePx;
     private boolean mAnimationEnabled = true;
     private int mState = -1;
+    private boolean mDisabledByPolicy = false;
     private int mTint;
     @Nullable
     private QSTile.Icon mLastIcon;
@@ -159,14 +160,10 @@
     }
 
     protected void setIcon(ImageView iv, QSTile.State state, boolean allowAnimations) {
-        if (state.disabledByPolicy) {
-            iv.setColorFilter(getContext().getColor(R.color.qs_tile_disabled_color));
-        } else {
-            iv.clearColorFilter();
-        }
-        if (state.state != mState) {
+        if (state.state != mState || state.disabledByPolicy != mDisabledByPolicy) {
             int color = getColor(state);
             mState = state.state;
+            mDisabledByPolicy = state.disabledByPolicy;
             if (mTint != 0 && allowAnimations && shouldAnimate(iv)) {
                 animateGrayScale(mTint, color, iv, () -> updateIcon(iv, state, allowAnimations));
             } else {
@@ -241,8 +238,8 @@
      */
     private static int getIconColorForState(Context context, QSTile.State state) {
         if (state.disabledByPolicy || state.state == Tile.STATE_UNAVAILABLE) {
-            return Utils.applyAlpha(QSTileViewImpl.UNAVAILABLE_ALPHA,
-                    Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary));
+            return Utils.getColorAttrDefaultColor(
+                    context, com.android.internal.R.attr.textColorTertiary);
         } else if (state.state == Tile.STATE_INACTIVE) {
             return Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary);
         } else if (state.state == Tile.STATE_ACTIVE) {
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 163ee2a..972b243 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -100,14 +100,15 @@
             Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.textColorOnAccent)
     private val colorLabelInactive =
             Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
-    private val colorLabelUnavailable = Utils.applyAlpha(UNAVAILABLE_ALPHA, colorLabelInactive)
+    private val colorLabelUnavailable =
+        Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.textColorTertiary)
 
     private val colorSecondaryLabelActive =
             Utils.getColorAttrDefaultColor(context, android.R.attr.textColorSecondaryInverse)
     private val colorSecondaryLabelInactive =
             Utils.getColorAttrDefaultColor(context, android.R.attr.textColorSecondary)
     private val colorSecondaryLabelUnavailable =
-            Utils.applyAlpha(UNAVAILABLE_ALPHA, colorSecondaryLabelInactive)
+        Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.textColorTertiary)
 
     private lateinit var label: TextView
     protected lateinit var secondaryLabel: TextView
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 c2a82a7..a31500c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -49,7 +49,6 @@
 /** Quick settings tile: Invert colors **/
 public class ColorInversionTile extends QSTileImpl<BooleanState> {
 
-    private final Icon mIcon = ResourceIcon.get(drawable.ic_invert_colors);
     private final SettingObserver mSetting;
 
     @Inject
@@ -123,7 +122,9 @@
         state.value = enabled;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
-        state.icon = mIcon;
+        state.icon = ResourceIcon.get(state.value
+                ? drawable.qs_invert_colors_icon_on
+                : drawable.qs_invert_colors_icon_off);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
     }
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 9fdf594..2fc99f3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -128,13 +128,13 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.value = arg instanceof Boolean ? (Boolean) arg
+        state.value = arg instanceof Boolean ? ((Boolean) arg).booleanValue()
                 : mDataSaverController.isDataSaverEnabled();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.label = mContext.getString(R.string.data_saver);
         state.contentDescription = state.label;
-        state.icon = ResourceIcon.get(state.value ? R.drawable.ic_data_saver
-                : R.drawable.ic_data_saver_off);
+        state.icon = ResourceIcon.get(state.value ? R.drawable.qs_data_saver_icon_on
+                : R.drawable.qs_data_saver_icon_off);
         state.expandedAccessibilityClassName = Switch.class.getName();
     }
 
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 73b0896..a747926 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -43,11 +43,12 @@
 
 import javax.inject.Inject;
 
-/** Quick settings tile: Control flashlight **/
+/**
+ * Quick settings tile: Control flashlight
+ **/
 public class FlashlightTile extends QSTileImpl<BooleanState> implements
         FlashlightController.FlashlightListener {
 
-    private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_flashlight);
     private final FlashlightController mFlashlightController;
 
     @Inject
@@ -116,19 +117,15 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        if (state.slash == null) {
-            state.slash = new SlashState();
-        }
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
         state.secondaryLabel = "";
         state.stateDescription = "";
         if (!mFlashlightController.isAvailable()) {
-            state.icon = mIcon;
-            state.slash.isSlashed = true;
             state.secondaryLabel = mContext.getString(
                     R.string.quick_settings_flashlight_camera_in_use);
             state.stateDescription = state.secondaryLabel;
             state.state = Tile.STATE_UNAVAILABLE;
+            state.icon = ResourceIcon.get(R.drawable.qs_flashlight_icon_off);
             return;
         }
         if (arg instanceof Boolean) {
@@ -140,11 +137,11 @@
         } else {
             state.value = mFlashlightController.isEnabled();
         }
-        state.icon = mIcon;
-        state.slash.isSlashed = !state.value;
         state.contentDescription = mContext.getString(R.string.quick_settings_flashlight_label);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        state.icon = ResourceIcon.get(state.value
+                ? R.drawable.qs_flashlight_icon_on : R.drawable.qs_flashlight_icon_off);
     }
 
     @Override
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 81813db..0e9f659 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -144,9 +144,10 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.value = mManager.isNightDisplayActivated();
         state.label = mContext.getString(R.string.quick_settings_night_display_label);
-        state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_night_display_on);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        state.icon = ResourceIcon.get(state.value ? R.drawable.qs_nightlight_icon_on
+                : R.drawable.qs_nightlight_icon_off);
         state.secondaryLabel = getSecondaryLabel(state.value);
         state.contentDescription = TextUtils.isEmpty(state.secondaryLabel)
                 ? state.label
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 6921ad5..1dac339 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
@@ -49,7 +49,6 @@
 public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState>
         implements ReduceBrightColorsController.Listener{
 
-    private final Icon mIcon = ResourceIcon.get(drawable.ic_reduce_bright_colors);
     private final boolean mIsAvailable;
     private final ReduceBrightColorsController mReduceBrightColorsController;
     private boolean mIsListening;
@@ -111,7 +110,9 @@
         state.label = mContext.getString(R.string.reduce_bright_colors_feature_name);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
-        state.icon = mIcon;
+        state.icon = ResourceIcon.get(state.value
+                ? drawable.qs_extra_dim_icon_on
+                : drawable.qs_extra_dim_icon_off);
     }
 
     @Override
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 75fb393..f63f044 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -120,7 +120,9 @@
         state.value = isRecording || isStarting;
         state.state = (isRecording || isStarting) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.label = mContext.getString(R.string.quick_settings_screen_record_label);
-        state.icon = ResourceIcon.get(R.drawable.ic_screenrecord);
+        state.icon = ResourceIcon.get(state.value
+                ? R.drawable.qs_screen_record_icon_on
+                : R.drawable.qs_screen_record_icon_off);
         // Show expand icon when clicking will open a dialog
         state.forceExpandIcon = state.state == Tile.STATE_INACTIVE;
 
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 f60e066..92f6690a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
@@ -81,8 +81,7 @@
         super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                 statusBarStateController, activityStarter, qsLogger);
         mBatteryController = batteryController;
-        mUiModeManager = (UiModeManager) host.getUserContext().getSystemService(
-                Context.UI_MODE_SERVICE);
+        mUiModeManager = host.getUserContext().getSystemService(UiModeManager.class);
         mLocationController = locationController;
         configurationController.observe(getLifecycle(), this);
         batteryController.observe(getLifecycle(), this);
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 2861ed7..24c4723 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
@@ -198,6 +198,8 @@
         mUiEventLogger.log(InternetDialogEvent.INTERNET_DIALOG_SHOW);
         mDialogView = LayoutInflater.from(mContext).inflate(R.layout.internet_connectivity_dialog,
                 null);
+        mDialogView.setAccessibilityPaneTitle(
+                mContext.getText(R.string.accessibility_desc_quick_settings));
         final Window window = getWindow();
         window.setContentView(mDialogView);
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
index 246265b..ac5640b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
@@ -24,8 +24,9 @@
 import android.util.Log
 import android.view.DisplayAddress
 import android.view.SurfaceControl
-import android.view.SurfaceControl.DisplayCaptureArgs
-import android.view.SurfaceControl.ScreenshotHardwareBuffer
+import android.window.ScreenCapture
+import android.window.ScreenCapture.DisplayCaptureArgs
+import android.window.ScreenCapture.ScreenshotHardwareBuffer
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
@@ -84,6 +85,6 @@
                 .setSize(width, height)
                 .setSourceCrop(crop)
                 .build()
-        return SurfaceControl.captureDisplay(captureArgs)
+        return ScreenCapture.captureDisplay(captureArgs)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 3429b9d..1011a6d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -33,6 +33,7 @@
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
+import static com.android.systemui.statusbar.VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES;
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD;
 import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
@@ -62,6 +63,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.Trace;
 import android.os.UserManager;
 import android.os.VibrationEffect;
@@ -236,6 +238,9 @@
     private static final boolean SPEW_LOGCAT = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
     private static final boolean DEBUG_DRAWABLE = false;
 
+    private static final VibrationEffect ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT =
+            VibrationEffect.get(VibrationEffect.EFFECT_STRENGTH_MEDIUM, false);
+
     /**
      * The parallax amount of the quick settings translation when dragging down the panel
      */
@@ -682,14 +687,22 @@
 
     private final FalsingTapListener mFalsingTapListener = new FalsingTapListener() {
         @Override
-        public void onDoubleTapRequired() {
+        public void onAdditionalTapRequired() {
             if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) {
                 mTapAgainViewController.show();
             } else {
                 mKeyguardIndicationController.showTransientIndication(
                         R.string.notification_tap_again);
             }
-            mVibratorHelper.vibrate(VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+
+            if (!mStatusBarStateController.isDozing()) {
+                mVibratorHelper.vibrate(
+                        Process.myUid(),
+                        mView.getContext().getPackageName(),
+                        ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT,
+                        "falsing-additional-tap-required",
+                        TOUCH_VIBRATION_ATTRIBUTES);
+            }
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index abafecc..8d74a09 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -73,7 +73,7 @@
     private final AmbientState mAmbientState;
     private final PulsingGestureListener mPulsingGestureListener;
 
-    private GestureDetector mGestureDetector;
+    private GestureDetector mPulsingWakeupGestureHandler;
     private View mBrightnessMirror;
     private boolean mTouchActive;
     private boolean mTouchCancelled;
@@ -149,7 +149,8 @@
     /** Inflates the {@link R.layout#status_bar_expanded} layout and sets it up. */
     public void setupExpandedStatusBar() {
         mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);
-        mGestureDetector = new GestureDetector(mView.getContext(), mPulsingGestureListener);
+        mPulsingWakeupGestureHandler = new GestureDetector(mView.getContext(),
+                mPulsingGestureListener);
 
         mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
             @Override
@@ -196,7 +197,7 @@
                 }
 
                 mFalsingCollector.onTouchEvent(ev);
-                mGestureDetector.onTouchEvent(ev);
+                mPulsingWakeupGestureHandler.onTouchEvent(ev);
                 mStatusBarKeyguardViewManager.onTouch(ev);
                 if (mBrightnessMirror != null
                         && mBrightnessMirror.getVisibility() == View.VISIBLE) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
index 9b3fe92..084b7dc 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.dock.DockManager
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
@@ -36,12 +37,12 @@
 
 /**
  * If tap and/or double tap to wake is enabled, this gestureListener will wake the display on
- * tap/double tap when the device is pulsing (AoD 2). Taps are gated by the proximity sensor and
- * falsing manager.
+ * tap/double tap when the device is pulsing (AoD2) or transitioning to AoD. Taps are gated by the
+ * proximity sensor and falsing manager.
  *
- * Touches go through the [NotificationShadeWindowViewController] when the device is pulsing.
- * Otherwise, if the device is dozing and NOT pulsing, wake-ups are handled by
- * [com.android.systemui.doze.DozeSensors].
+ * Touches go through the [NotificationShadeWindowViewController] when the device is dozing but the
+ * screen is still ON and not in the true AoD display state. When the device is in the true AoD
+ * display state, wake-ups are handled by [com.android.systemui.doze.DozeSensors].
  */
 @CentralSurfacesComponent.CentralSurfacesScope
 class PulsingGestureListener @Inject constructor(
@@ -75,12 +76,12 @@
         dumpManager.registerDumpable(this)
     }
 
-    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
-        if (statusBarStateController.isPulsing &&
+    override fun onSingleTapUp(e: MotionEvent): Boolean {
+        if (statusBarStateController.isDozing &&
                 singleTapEnabled &&
                 !dockManager.isDocked &&
                 !falsingManager.isProximityNear &&
-                !falsingManager.isFalseTap(FalsingManager.MODERATE_PENALTY)
+                !falsingManager.isFalseTap(LOW_PENALTY)
         ) {
             centralSurfaces.wakeUpIfDozing(
                     SystemClock.uptimeMillis(),
@@ -91,8 +92,15 @@
         return false
     }
 
-    override fun onDoubleTap(e: MotionEvent): Boolean {
-        if (statusBarStateController.isPulsing &&
+    /**
+     * Receives [MotionEvent.ACTION_DOWN], [MotionEvent.ACTION_MOVE], and [MotionEvent.ACTION_UP]
+     * motion events for a double tap.
+     */
+    override fun onDoubleTapEvent(e: MotionEvent): Boolean {
+        // React to the [MotionEvent.ACTION_UP] event after double tap is detected. Falsing
+        // checks MUST be on the ACTION_UP event.
+        if (e.actionMasked == MotionEvent.ACTION_UP &&
+                statusBarStateController.isDozing &&
                 (doubleTapEnabled || singleTapEnabled) &&
                 !falsingManager.isProximityNear &&
                 !falsingManager.isFalseDoubleTap
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 408c61f..e06c977 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -19,9 +19,6 @@
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
 import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_MANAGEMENT_DISCLOSURE;
 import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_NAMED_MANAGEMENT_DISCLOSURE;
-import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_FIRST_FRAME_RECEIVED;
-import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_GOOD;
-import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_START;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
 import static android.hardware.biometrics.BiometricSourceType.FACE;
 import static android.view.View.GONE;
@@ -53,6 +50,7 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
+import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
@@ -82,7 +80,7 @@
 import com.android.settingslib.Utils;
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.systemui.R;
-import com.android.systemui.biometrics.BiometricMessageDeferral;
+import com.android.systemui.biometrics.FaceHelpMessageDeferral;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -184,6 +182,7 @@
     private long mChargingTimeRemaining;
     private String mBiometricErrorMessageToShowOnScreenOn;
     private final Set<Integer> mCoExFaceAcquisitionMsgIdsToShow;
+    private final FaceHelpMessageDeferral mFaceAcquiredMessageDeferral;
     private boolean mInited;
 
     private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
@@ -233,7 +232,8 @@
             LockPatternUtils lockPatternUtils,
             ScreenLifecycle screenLifecycle,
             KeyguardBypassController keyguardBypassController,
-            AccessibilityManager accessibilityManager) {
+            AccessibilityManager accessibilityManager,
+            FaceHelpMessageDeferral faceHelpMessageDeferral) {
         mContext = context;
         mBroadcastDispatcher = broadcastDispatcher;
         mDevicePolicyManager = devicePolicyManager;
@@ -254,6 +254,7 @@
         mScreenLifecycle = screenLifecycle;
         mScreenLifecycle.addObserver(mScreenObserver);
 
+        mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
         mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
         int[] msgIds = context.getResources().getIntArray(
                 com.android.systemui.R.array.config_face_help_msgs_when_fingerprint_enrolled);
@@ -1041,8 +1042,22 @@
         }
 
         @Override
+        public void onBiometricAcquired(BiometricSourceType biometricSourceType, int acquireInfo) {
+            if (biometricSourceType == FACE) {
+                mFaceAcquiredMessageDeferral.processFrame(acquireInfo);
+            }
+        }
+
+        @Override
         public void onBiometricHelp(int msgId, String helpString,
                 BiometricSourceType biometricSourceType) {
+            if (biometricSourceType == FACE) {
+                mFaceAcquiredMessageDeferral.updateMessage(msgId, helpString);
+                if (mFaceAcquiredMessageDeferral.shouldDefer(msgId)) {
+                    return;
+                }
+            }
+
             // TODO(b/141025588): refactor to reduce repetition of code/comments
             // Only checking if unlocking with Biometric is allowed (no matter strong or non-strong
             // as long as primary auth, i.e. PIN/pattern/password, is not required), so it's ok to
@@ -1053,17 +1068,6 @@
                 return;
             }
 
-            if (biometricSourceType == FACE) {
-                if (msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED) {
-                    mFaceAcquiredMessageDeferral.reset();
-                } else {
-                    mFaceAcquiredMessageDeferral.processMessage(msgId, helpString);
-                    if (mFaceAcquiredMessageDeferral.shouldDefer(msgId)) {
-                        return;
-                    }
-                }
-            }
-
             final boolean faceAuthSoftError = biometricSourceType == FACE
                     && msgId != BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
             final boolean faceAuthFailed = biometricSourceType == FACE
@@ -1109,11 +1113,23 @@
         }
 
         @Override
+        public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
+            if (biometricSourceType == FACE) {
+                mFaceAcquiredMessageDeferral.reset();
+            }
+        }
+
+        @Override
         public void onBiometricError(int msgId, String errString,
                 BiometricSourceType biometricSourceType) {
             CharSequence deferredFaceMessage = null;
             if (biometricSourceType == FACE) {
-                deferredFaceMessage = mFaceAcquiredMessageDeferral.getDeferredMessage();
+                if (msgId == BiometricFaceConstants.FACE_ERROR_TIMEOUT) {
+                    deferredFaceMessage = mFaceAcquiredMessageDeferral.getDeferredMessage();
+                    if (DEBUG) {
+                        Log.d(TAG, "showDeferredFaceMessage msgId=" + deferredFaceMessage);
+                    }
+                }
                 mFaceAcquiredMessageDeferral.reset();
             }
 
@@ -1308,14 +1324,4 @@
             }
         }
     };
-
-    private final BiometricMessageDeferral mFaceAcquiredMessageDeferral =
-            new BiometricMessageDeferral(
-                    Set.of(
-                            FACE_ACQUIRED_GOOD,
-                            FACE_ACQUIRED_START,
-                            FACE_ACQUIRED_FIRST_FRAME_RECEIVED
-                    ),
-                    Set.of(FACE_ACQUIRED_TOO_DARK)
-            );
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
index 867be1a..c070fcc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java
@@ -40,7 +40,7 @@
 public class VibratorHelper {
 
     private final Vibrator mVibrator;
-    private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
+    public static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
 
     private static final VibrationEffect BIOMETRIC_SUCCESS_VIBRATION_EFFECT =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index 31b21c9..553826d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -136,7 +136,7 @@
         headsUpManager.removeNotification(notificationKey, true /* releaseImmediately */, animate)
     }
 
-    override fun onLaunchAnimationCancelled() {
+    override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) {
         // TODO(b/184121838): Should we call InteractionJankMonitor.cancel if the animation started
         // here?
         notificationShadeWindowViewController.setExpandAnimationRunning(false)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationRoundnessLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationRoundnessLogger.kt
new file mode 100644
index 0000000..fe03b2a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationRoundnessLogger.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.logging
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel.INFO
+import com.android.systemui.log.dagger.NotificationRenderLog
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.notification.stack.NotificationSection
+import javax.inject.Inject
+
+/** Handles logging for the {NotificationRoundnessManager}. */
+class NotificationRoundnessLogger
+@Inject
+constructor(@NotificationRenderLog val buffer: LogBuffer) {
+
+    /** Called when the {NotificationRoundnessManager} updates the corners if the Notifications. */
+    fun onCornersUpdated(
+        view: ExpandableView?,
+        isFirstInSection: Boolean,
+        isLastInSection: Boolean,
+        topChanged: Boolean,
+        bottomChanged: Boolean
+    ) {
+        buffer.log(
+            TAG_ROUNDNESS,
+            INFO,
+            {
+                str1 = (view as? ExpandableNotificationRow)?.entry?.key
+                bool1 = isFirstInSection
+                bool2 = isLastInSection
+                bool3 = topChanged
+                bool4 = bottomChanged
+            },
+            {
+                "onCornersUpdated: " +
+                    "entry=$str1 isFirstInSection=$bool1 isLastInSection=$bool2 " +
+                    "topChanged=$bool3 bottomChanged=$bool4"
+            }
+        )
+    }
+
+    /** Called when we update the {NotificationRoundnessManager} with new sections. */
+    fun onSectionCornersUpdated(sections: Array<NotificationSection?>, anyChanged: Boolean) {
+        buffer.log(
+            TAG_ROUNDNESS,
+            INFO,
+            {
+                int1 = sections.size
+                bool1 = anyChanged
+            },
+            { "onSectionCornersUpdated: sections size=$int1 anyChanged=$bool1" }
+        )
+    }
+}
+
+private const val TAG_ROUNDNESS = "NotifRoundnessLogger"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index b589d9a..2015c87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -19,12 +19,19 @@
 import android.content.res.Resources;
 import android.util.MathUtils;
 
+import androidx.annotation.NonNull;
+
+import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.logging.NotificationRoundnessLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 
+import java.io.PrintWriter;
 import java.util.HashSet;
 
 import javax.inject.Inject;
@@ -33,12 +40,16 @@
  * A class that manages the roundness for notification views
  */
 @SysUISingleton
-public class NotificationRoundnessManager {
+public class NotificationRoundnessManager implements Dumpable {
+
+    private static final String TAG = "NotificationRoundnessManager";
 
     private final ExpandableView[] mFirstInSectionViews;
     private final ExpandableView[] mLastInSectionViews;
     private final ExpandableView[] mTmpFirstInSectionViews;
     private final ExpandableView[] mTmpLastInSectionViews;
+    private final NotificationRoundnessLogger mNotifLogger;
+    private final DumpManager mDumpManager;
     private boolean mExpanded;
     private HashSet<ExpandableView> mAnimatedChildren;
     private Runnable mRoundingChangedCallback;
@@ -53,12 +64,31 @@
 
     @Inject
     NotificationRoundnessManager(
-            NotificationSectionsFeatureManager sectionsFeatureManager) {
+            NotificationSectionsFeatureManager sectionsFeatureManager,
+            NotificationRoundnessLogger notifLogger,
+            DumpManager dumpManager) {
         int numberOfSections = sectionsFeatureManager.getNumberOfBuckets();
         mFirstInSectionViews = new ExpandableView[numberOfSections];
         mLastInSectionViews = new ExpandableView[numberOfSections];
         mTmpFirstInSectionViews = new ExpandableView[numberOfSections];
         mTmpLastInSectionViews = new ExpandableView[numberOfSections];
+        mNotifLogger = notifLogger;
+        mDumpManager = dumpManager;
+
+        mDumpManager.registerDumpable(TAG, this);
+    }
+
+    @Override
+    public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+        pw.println("mFirstInSectionViews: length=" + mFirstInSectionViews.length);
+        pw.println(dumpViews(mFirstInSectionViews));
+        pw.println("mLastInSectionViews: length=" + mLastInSectionViews.length);
+        pw.println(dumpViews(mFirstInSectionViews));
+        if (mTrackedHeadsUp != null) {
+            pw.println("trackedHeadsUp=" + mTrackedHeadsUp.getEntry());
+        }
+        pw.println("roundForPulsingViews=" + mRoundForPulsingViews);
+        pw.println("isClearAllInProgress=" + mIsClearAllInProgress);
     }
 
     public void updateView(ExpandableView view, boolean animate) {
@@ -95,6 +125,9 @@
         view.setFirstInSection(isFirstInSection);
         view.setLastInSection(isLastInSection);
 
+        mNotifLogger.onCornersUpdated(view, isFirstInSection,
+                isLastInSection, topChanged, bottomChanged);
+
         return (isFirstInSection || isLastInSection) && (topChanged || bottomChanged);
     }
 
@@ -184,6 +217,7 @@
         if (isLastInSection(view) && !top) {
             return 1.0f;
         }
+
         if (view == mTrackedHeadsUp) {
             // If we're pushing up on a headsup the appear fraction is < 0 and it needs to still be
             // rounded.
@@ -220,6 +254,8 @@
         if (anyChanged) {
             mRoundingChangedCallback.run();
         }
+
+        mNotifLogger.onSectionCornersUpdated(sections, anyChanged);
     }
 
     private boolean handleRemovedOldViews(NotificationSection[] sections,
@@ -296,4 +332,36 @@
     public void setShouldRoundPulsingViews(boolean shouldRoundPulsingViews) {
         mRoundForPulsingViews = shouldRoundPulsingViews;
     }
+
+    private String dumpViews(ExpandableView[] views) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < views.length; i++) {
+            if (views[i] == null) continue;
+
+            sb.append("\t")
+                    .append("[").append(i).append("] ")
+                    .append("isPinned=").append(views[i].isPinned()).append(" ")
+                    .append("isFirstInSection=").append(views[i].isFirstInSection()).append(" ")
+                    .append("isLastInSection=").append(views[i].isLastInSection()).append(" ");
+
+            if (views[i] instanceof ExpandableNotificationRow) {
+                sb.append("entry=");
+                dumpEntry(((ExpandableNotificationRow) views[i]).getEntry(), sb);
+            }
+
+            sb.append("\n");
+        }
+        return sb.toString();
+    }
+
+    private void dumpEntry(NotificationEntry entry, StringBuilder sb) {
+        sb.append("NotificationEntry{key=").append(entry.getKey()).append(" ");
+
+        if (entry.getSection() != null) {
+            sb.append(" section=")
+                    .append(entry.getSection().getLabel());
+        }
+
+        sb.append("}");
+    }
 }
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 9603de9..1eafaf0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -1719,13 +1719,18 @@
                 }
 
                 @Override
-                public void onLaunchAnimationCancelled() {
+                public void onLaunchAnimationCancelled(@Nullable Boolean newKeyguardOccludedState) {
+                    if (newKeyguardOccludedState != null) {
+                        mKeyguardViewMediator.setOccluded(
+                                newKeyguardOccludedState, false /* animate */);
+                    }
+
                     // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
                     // animation so that we can assume that mIsLaunchingActivityOverLockscreen
                     // being true means that we will collapse the shade (or at least run the
                     // post collapse runnables) later on.
                     CentralSurfacesImpl.this.mIsLaunchingActivityOverLockscreen = false;
-                    getDelegate().onLaunchAnimationCancelled();
+                    getDelegate().onLaunchAnimationCancelled(newKeyguardOccludedState);
                 }
             };
         } else if (dismissShade) {
@@ -3603,6 +3608,7 @@
             dismissVolumeDialog();
             mWakeUpCoordinator.setFullyAwake(false);
             mKeyguardBypassController.onStartedGoingToSleep();
+            mStatusBarTouchableRegionManager.updateTouchableRegion();
 
             // The unlocked screen off and fold to aod animations might use our LightRevealScrim -
             // we need to be expanded for it to be visible.
@@ -3631,6 +3637,7 @@
                 // once we fully woke up.
                 updateRevealEffect(true /* wakingUp */);
                 updateNotificationPanelTouchState();
+                mStatusBarTouchableRegionManager.updateTouchableRegion();
 
                 // If we are waking up during the screen off animation, we should undo making the
                 // expanded visible (we did that so the LightRevealScrim would be visible).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 985f3cd..6649f3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -667,9 +667,7 @@
     private void setDozing(boolean dozing) {
         if (mDozing != dozing) {
             mDozing = dozing;
-            if (dozing || mBouncer.needsFullscreenBouncer() || mOccluded) {
-                reset(dozing /* hideBouncerWhenShowing */);
-            }
+            reset(true /* hideBouncerWhenShowing */);
             updateStates();
 
             if (!dozing) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
index c092216..ee948c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
@@ -51,7 +51,7 @@
         centralSurfaces.notificationPanelViewController.applyLaunchAnimationProgress(linearProgress)
     }
 
-    override fun onLaunchAnimationCancelled() {
+    override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) {
         delegate.onLaunchAnimationCancelled()
         centralSurfaces.notificationPanelViewController.setIsLaunchAnimationRunning(false)
         centralSurfaces.onLaunchAnimationCancelled(isLaunchForActivity)
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 75dac1a..d9c0293 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -55,6 +55,7 @@
     private final Context mContext;
     private final HeadsUpManagerPhone mHeadsUpManager;
     private final NotificationShadeWindowController mNotificationShadeWindowController;
+    private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
 
     private boolean mIsStatusBarExpanded = false;
     private boolean mShouldAdjustInsets = false;
@@ -72,7 +73,8 @@
             Context context,
             NotificationShadeWindowController notificationShadeWindowController,
             ConfigurationController configurationController,
-            HeadsUpManagerPhone headsUpManager
+            HeadsUpManagerPhone headsUpManager,
+            UnlockedScreenOffAnimationController unlockedScreenOffAnimationController
     ) {
         mContext = context;
         initResources();
@@ -115,6 +117,8 @@
         mNotificationShadeWindowController.setForcePluginOpenListener((forceOpen) -> {
             updateTouchableRegion();
         });
+
+        mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
     }
 
     protected void setup(
@@ -179,7 +183,7 @@
     /**
      * Set the touchable portion of the status bar based on what elements are visible.
      */
-    private void updateTouchableRegion() {
+    public void updateTouchableRegion() {
         boolean hasCutoutInset = (mNotificationShadeWindowView != null)
                 && (mNotificationShadeWindowView.getRootWindowInsets() != null)
                 && (mNotificationShadeWindowView.getRootWindowInsets().getDisplayCutout() != null);
@@ -242,12 +246,25 @@
         touchableRegion.union(bounds);
     }
 
+    /**
+     * Helper to let us know when calculating the region is not needed because we know the entire
+     * screen needs to be touchable.
+     */
+    private boolean shouldMakeEntireScreenTouchable() {
+        // The touchable region is always the full area when expanded, whether we're showing the
+        // shade or the bouncer. It's also fully touchable when the screen off animation is playing
+        // since we don't want stray touches to go through the light reveal scrim to whatever is
+        // underneath.
+        return mIsStatusBarExpanded
+                || mCentralSurfaces.isBouncerShowing()
+                || mUnlockedScreenOffAnimationController.isAnimationPlaying();
+    }
+
     private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener =
             new OnComputeInternalInsetsListener() {
         @Override
         public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
-            if (mIsStatusBarExpanded || mCentralSurfaces.isBouncerShowing()) {
-                // The touchable region is always the full area when expanded
+            if (shouldMakeEntireScreenTouchable()) {
                 return;
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
deleted file mode 100644
index fe84674..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.pipeline
-
-import android.content.Context
-import com.android.systemui.CoreStartable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
-import javax.inject.Inject
-import javax.inject.Provider
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.launch
-
-/**
- * A temporary object that collects on [WifiViewModel] flows for debugging purposes.
- *
- * This will eventually get migrated to a view binder that will use the flow outputs to set state on
- * views. For now, this just collects on flows so that the information gets logged.
- */
-@SysUISingleton
-class ConnectivityInfoProcessor @Inject constructor(
-        context: Context,
-        // TODO(b/238425913): Don't use the application scope; instead, use the status bar view's
-        // scope so we only do work when there's UI that cares about it.
-        @Application private val scope: CoroutineScope,
-        private val statusBarPipelineFlags: StatusBarPipelineFlags,
-        private val wifiViewModelProvider: Provider<WifiViewModel>,
-) : CoreStartable(context) {
-    override fun start() {
-        if (!statusBarPipelineFlags.isNewPipelineBackendEnabled()) {
-            return
-        }
-        // TODO(b/238425913): The view binder should do this instead. For now, do it here so we can
-        // see the logs.
-        scope.launch {
-            wifiViewModelProvider.get().isActivityInVisible.collect { }
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index 681dc6f..9a7c3fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -16,25 +16,15 @@
 
 package com.android.systemui.statusbar.pipeline.dagger
 
-import com.android.systemui.CoreStartable
-import com.android.systemui.statusbar.pipeline.ConnectivityInfoProcessor
 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl
 import dagger.Binds
 import dagger.Module
-import dagger.multibindings.ClassKey
-import dagger.multibindings.IntoMap
 
 @Module
 abstract class StatusBarPipelineModule {
-    /** Inject into ConnectivityInfoProcessor. */
-    @Binds
-    @IntoMap
-    @ClassKey(ConnectivityInfoProcessor::class)
-    abstract fun bindConnectivityInfoProcessor(cip: ConnectivityInfoProcessor): CoreStartable
-
     @Binds
     abstract fun connectivityRepository(impl: ConnectivityRepositoryImpl): ConnectivityRepository
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 753e940..149ed0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -19,14 +19,17 @@
 import android.annotation.Nullable;
 import android.view.View;
 
-import com.android.systemui.Dumpable;
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 
-public interface BatteryController extends DemoMode, Dumpable,
+/**
+ * Controller for battery related information, including the charge level, power save mode,
+ * and time remaining information
+ */
+public interface BatteryController extends DemoMode,
         CallbackController<BatteryStateChangeCallback> {
     /**
      * Prints the current state of the {@link BatteryController} to the given {@link PrintWriter}.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 33ddf7e..c7ad767 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -38,11 +38,13 @@
 import com.android.settingslib.fuelgauge.BatterySaverUtils;
 import com.android.settingslib.fuelgauge.Estimate;
 import com.android.settingslib.utils.PowerUtil;
+import com.android.systemui.Dumpable;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.util.Assert;
 
@@ -56,7 +58,8 @@
  * Default implementation of a {@link BatteryController}. This controller monitors for battery
  * level change events that are broadcasted by the system.
  */
-public class BatteryControllerImpl extends BroadcastReceiver implements BatteryController {
+public class BatteryControllerImpl extends BroadcastReceiver implements BatteryController,
+        Dumpable {
     private static final String TAG = "BatteryController";
 
     private static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
@@ -70,6 +73,7 @@
     private final ArrayList<EstimateFetchCompletion> mFetchCallbacks = new ArrayList<>();
     private final PowerManager mPowerManager;
     private final DemoModeController mDemoModeController;
+    private final DumpManager mDumpManager;
     private final Handler mMainHandler;
     private final Handler mBgHandler;
     protected final Context mContext;
@@ -101,6 +105,7 @@
             PowerManager powerManager,
             BroadcastDispatcher broadcastDispatcher,
             DemoModeController demoModeController,
+            DumpManager dumpManager,
             @Main Handler mainHandler,
             @Background Handler bgHandler) {
         mContext = context;
@@ -110,6 +115,7 @@
         mEstimates = enhancedEstimates;
         mBroadcastDispatcher = broadcastDispatcher;
         mDemoModeController = demoModeController;
+        mDumpManager = dumpManager;
     }
 
     private void registerReceiver() {
@@ -134,6 +140,7 @@
             }
         }
         mDemoModeController.addCallback(this);
+        mDumpManager.registerDumpable(TAG, this);
         updatePowerSave();
         updateEstimateInBackground();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index e7fa6d2..aae0f93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -27,7 +27,6 @@
 import android.os.Message;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 
@@ -37,6 +36,7 @@
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfile;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.systemui.bluetooth.BluetoothLogger;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -57,9 +57,9 @@
 public class BluetoothControllerImpl implements BluetoothController, BluetoothCallback,
         CachedBluetoothDevice.Callback, LocalBluetoothProfileManager.ServiceListener {
     private static final String TAG = "BluetoothController";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final DumpManager mDumpManager;
+    private final BluetoothLogger mLogger;
     private final LocalBluetoothManager mLocalBluetoothManager;
     private final UserManager mUserManager;
     private final int mCurrentUser;
@@ -70,6 +70,7 @@
     private final List<CachedBluetoothDevice> mConnectedDevices = new ArrayList<>();
 
     private boolean mEnabled;
+    @ConnectionState
     private int mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
     private boolean mAudioProfileOnly;
     private boolean mIsActive;
@@ -83,10 +84,12 @@
     public BluetoothControllerImpl(
             Context context,
             DumpManager dumpManager,
+            BluetoothLogger logger,
             @Background Looper bgLooper,
             @Main Looper mainLooper,
             @Nullable LocalBluetoothManager localBluetoothManager) {
         mDumpManager = dumpManager;
+        mLogger = logger;
         mLocalBluetoothManager = localBluetoothManager;
         mBgHandler = new Handler(bgLooper);
         mHandler = new H(mainLooper);
@@ -116,7 +119,7 @@
             return;
         }
         pw.print("  mEnabled="); pw.println(mEnabled);
-        pw.print("  mConnectionState="); pw.println(stateToString(mConnectionState));
+        pw.print("  mConnectionState="); pw.println(connectionStateToString(mConnectionState));
         pw.print("  mAudioProfileOnly="); pw.println(mAudioProfileOnly);
         pw.print("  mIsActive="); pw.println(mIsActive);
         pw.print("  mConnectedDevices="); pw.println(getConnectedDevices());
@@ -127,7 +130,7 @@
         }
     }
 
-    private static String stateToString(int state) {
+    private static String connectionStateToString(@ConnectionState int state) {
         switch (state) {
             case BluetoothAdapter.STATE_CONNECTED:
                 return "CONNECTED";
@@ -320,8 +323,8 @@
     }
 
     @Override
-    public void onBluetoothStateChanged(int bluetoothState) {
-        if (DEBUG) Log.d(TAG, "BluetoothStateChanged=" + stateToString(bluetoothState));
+    public void onBluetoothStateChanged(@AdapterState int bluetoothState) {
+        mLogger.logStateChange(BluetoothAdapter.nameForState(bluetoothState));
         mEnabled = bluetoothState == BluetoothAdapter.STATE_ON
                 || bluetoothState == BluetoothAdapter.STATE_TURNING_ON;
         mState = bluetoothState;
@@ -330,24 +333,25 @@
     }
 
     @Override
-    public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
-        if (DEBUG) Log.d(TAG, "DeviceAdded=" + cachedDevice.getAddress());
+    public void onDeviceAdded(@NonNull CachedBluetoothDevice cachedDevice) {
+        mLogger.logDeviceAdded(cachedDevice.getAddress());
         cachedDevice.registerCallback(this);
         updateConnected();
         mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
     }
 
     @Override
-    public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
-        if (DEBUG) Log.d(TAG, "DeviceDeleted=" + cachedDevice.getAddress());
+    public void onDeviceDeleted(@NonNull CachedBluetoothDevice cachedDevice) {
+        mLogger.logDeviceDeleted(cachedDevice.getAddress());
         mCachedState.remove(cachedDevice);
         updateConnected();
         mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
     }
 
     @Override
-    public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
-        if (DEBUG) Log.d(TAG, "DeviceBondStateChanged=" + cachedDevice.getAddress());
+    public void onDeviceBondStateChanged(
+            @NonNull CachedBluetoothDevice cachedDevice, int bondState) {
+        mLogger.logBondStateChange(cachedDevice.getAddress(), bondState);
         mCachedState.remove(cachedDevice);
         updateConnected();
         mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
@@ -355,50 +359,47 @@
 
     @Override
     public void onDeviceAttributesChanged() {
-        if (DEBUG) Log.d(TAG, "DeviceAttributesChanged");
+        mLogger.logDeviceAttributesChanged();
         updateConnected();
         mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
     }
 
     @Override
-    public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
-        if (DEBUG) {
-            Log.d(TAG, "ConnectionStateChanged=" + cachedDevice.getAddress() + " "
-                    + stateToString(state));
-        }
+    public void onConnectionStateChanged(
+            @Nullable CachedBluetoothDevice cachedDevice,
+            @ConnectionState int state) {
+        mLogger.logDeviceConnectionStateChanged(
+                getAddressOrNull(cachedDevice), connectionStateToString(state));
         mCachedState.remove(cachedDevice);
         updateConnected();
         mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
     }
 
     @Override
-    public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
-            int state, int bluetoothProfile) {
-        if (DEBUG) {
-            Log.d(TAG, "ProfileConnectionStateChanged=" + cachedDevice.getAddress() + " "
-                    + stateToString(state) + " profileId=" + bluetoothProfile);
-        }
+    public void onProfileConnectionStateChanged(
+            @NonNull CachedBluetoothDevice cachedDevice,
+            @ConnectionState int state,
+            int bluetoothProfile) {
+        mLogger.logProfileConnectionStateChanged(
+                cachedDevice.getAddress(), connectionStateToString(state), bluetoothProfile);
         mCachedState.remove(cachedDevice);
         updateConnected();
         mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
     }
 
     @Override
-    public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
-        if (DEBUG) {
-            Log.d(TAG, "ActiveDeviceChanged=" + activeDevice.getAddress()
-                    + " profileId=" + bluetoothProfile);
-        }
+    public void onActiveDeviceChanged(
+            @Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) {
+        mLogger.logActiveDeviceChanged(getAddressOrNull(activeDevice), bluetoothProfile);
         updateActive();
         mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
     }
 
     @Override
-    public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
-        if (DEBUG) {
-            Log.d(TAG, "ACLConnectionStateChanged=" + cachedDevice.getAddress() + " "
-                    + stateToString(state));
-        }
+    public void onAclConnectionStateChanged(
+            @NonNull CachedBluetoothDevice cachedDevice, int state) {
+        mLogger.logAclConnectionStateChanged(
+                cachedDevice.getAddress(), connectionStateToString(state));
         mCachedState.remove(cachedDevice);
         updateConnected();
         mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
@@ -415,6 +416,11 @@
         return state;
     }
 
+    @Nullable
+    private String getAddressOrNull(@Nullable CachedBluetoothDevice device) {
+        return device == null ? null : device.getAddress();
+    }
+
     @Override
     public void onServiceConnected() {
         updateConnected();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 3b8ed33..63e88a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -1122,11 +1122,19 @@
         }
 
         public String getName(Context context, UserRecord item) {
+            return getName(context, item, false);
+        }
+
+        /**
+         * Returns the name for the given {@link UserRecord}.
+         */
+        public String getName(Context context, UserRecord item, boolean isTablet) {
             return LegacyUserUiHelper.getUserRecordName(
                     context,
                     item,
                     mController.isGuestUserAutoCreated(),
-                    mController.isGuestUserResetting());
+                    mController.isGuestUserResetting(),
+                    isTablet);
         }
 
         protected static ColorFilter getDisabledUserAvatarColorFilter() {
@@ -1136,8 +1144,12 @@
         }
 
         protected static Drawable getIconDrawable(Context context, UserRecord item) {
+            return getIconDrawable(context, item, false);
+        }
+        protected static Drawable getIconDrawable(Context context, UserRecord item,
+                boolean isTablet) {
             int iconRes = LegacyUserUiHelper.getUserSwitcherActionIconResourceId(
-                    item.isAddUser, item.isGuest, item.isAddSupervisedUser);
+                    item.isAddUser, item.isGuest, item.isAddSupervisedUser, isTablet);
             return context.getDrawable(iconRes);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
index 734eeec..a52e2af 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
@@ -19,12 +19,10 @@
 import android.annotation.LayoutRes
 import android.annotation.SuppressLint
 import android.content.Context
-import android.content.pm.PackageManager
 import android.graphics.PixelFormat
 import android.graphics.drawable.Drawable
 import android.os.PowerManager
 import android.os.SystemClock
-import android.util.Log
 import android.view.LayoutInflater
 import android.view.ViewGroup
 import android.view.WindowManager
@@ -33,11 +31,7 @@
 import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS
 import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_TEXT
 import androidx.annotation.CallSuper
-import com.android.internal.widget.CachingIconView
-import com.android.settingslib.Utils
-import com.android.systemui.R
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.concurrency.DelayableExecutor
 
@@ -50,17 +44,22 @@
  * The generic type T is expected to contain all the information necessary for the subclasses to
  * display the view in a certain state, since they receive <T> in [updateView].
  *
- * TODO(b/245610654): Remove all the media-specific logic from this class.
+ * @property windowTitle the title to use for the window that displays the temporary view. Should be
+ *   normally cased, like "Window Title".
+ * @property wakeReason a string used for logging if we needed to wake the screen in order to
+ *   display the temporary view. Should be screaming snake cased, like WAKE_REASON.
  */
-abstract class TemporaryViewDisplayController<T : TemporaryViewInfo>(
+abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : TemporaryViewLogger>(
     internal val context: Context,
-    internal val logger: MediaTttLogger,
+    internal val logger: U,
     internal val windowManager: WindowManager,
     @Main private val mainExecutor: DelayableExecutor,
     private val accessibilityManager: AccessibilityManager,
     private val configurationController: ConfigurationController,
     private val powerManager: PowerManager,
     @LayoutRes private val viewLayoutRes: Int,
+    private val windowTitle: String,
+    private val wakeReason: String,
 ) {
     /**
      * Window layout params that will be used as a starting point for the [windowLayoutParams] of
@@ -72,7 +71,7 @@
         height = WindowManager.LayoutParams.WRAP_CONTENT
         type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY
         flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-        title = WINDOW_TITLE
+        title = windowTitle
         format = PixelFormat.TRANSLUCENT
         setTrustedOverlay()
     }
@@ -115,10 +114,10 @@
                 powerManager.wakeUp(
                         SystemClock.uptimeMillis(),
                         PowerManager.WAKE_REASON_APPLICATION,
-                        "com.android.systemui:media_tap_to_transfer_activated"
+                        "com.android.systemui:$wakeReason",
                 )
             }
-
+            logger.logChipAddition()
             inflateAndUpdateView(newInfo)
         }
 
@@ -192,80 +191,8 @@
      * appears.
      */
     open fun animateViewIn(view: ViewGroup) {}
-
-    /**
-     * Returns the size that the icon should be, or null if no size override is needed.
-     */
-    open fun getIconSize(isAppIcon: Boolean): Int? = null
-
-    /**
-     * An internal method to set the icon on the view.
-     *
-     * This is in the common superclass since both the sender and the receiver show an icon.
-     *
-     * @param appPackageName the package name of the app playing the media. Will be used to fetch
-     *   the app icon and app name if overrides aren't provided.
-     *
-     * @return the content description of the icon.
-     */
-    internal fun setIcon(
-        currentView: ViewGroup,
-        appPackageName: String?,
-        appIconDrawableOverride: Drawable? = null,
-        appNameOverride: CharSequence? = null,
-    ): CharSequence {
-        val appIconView = currentView.requireViewById<CachingIconView>(R.id.app_icon)
-        val iconInfo = getIconInfo(appPackageName)
-
-        getIconSize(iconInfo.isAppIcon)?.let { size ->
-            val lp = appIconView.layoutParams
-            lp.width = size
-            lp.height = size
-            appIconView.layoutParams = lp
-        }
-
-        appIconView.contentDescription = appNameOverride ?: iconInfo.iconName
-        appIconView.setImageDrawable(appIconDrawableOverride ?: iconInfo.icon)
-        return appIconView.contentDescription
-    }
-
-    /**
-     * Returns the information needed to display the icon.
-     *
-     * The information will either contain app name and icon of the app playing media, or a default
-     * name and icon if we can't find the app name/icon.
-     */
-    private fun getIconInfo(appPackageName: String?): IconInfo {
-        if (appPackageName != null) {
-            try {
-                return IconInfo(
-                    iconName = context.packageManager.getApplicationInfo(
-                        appPackageName, PackageManager.ApplicationInfoFlags.of(0)
-                    ).loadLabel(context.packageManager).toString(),
-                    icon = context.packageManager.getApplicationIcon(appPackageName),
-                    isAppIcon = true
-                )
-            } catch (e: PackageManager.NameNotFoundException) {
-                Log.w(TAG, "Cannot find package $appPackageName", e)
-            }
-        }
-        return IconInfo(
-            iconName = context.getString(R.string.media_output_dialog_unknown_launch_app_name),
-            icon = context.resources.getDrawable(R.drawable.ic_cast).apply {
-                this.setTint(
-                    Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
-                )
-            },
-            isAppIcon = false
-        )
-    }
 }
 
-// Used in CTS tests UpdateMediaTapToTransferSenderDisplayTest and
-// UpdateMediaTapToTransferReceiverDisplayTest
-private const val WINDOW_TITLE = "Media Transfer Chip View"
-private val TAG = TemporaryViewDisplayController::class.simpleName!!
-
 object TemporaryDisplayRemovalReason {
     const val REASON_TIMEOUT = "TIMEOUT"
     const val REASON_SCREEN_TAP = "SCREEN_TAP"
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewLogger.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewLogger.kt
new file mode 100644
index 0000000..606a11a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewLogger.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.temporarydisplay
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+
+/** A logger for temporary view changes -- see [TemporaryViewDisplayController]. */
+open class TemporaryViewLogger(
+    internal val buffer: LogBuffer,
+    internal val tag: String,
+) {
+    /** Logs that we added the chip to a new window. */
+    fun logChipAddition() {
+        buffer.log(tag, LogLevel.DEBUG, {}, { "Chip added" })
+    }
+
+    /** Logs that we removed the chip for the given [reason]. */
+    fun logChipRemoval(reason: String) {
+        buffer.log(tag, LogLevel.DEBUG, { str1 = reason }, { "Chip removed due to $str1" })
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index 27746c0..00ed3d6 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -36,6 +36,7 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
 import com.android.systemui.doze.DozeHost;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.navigationbar.gestural.GestureModule;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -116,9 +117,12 @@
     static BatteryController provideBatteryController(Context context,
             EnhancedEstimates enhancedEstimates, PowerManager powerManager,
             BroadcastDispatcher broadcastDispatcher, DemoModeController demoModeController,
+            DumpManager dumpManager,
             @Main Handler mainHandler, @Background Handler bgHandler) {
         BatteryController bC = new BatteryControllerImpl(context, enhancedEstimates, powerManager,
-                broadcastDispatcher, demoModeController, mainHandler, bgHandler);
+                broadcastDispatcher, demoModeController,
+                dumpManager,
+                mainHandler, bgHandler);
         bC.init();
         return bC;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
index d43f739..5e2dde6 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
@@ -173,8 +173,8 @@
             this,
             R.layout.user_switcher_fullscreen_popup_item,
             layoutInflater,
-            { item: UserRecord -> adapter.getName(this@UserSwitcherActivity, item) },
-            { item: UserRecord -> adapter.findUserIcon(item).mutate().apply {
+            { item: UserRecord -> adapter.getName(this@UserSwitcherActivity, item, true) },
+            { item: UserRecord -> adapter.findUserIcon(item, true).mutate().apply {
                 setTint(resources.getColor(
                     R.color.user_switcher_fullscreen_popup_item_tint,
                     getTheme()
@@ -322,6 +322,9 @@
         return flags.isEnabled(Flags.MODERN_USER_SWITCHER_ACTIVITY)
     }
 
+    /**
+     * Provides views to populate the option menu.
+     */
     private class ItemAdapter(
         val parentContext: Context,
         val resource: Int,
@@ -375,20 +378,20 @@
             return view
         }
 
-        override fun getName(context: Context, item: UserRecord): String {
+        override fun getName(context: Context, item: UserRecord, isTablet: Boolean): String {
             return if (item == manageUserRecord) {
                 getString(R.string.manage_users)
             } else {
-                super.getName(context, item)
+                super.getName(context, item, isTablet)
             }
         }
 
-        fun findUserIcon(item: UserRecord): Drawable {
+        fun findUserIcon(item: UserRecord, isTablet: Boolean = false): Drawable {
             if (item == manageUserRecord) {
                 return getDrawable(R.drawable.ic_manage_users)
             }
             if (item.info == null) {
-                return getIconDrawable(this@UserSwitcherActivity, item)
+                return getIconDrawable(this@UserSwitcherActivity, item, isTablet)
             }
             val userIcon = userManager.getUserIcon(item.info.id)
             if (userIcon != null) {
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 18369d9..15fdc35 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
@@ -49,8 +49,11 @@
         isAddUser: Boolean,
         isGuest: Boolean,
         isAddSupervisedUser: Boolean,
+        isTablet: Boolean = false,
     ): Int {
-        return if (isAddUser) {
+        return if (isAddUser && isTablet) {
+            R.drawable.ic_account_circle_filled
+        } else if (isAddUser) {
             R.drawable.ic_add
         } else if (isGuest) {
             R.drawable.ic_account_circle
@@ -67,6 +70,7 @@
         record: UserRecord,
         isGuestUserAutoCreated: Boolean,
         isGuestUserResetting: Boolean,
+        isTablet: Boolean = false,
     ): String {
         val resourceId: Int? = getGuestUserRecordNameResourceId(record)
         return when {
@@ -80,6 +84,7 @@
                         isGuestUserResetting = isGuestUserResetting,
                         isAddUser = record.isAddUser,
                         isAddSupervisedUser = record.isAddSupervisedUser,
+                        isTablet = isTablet,
                     )
                 )
         }
@@ -108,12 +113,14 @@
         isGuestUserResetting: Boolean,
         isAddUser: Boolean,
         isAddSupervisedUser: Boolean,
+        isTablet: Boolean = false,
     ): Int {
         check(isGuest || isAddUser || isAddSupervisedUser)
 
         return when {
             isGuest && isGuestUserAutoCreated && isGuestUserResetting ->
                 com.android.settingslib.R.string.guest_resetting
+            isGuest && isTablet -> com.android.settingslib.R.string.guest_new_guest
             isGuest && isGuestUserAutoCreated -> com.android.internal.R.string.guest_name
             isGuest -> com.android.internal.R.string.guest_name
             isAddUser -> com.android.settingslib.R.string.user_add_user
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 83a3d0d..d7ad3ce 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
@@ -129,7 +129,10 @@
                     viewModel.users.collect { users ->
                         val viewPool =
                             view.children.filter { it.tag == USER_VIEW_TAG }.toMutableList()
-                        viewPool.forEach { view.removeView(it) }
+                        viewPool.forEach {
+                            view.removeView(it)
+                            flowWidget.removeView(it)
+                        }
                         users.forEach { userViewModel ->
                             val userView =
                                 if (viewPool.isNotEmpty()) {
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 66ce01b..398341d 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
@@ -20,6 +20,7 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import com.android.systemui.R
+import com.android.systemui.common.ui.drawable.CircularDrawable
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.user.domain.interactor.UserInteractor
 import com.android.systemui.user.legacyhelper.ui.LegacyUserUiHelper
@@ -130,7 +131,7 @@
         return UserViewModel(
             viewKey = model.id,
             name = model.name,
-            image = model.image,
+            image = CircularDrawable(model.image),
             isSelectionMarkerVisible = model.isSelected,
             alpha =
                 if (model.isSelectable) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index c7ba518..903aba1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -48,6 +48,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -74,6 +75,7 @@
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.text.InputFilter;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
@@ -1049,7 +1051,13 @@
                 Events.writeEvent(Events.EVENT_SETTINGS_CLICK);
                 dismissH(DISMISS_REASON_SETTINGS_CLICKED);
                 mMediaOutputDialogFactory.dismiss();
-                mVolumePanelFactory.create(true /* aboveStatusBar */, null);
+                if (FeatureFlagUtils.isEnabled(mContext,
+                        FeatureFlagUtils.SETTINGS_VOLUME_PANEL_IN_SYSTEMUI)) {
+                    mVolumePanelFactory.create(true /* aboveStatusBar */, null);
+                } else {
+                    mActivityStarter.startActivity(new Intent(Settings.Panel.ACTION_VOLUME),
+                            true /* dismissShade */);
+                }
             });
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 914d945..25e7dbb 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -119,6 +119,20 @@
     }
 
     @Test
+    fun fontChanged_verifyFontSizeUpdated() {
+        clockEventController.clock = clock
+        verify(events).onColorPaletteChanged(any(), any(), any())
+
+        clockEventController.registerListeners()
+
+        val captor = argumentCaptor<ConfigurationController.ConfigurationListener>()
+        verify(configurationController).addCallback(capture(captor))
+        captor.value.onDensityOrFontScaleChanged()
+
+        verify(events).onFontSettingChanged()
+    }
+
+    @Test
     fun batteryCallback_keyguardShowingCharging_verifyChargeAnimation() {
         clockEventController.clock = clock
         clockEventController.registerListeners()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 508f81d..e3c7128 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -329,8 +329,7 @@
     @After
     public void tearDown() {
         mMockitoSession.finishMocking();
-        mKeyguardUpdateMonitor.removeCallback(mTestCallback);
-        mKeyguardUpdateMonitor.destroy();
+        cleanupKeyguardUpdateMonitor();
     }
 
     @Test
@@ -352,6 +351,7 @@
 
     @Test
     public void testSimStateInitialized() {
+        cleanupKeyguardUpdateMonitor();
         final int subId = 3;
         final int state = TelephonyManager.SIM_STATE_ABSENT;
 
@@ -1206,7 +1206,9 @@
 
     @Test
     public void testShouldListenForFace_whenFaceManagerNotAvailable_returnsFalse() {
-        mFaceManager = null;
+        cleanupKeyguardUpdateMonitor();
+        mSpiedContext.addMockSystemService(FaceManager.class, null);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(false);
         mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mSpiedContext);
 
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
@@ -1259,6 +1261,7 @@
 
     @Test
     public void testShouldListenForFace_whenUserIsNotPrimary_returnsFalse() throws RemoteException {
+        cleanupKeyguardUpdateMonitor();
         // This disables face auth
         when(mUserManager.isPrimaryUser()).thenReturn(false);
         mKeyguardUpdateMonitor =
@@ -1588,9 +1591,9 @@
 
     @Test
     public void testFingerAcquired_wakesUpPowerManager() {
-        mContext.getOrCreateTestableResources().addOverride(
+        cleanupKeyguardUpdateMonitor();
+        mSpiedContext.getOrCreateTestableResources().addOverride(
                 com.android.internal.R.bool.kg_wake_on_acquire_start, true);
-        mSpiedContext = spy(mContext);
         mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mSpiedContext);
         fingerprintAcquireStart();
 
@@ -1599,15 +1602,23 @@
 
     @Test
     public void testFingerAcquired_doesNotWakeUpPowerManager() {
-        mContext.getOrCreateTestableResources().addOverride(
+        cleanupKeyguardUpdateMonitor();
+        mSpiedContext.getOrCreateTestableResources().addOverride(
                 com.android.internal.R.bool.kg_wake_on_acquire_start, false);
-        mSpiedContext = spy(mContext);
         mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mSpiedContext);
         fingerprintAcquireStart();
 
         verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString());
     }
 
+    private void cleanupKeyguardUpdateMonitor() {
+        if (mKeyguardUpdateMonitor != null) {
+            mKeyguardUpdateMonitor.removeCallback(mTestCallback);
+            mKeyguardUpdateMonitor.destroy();
+            mKeyguardUpdateMonitor = null;
+        }
+    }
+
     private void faceAuthLockedOut() {
         mKeyguardUpdateMonitor.mFaceAuthenticationCallback
                 .onAuthenticationError(FaceManager.FACE_ERROR_LOCKOUT_PERMANENT, "");
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 e2790e4..a61cd23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -161,7 +161,18 @@
         runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback)
 
         waitForIdleSync()
-        verify(controller).onLaunchAnimationCancelled()
+        verify(controller).onLaunchAnimationCancelled(false /* newKeyguardOccludedState */)
+        verify(controller, never()).onLaunchAnimationStart(anyBoolean())
+    }
+
+    @Test
+    fun passesOccludedStateToLaunchAnimationCancelled_ifTrue() {
+        val runner = activityLaunchAnimator.createRunner(controller)
+        runner.onAnimationCancelled(true /* isKeyguardOccluded */)
+        runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback)
+
+        waitForIdleSync()
+        verify(controller).onLaunchAnimationCancelled(true /* newKeyguardOccludedState */)
         verify(controller, never()).onLaunchAnimationStart(anyBoolean())
     }
 
@@ -253,7 +264,7 @@
         assertOnMainThread()
     }
 
-    override fun onLaunchAnimationCancelled() {
+    override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) {
         assertOnMainThread()
     }
 }
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 bf3788e..4a5b23c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -29,6 +29,7 @@
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
 import android.testing.ViewUtils
+import android.view.KeyEvent
 import android.view.View
 import android.view.WindowInsets
 import android.view.WindowManager
@@ -92,6 +93,21 @@
     }
 
     @Test
+    fun testDismissesOnBack() {
+        val container = initializeFingerprintContainer(addToView = true)
+        assertThat(container.parent).isNotNull()
+        val root = container.rootView
+
+        // Simulate back invocation
+        container.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK))
+        container.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK))
+        waitForIdleSync()
+
+        assertThat(container.parent).isNull()
+        assertThat(root.isAttachedToWindow).isFalse()
+    }
+
+    @Test
     fun testIgnoresAnimatedInWhenDismissed() {
         val container = initializeFingerprintContainer(addToView = false)
         container.dismissFromSystemServer()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
index 44ef922..37bb0c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -18,6 +18,7 @@
 
 import android.graphics.Point
 import android.hardware.biometrics.BiometricSourceType
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
@@ -76,6 +77,7 @@
     @Mock private lateinit var udfpsController: UdfpsController
     @Mock private lateinit var statusBarStateController: StatusBarStateController
     @Mock private lateinit var lightRevealScrim: LightRevealScrim
+    @Mock private lateinit var fpSensorProp: FingerprintSensorPropertiesInternal
 
     @Before
     fun setUp() {
@@ -86,6 +88,7 @@
                 .startMocking()
 
         `when`(RotationUtils.getRotation(context)).thenReturn(RotationUtils.ROTATION_NONE)
+        `when`(authController.udfpsProps).thenReturn(listOf(fpSensorProp))
         `when`(udfpsControllerProvider.get()).thenReturn(udfpsController)
 
         controller = AuthRippleController(
@@ -132,7 +135,7 @@
             false /* isStrongBiometric */)
 
         // THEN update sensor location and show ripple
-        verify(rippleView).setFingerprintSensorLocation(fpsLocation, -1f)
+        verify(rippleView).setFingerprintSensorLocation(fpsLocation, 0f)
         verify(rippleView).startUnlockedRipple(any())
     }
 
@@ -155,7 +158,7 @@
                 false /* isStrongBiometric */)
 
         // THEN update sensor location and show ripple
-        verify(rippleView).setFingerprintSensorLocation(fpsLocation, -1f)
+        verify(rippleView).setFingerprintSensorLocation(fpsLocation, 0f)
         verify(rippleView).startUnlockedRipple(any())
     }
 
@@ -342,4 +345,23 @@
         captor.value.onUiModeChanged()
         verify(rippleView).setLockScreenColor(ArgumentMatchers.anyInt())
     }
+
+    @Test
+    fun testUdfps_onFingerDown_showDwellRipple() {
+        // GIVEN view is already attached
+        controller.onViewAttached()
+        val captor = ArgumentCaptor.forClass(UdfpsController.Callback::class.java)
+        verify(udfpsController).addCallback(captor.capture())
+
+        // GIVEN fp is updated to Point(5, 5)
+        val fpsLocation = Point(5, 5)
+        `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
+
+        // WHEN finger is down
+        captor.value.onFingerDown()
+
+        // THEN update sensor location and show ripple
+        verify(rippleView).setFingerprintSensorLocation(fpsLocation, 0f)
+        verify(rippleView).startDwellRipple(false)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricMessageDeferralTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricMessageDeferralTest.kt
deleted file mode 100644
index 419fedf..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricMessageDeferralTest.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics
-
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertNull
-import org.junit.Assert.assertTrue
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class BiometricMessageDeferralTest : SysuiTestCase() {
-
-    @Test
-    fun testProcessNoMessages_noDeferredMessage() {
-        val biometricMessageDeferral = BiometricMessageDeferral(setOf(), setOf())
-
-        assertNull(biometricMessageDeferral.getDeferredMessage())
-    }
-
-    @Test
-    fun testProcessNonDeferredMessages_noDeferredMessage() {
-        val biometricMessageDeferral = BiometricMessageDeferral(setOf(), setOf(1, 2))
-
-        // WHEN there are no deferred messages processed
-        for (i in 0..3) {
-            biometricMessageDeferral.processMessage(4, "test")
-        }
-
-        // THEN getDeferredMessage is null
-        assertNull(biometricMessageDeferral.getDeferredMessage())
-    }
-
-    @Test
-    fun testAllProcessedMessagesWereDeferred() {
-        val biometricMessageDeferral = BiometricMessageDeferral(setOf(), setOf(1))
-
-        // WHEN all the processed messages are a deferred message
-        for (i in 0..3) {
-            biometricMessageDeferral.processMessage(1, "test")
-        }
-
-        // THEN deferredMessage will return the string associated with the deferred msgId
-        assertEquals("test", biometricMessageDeferral.getDeferredMessage())
-    }
-
-    @Test
-    fun testReturnsMostFrequentDeferredMessage() {
-        val biometricMessageDeferral = BiometricMessageDeferral(setOf(), setOf(1, 2))
-
-        // WHEN there's two msgId=1 processed and one msgId=2 processed
-        biometricMessageDeferral.processMessage(1, "msgId-1")
-        biometricMessageDeferral.processMessage(1, "msgId-1")
-        biometricMessageDeferral.processMessage(1, "msgId-1")
-        biometricMessageDeferral.processMessage(2, "msgId-2")
-
-        // THEN the most frequent deferred message is that meets the threshold is returned
-        assertEquals("msgId-1", biometricMessageDeferral.getDeferredMessage())
-    }
-
-    @Test
-    fun testDeferredMessage_mustMeetThreshold() {
-        val biometricMessageDeferral = BiometricMessageDeferral(setOf(), setOf(1))
-
-        // WHEN more nonDeferredMessages are shown than the deferred message
-        val totalMessages = 10
-        val nonDeferredMessagesCount =
-            (totalMessages * BiometricMessageDeferral.THRESHOLD).toInt() + 1
-        for (i in 0 until nonDeferredMessagesCount) {
-            biometricMessageDeferral.processMessage(4, "non-deferred-msg")
-        }
-        for (i in nonDeferredMessagesCount until totalMessages) {
-            biometricMessageDeferral.processMessage(1, "msgId-1")
-        }
-
-        // THEN there's no deferred message because it didn't meet the threshold
-        assertNull(biometricMessageDeferral.getDeferredMessage())
-    }
-
-    @Test
-    fun testDeferredMessage_manyExcludedMessages_getDeferredMessage() {
-        val biometricMessageDeferral = BiometricMessageDeferral(setOf(3), setOf(1))
-
-        // WHEN more excludedMessages are shown than the deferred message
-        val totalMessages = 10
-        val excludedMessagesCount = (totalMessages * BiometricMessageDeferral.THRESHOLD).toInt() + 1
-        for (i in 0 until excludedMessagesCount) {
-            biometricMessageDeferral.processMessage(3, "excluded-msg")
-        }
-        for (i in excludedMessagesCount until totalMessages) {
-            biometricMessageDeferral.processMessage(1, "msgId-1")
-        }
-
-        // THEN there IS a deferred message because the deferred msg meets the threshold amongst the
-        // non-excluded messages
-        assertEquals("msgId-1", biometricMessageDeferral.getDeferredMessage())
-    }
-
-    @Test
-    fun testResetClearsOutCounts() {
-        val biometricMessageDeferral = BiometricMessageDeferral(setOf(), setOf(1, 2))
-
-        // GIVEN two msgId=1 events processed
-        biometricMessageDeferral.processMessage(1, "msgId-1")
-        biometricMessageDeferral.processMessage(1, "msgId-1")
-
-        // WHEN counts are reset and then a single deferred message is processed (msgId=2)
-        biometricMessageDeferral.reset()
-        biometricMessageDeferral.processMessage(2, "msgId-2")
-
-        // THEN msgId-2 is the deferred message since the two msgId=1 events were reset
-        assertEquals("msgId-2", biometricMessageDeferral.getDeferredMessage())
-    }
-
-    @Test
-    fun testShouldDefer() {
-        // GIVEN should defer msgIds 1 and 2
-        val biometricMessageDeferral = BiometricMessageDeferral(setOf(3), setOf(1, 2))
-
-        // THEN shouldDefer returns true for ids 1 & 2
-        assertTrue(biometricMessageDeferral.shouldDefer(1))
-        assertTrue(biometricMessageDeferral.shouldDefer(2))
-
-        // THEN should defer returns false for ids 3 & 4
-        assertFalse(biometricMessageDeferral.shouldDefer(3))
-        assertFalse(biometricMessageDeferral.shouldDefer(4))
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
new file mode 100644
index 0000000..c9ccdb3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.keyguard.logging.BiometricMessageDeferralLogger
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class FaceHelpMessageDeferralTest : SysuiTestCase() {
+    val threshold = .75f
+    @Mock lateinit var logger: BiometricMessageDeferralLogger
+    @Mock lateinit var dumpManager: DumpManager
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @Test
+    fun testProcessFrame_logs() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1))
+        biometricMessageDeferral.processFrame(1)
+        verify(logger).logFrameProcessed(1, 1, "1")
+    }
+
+    @Test
+    fun testUpdateMessage_logs() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1))
+        biometricMessageDeferral.updateMessage(1, "hi")
+        verify(logger).logUpdateMessage(1, "hi")
+    }
+
+    @Test
+    fun testReset_logs() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1))
+        biometricMessageDeferral.reset()
+        verify(logger).reset()
+    }
+
+    @Test
+    fun testProcessNoMessages_noDeferredMessage() {
+        val biometricMessageDeferral = createMsgDeferral(emptySet())
+
+        assertNull(biometricMessageDeferral.getDeferredMessage())
+    }
+
+    @Test
+    fun testProcessNonDeferredMessages_noDeferredMessage() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1, 2))
+
+        // WHEN there are no deferred messages processed
+        for (i in 0..3) {
+            biometricMessageDeferral.processFrame(4)
+            biometricMessageDeferral.updateMessage(4, "test")
+        }
+
+        // THEN getDeferredMessage is null
+        assertNull(biometricMessageDeferral.getDeferredMessage())
+    }
+
+    @Test
+    fun testProcessMessagesWithDeferredMessage_deferredMessageWasNeverGivenAString() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1, 2))
+
+        biometricMessageDeferral.processFrame(1)
+
+        assertNull(biometricMessageDeferral.getDeferredMessage())
+    }
+
+    @Test
+    fun testAllProcessedMessagesWereDeferred() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1))
+
+        // WHEN all the processed messages are a deferred message
+        for (i in 0..3) {
+            biometricMessageDeferral.processFrame(1)
+            biometricMessageDeferral.updateMessage(1, "test")
+        }
+
+        // THEN deferredMessage will return the string associated with the deferred msgId
+        assertEquals("test", biometricMessageDeferral.getDeferredMessage())
+    }
+
+    @Test
+    fun testReturnsMostFrequentDeferredMessage() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1, 2))
+
+        // WHEN there's 80%of the messages are msgId=1 and 20% is msgId=2
+        biometricMessageDeferral.processFrame(1)
+        biometricMessageDeferral.processFrame(1)
+        biometricMessageDeferral.processFrame(1)
+        biometricMessageDeferral.processFrame(1)
+        biometricMessageDeferral.updateMessage(1, "msgId-1")
+
+        biometricMessageDeferral.processFrame(2)
+        biometricMessageDeferral.updateMessage(2, "msgId-2")
+
+        // THEN the most frequent deferred message is that meets the threshold is returned
+        assertEquals("msgId-1", biometricMessageDeferral.getDeferredMessage())
+    }
+
+    @Test
+    fun testDeferredMessage_mustMeetThreshold() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1))
+
+        // WHEN more nonDeferredMessages are shown than the deferred message
+        val totalMessages = 10
+        val nonDeferredMessagesCount = (totalMessages * threshold).toInt() + 1
+        for (i in 0 until nonDeferredMessagesCount) {
+            biometricMessageDeferral.processFrame(4)
+            biometricMessageDeferral.updateMessage(4, "non-deferred-msg")
+        }
+        for (i in nonDeferredMessagesCount until totalMessages) {
+            biometricMessageDeferral.processFrame(1)
+            biometricMessageDeferral.updateMessage(1, "msgId-1")
+        }
+
+        // THEN there's no deferred message because it didn't meet the threshold
+        assertNull(biometricMessageDeferral.getDeferredMessage())
+    }
+
+    @Test
+    fun testResetClearsOutCounts() {
+        val biometricMessageDeferral = createMsgDeferral(setOf(1, 2))
+
+        // GIVEN two msgId=1 events processed
+        biometricMessageDeferral.processFrame(
+            1,
+        )
+        biometricMessageDeferral.updateMessage(1, "msgId-1")
+        biometricMessageDeferral.processFrame(1)
+        biometricMessageDeferral.updateMessage(1, "msgId-1")
+
+        // WHEN counts are reset and then a single deferred message is processed (msgId=2)
+        biometricMessageDeferral.reset()
+        biometricMessageDeferral.processFrame(2)
+        biometricMessageDeferral.updateMessage(2, "msgId-2")
+
+        // THEN msgId-2 is the deferred message since the two msgId=1 events were reset
+        assertEquals("msgId-2", biometricMessageDeferral.getDeferredMessage())
+    }
+
+    @Test
+    fun testShouldDefer() {
+        // GIVEN should defer msgIds 1 and 2
+        val biometricMessageDeferral = createMsgDeferral(setOf(1, 2))
+
+        // THEN shouldDefer returns true for ids 1 & 2
+        assertTrue(biometricMessageDeferral.shouldDefer(1))
+        assertTrue(biometricMessageDeferral.shouldDefer(2))
+
+        // THEN should defer returns false for ids 3 & 4
+        assertFalse(biometricMessageDeferral.shouldDefer(3))
+        assertFalse(biometricMessageDeferral.shouldDefer(4))
+    }
+
+    private fun createMsgDeferral(messagesToDefer: Set<Int>): BiometricMessageDeferral {
+        return BiometricMessageDeferral(messagesToDefer, threshold, logger, dumpManager)
+    }
+}
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 cb8358d..5c564e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -17,23 +17,13 @@
 package com.android.systemui.biometrics
 
 import android.graphics.Rect
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_BP
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_OTHER
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR
-import android.hardware.biometrics.BiometricOverlayConstants.ShowReason
+import android.hardware.biometrics.BiometricOverlayConstants.*
 import android.hardware.fingerprint.FingerprintManager
 import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
-import android.view.LayoutInflater
-import android.view.MotionEvent
-import android.view.View
-import android.view.Surface
+import android.view.*
 import android.view.Surface.Rotation
-import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -65,7 +55,6 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
 
-private const val HAL_CONTROLS_ILLUMINATION = true
 private const val REQUEST_ID = 2L
 
 // Dimensions for the current display resolution.
@@ -95,8 +84,9 @@
     @Mock private lateinit var configurationController: ConfigurationController
     @Mock private lateinit var systemClock: SystemClock
     @Mock private lateinit var keyguardStateController: KeyguardStateController
-    @Mock private lateinit var unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController
-    @Mock private lateinit var hbmProvider: UdfpsHbmProvider
+    @Mock private lateinit var unlockedScreenOffAnimationController:
+            UnlockedScreenOffAnimationController
+    @Mock private lateinit var udfpsDisplayMode: UdfpsDisplayModeProvider
     @Mock private lateinit var controllerCallback: IUdfpsOverlayControllerCallback
     @Mock private lateinit var udfpsController: UdfpsController
     @Mock private lateinit var udfpsView: UdfpsView
@@ -130,8 +120,9 @@
             statusBarStateController, panelExpansionStateManager, statusBarKeyguardViewManager,
             keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
             configurationController, systemClock, keyguardStateController,
-            unlockedScreenOffAnimationController, HAL_CONTROLS_ILLUMINATION, hbmProvider,
-            REQUEST_ID, reason, controllerCallback, onTouch, activityLaunchAnimator)
+            unlockedScreenOffAnimationController, udfpsDisplayMode, REQUEST_ID, reason,
+            controllerCallback, onTouch, activityLaunchAnimator
+        )
         block()
     }
 
@@ -246,7 +237,7 @@
         val didShow = controllerOverlay.show(udfpsController, overlayParams)
 
         verify(windowManager).addView(eq(controllerOverlay.overlayView), any())
-        verify(udfpsView).setHbmProvider(eq(hbmProvider))
+        verify(udfpsView).setUdfpsDisplayModeProvider(eq(udfpsDisplayMode))
         verify(udfpsView).animationViewController = any()
         verify(udfpsView).addView(any())
 
@@ -351,12 +342,12 @@
     }
 
     @Test
-    fun stopIlluminatingOnHide() = withReason(REASON_AUTH_BP) {
-        whenever(udfpsView.isIlluminationRequested).thenReturn(true)
+    fun unconfigureDisplayOnHide() = withReason(REASON_AUTH_BP) {
+        whenever(udfpsView.isDisplayConfigured).thenReturn(true)
 
         controllerOverlay.show(udfpsController, overlayParams)
         controllerOverlay.hide()
-        verify(udfpsView).stopIllumination()
+        verify(udfpsView).unconfigureDisplay()
     }
 
     @Test
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 d7a0a0a..a6c0539 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -125,7 +125,7 @@
     @Mock
     private WindowManager mWindowManager;
     @Mock
-    private UdfpsHbmProvider mHbmProvider;
+    private UdfpsDisplayModeProvider mDisplayModeProvider;
     @Mock
     private StatusBarStateController mStatusBarStateController;
     @Mock
@@ -193,7 +193,7 @@
     private IUdfpsOverlayController mOverlayController;
     @Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor;
     @Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor;
-    @Captor private ArgumentCaptor<Runnable> mOnIlluminatedRunnableCaptor;
+    @Captor private ArgumentCaptor<Runnable> mOnDisplayConfiguredCaptor;
     @Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
     private ScreenLifecycle.Observer mScreenObserver;
 
@@ -256,7 +256,7 @@
                 mVibrator,
                 mUdfpsHapticsSimulator,
                 mUdfpsShell,
-                Optional.of(mHbmProvider),
+                Optional.of(mDisplayModeProvider),
                 mKeyguardStateController,
                 mDisplayManager,
                 mHandler,
@@ -512,7 +512,7 @@
         final float expectedMajor = touchMajor / scaleFactor;
 
         // Configure UdfpsView to accept the ACTION_DOWN event
-        when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
+        when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
         when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
 
         // Show the overlay.
@@ -590,7 +590,7 @@
     @Test
     public void fingerDown() throws RemoteException {
         // Configure UdfpsView to accept the ACTION_DOWN event
-        when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
+        when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
         when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
 
@@ -617,12 +617,12 @@
         verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
                 anyFloat(), anyFloat());
         verify(mLatencyTracker).onActionStart(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
-        // AND illumination begins
-        verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
+        // AND display configuration begins
+        verify(mUdfpsView).configureDisplay(mOnDisplayConfiguredCaptor.capture());
         verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
         verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
-        // AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
-        mOnIlluminatedRunnableCaptor.getValue().run();
+        // AND onDisplayConfigured notifies FingerprintManager about onUiReady
+        mOnDisplayConfiguredCaptor.getValue().run();
         mBiometricsExecutor.runAllReady();
         InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker);
         inOrder.verify(mAlternateTouchProvider).onUiReady();
@@ -640,10 +640,10 @@
         // WHEN fingerprint is requested because of AOD interrupt
         mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
         mFgExecutor.runAllReady();
-        // THEN illumination begins
-        // AND onIlluminatedRunnable that notifies FingerprintManager is set
-        verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
-        mOnIlluminatedRunnableCaptor.getValue().run();
+        // THEN display configuration begins
+        // AND onDisplayConfigured notifies FingerprintManager about onUiReady
+        verify(mUdfpsView).configureDisplay(mOnDisplayConfiguredCaptor.capture());
+        mOnDisplayConfiguredCaptor.getValue().run();
         mBiometricsExecutor.runAllReady();
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID),
                 eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
@@ -661,11 +661,11 @@
         mFgExecutor.runAllReady();
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
-        when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
+        when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
         // WHEN it is cancelled
         mUdfpsController.onCancelUdfps();
-        // THEN the illumination is hidden
-        verify(mUdfpsView).stopIllumination();
+        // THEN the display is unconfigured
+        verify(mUdfpsView).unconfigureDisplay();
     }
 
     @Test
@@ -678,12 +678,12 @@
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
         mFgExecutor.runAllReady();
-        when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
+        when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
         // WHEN it times out
         mFgExecutor.advanceClockToNext();
         mFgExecutor.runAllReady();
-        // THEN the illumination is hidden
-        verify(mUdfpsView).stopIllumination();
+        // THEN the display is unconfigured
+        verify(mUdfpsView).unconfigureDisplay();
     }
 
     @Test
@@ -698,8 +698,8 @@
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
 
-        // THEN no illumination because screen is off
-        verify(mUdfpsView, never()).startIllumination(any());
+        // THEN display doesn't get configured because it's off
+        verify(mUdfpsView, never()).configureDisplay(any());
     }
 
     @Test
@@ -715,14 +715,14 @@
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false);
         mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
 
-        // THEN no illumination because screen is off
-        verify(mUdfpsView, never()).startIllumination(any());
+        // THEN display doesn't get configured because it's off
+        verify(mUdfpsView, never()).configureDisplay(any());
     }
 
     @Test
     public void playHapticOnTouchUdfpsArea_a11yTouchExplorationEnabled() throws RemoteException {
         // Configure UdfpsView to accept the ACTION_DOWN event
-        when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
+        when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
         when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
 
         // GIVEN that the overlay is showing and a11y touch exploration enabled
@@ -757,7 +757,7 @@
     @Test
     public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled() throws RemoteException {
         // Configure UdfpsView to accept the ACTION_DOWN event
-        when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
+        when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
         when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
 
         // GIVEN that the overlay is showing and a11y touch exploration NOT enabled
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 0327cfc..b78c063 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -36,13 +36,12 @@
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.Mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.nullable
 import org.mockito.Mockito.verify
-import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
 
 private const val SENSOR_X = 50
 private const val SENSOR_Y = 250
@@ -57,7 +56,7 @@
     var rule = MockitoJUnit.rule()
 
     @Mock
-    lateinit var hbmProvider: UdfpsHbmProvider
+    lateinit var hbmProvider: UdfpsDisplayModeProvider
     @Mock
     lateinit var animationViewController: UdfpsAnimationViewController<UdfpsAnimationView>
 
@@ -66,13 +65,11 @@
     @Before
     fun setup() {
         context.setTheme(R.style.Theme_AppCompat)
-        context.orCreateTestableResources.addOverride(
-            com.android.internal.R.integer.config_udfps_illumination_transition_ms, 0)
         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
         view.overlayParams = UdfpsOverlayParams(sensorBounds, 1920, 1080, 1f, Surface.ROTATION_0)
-        view.setHbmProvider(hbmProvider)
+        view.setUdfpsDisplayModeProvider(hbmProvider)
         ViewUtils.attachView(view)
     }
 
@@ -143,27 +140,27 @@
     @Test
     fun startAndStopIllumination() {
         val onDone: Runnable = mock()
-        view.startIllumination(onDone)
+        view.configureDisplay(onDone)
 
         val illuminator = withArgCaptor<Runnable> {
-            verify(hbmProvider).enableHbm(anyBoolean(), capture())
+            verify(hbmProvider).enable(capture())
         }
 
-        assertThat(view.isIlluminationRequested).isTrue()
-        verify(animationViewController).onIlluminationStarting()
-        verify(animationViewController, never()).onIlluminationStopped()
+        assertThat(view.isDisplayConfigured).isTrue()
+        verify(animationViewController).onDisplayConfiguring()
+        verify(animationViewController, never()).onDisplayUnconfigured()
         verify(onDone, never()).run()
 
         // fake illumination event
         illuminator.run()
         waitForLooper()
         verify(onDone).run()
-        verify(hbmProvider, never()).disableHbm(any())
+        verify(hbmProvider, never()).disable(any())
 
-        view.stopIllumination()
-        assertThat(view.isIlluminationRequested).isFalse()
-        verify(animationViewController).onIlluminationStopped()
-        verify(hbmProvider).disableHbm(nullable(Runnable::class.java))
+        view.unconfigureDisplay()
+        assertThat(view.isDisplayConfigured).isFalse()
+        verify(animationViewController).onDisplayUnconfigured()
+        verify(hbmProvider).disable(nullable(Runnable::class.java))
     }
 
     private fun waitForLooper() = TestableLooper.get(this).processAllMessages()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
index acb5622c..3e9cf1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
@@ -229,7 +229,10 @@
     }
 
     @Test
-    public void testAvoidDozingNotPulsing() {
+    public void testGestureWhenDozing() {
+        // We check the FalsingManager for taps during the transition to AoD (dozing=true,
+        // pulsing=false), so the FalsingCollector needs to continue to analyze events that occur
+        // while the device is dozing.
         MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
         MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
 
@@ -239,13 +242,13 @@
         mFalsingCollector.onTouchEvent(down);
         verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class));
 
-        // Up event would normally flush the up event, but doesn't.
+        // Up event flushes
         mFalsingCollector.onTouchEvent(up);
-        verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class));
+        verify(mFalsingDataProvider, times(2)).onMotionEvent(any(MotionEvent.class));
     }
 
     @Test
-    public void testAvoidDozingButPulsing() {
+    public void testGestureWhenPulsing() {
         MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
         MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java
new file mode 100644
index 0000000..08fe7c4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.clipboardoverlay;
+
+import android.content.ClipData;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.net.Uri;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class IntentCreatorTest extends SysuiTestCase {
+    private static final int EXTERNAL_INTENT_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK
+            | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION;
+
+    @Test
+    public void test_getTextEditorIntent() {
+        Intent intent = IntentCreator.getTextEditorIntent(getContext());
+        assertEquals(new ComponentName(getContext(), EditTextActivity.class),
+                intent.getComponent());
+        assertFlags(intent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+    }
+
+    @Test
+    public void test_getRemoteCopyIntent() {
+        getContext().getOrCreateTestableResources().addOverride(R.string.config_remoteCopyPackage,
+                "");
+
+        ClipData clipData = ClipData.newPlainText("Test", "Test Item");
+        Intent intent = IntentCreator.getRemoteCopyIntent(clipData, getContext());
+
+        assertEquals(null, intent.getComponent());
+        assertFlags(intent, EXTERNAL_INTENT_FLAGS);
+        assertEquals(clipData, intent.getClipData());
+
+        // Try again with a remote copy component
+        ComponentName fakeComponent = new ComponentName("com.android.remotecopy",
+                "com.android.remotecopy.RemoteCopyActivity");
+        getContext().getOrCreateTestableResources().addOverride(R.string.config_remoteCopyPackage,
+                fakeComponent.flattenToString());
+
+        intent = IntentCreator.getRemoteCopyIntent(clipData, getContext());
+        assertEquals(fakeComponent, intent.getComponent());
+    }
+
+    @Test
+    public void test_getImageEditIntent() {
+        getContext().getOrCreateTestableResources().addOverride(R.string.config_screenshotEditor,
+                "");
+        Uri fakeUri = Uri.parse("content://foo");
+        Intent intent = IntentCreator.getImageEditIntent(fakeUri, getContext());
+
+        assertEquals(Intent.ACTION_EDIT, intent.getAction());
+        assertEquals("image/*", intent.getType());
+        assertEquals(null, intent.getComponent());
+        assertFlags(intent, EXTERNAL_INTENT_FLAGS);
+
+        // try again with an editor component
+        ComponentName fakeComponent = new ComponentName("com.android.remotecopy",
+                "com.android.remotecopy.RemoteCopyActivity");
+        getContext().getOrCreateTestableResources().addOverride(R.string.config_screenshotEditor,
+                fakeComponent.flattenToString());
+        intent = IntentCreator.getImageEditIntent(fakeUri, getContext());
+        assertEquals(fakeComponent, intent.getComponent());
+    }
+
+    @Test
+    public void test_getShareIntent_plaintext() {
+        ClipData clipData = ClipData.newPlainText("Test", "Test Item");
+        Intent intent = IntentCreator.getShareIntent(clipData, getContext());
+
+        assertEquals(Intent.ACTION_CHOOSER, intent.getAction());
+        assertFlags(intent, EXTERNAL_INTENT_FLAGS);
+        Intent target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent.class);
+        assertEquals("Test Item", target.getStringExtra(Intent.EXTRA_TEXT));
+        assertEquals("text/plain", target.getType());
+    }
+
+    @Test
+    public void test_getShareIntent_html() {
+        ClipData clipData = ClipData.newHtmlText("Test", "Some HTML",
+                "<b>Some HTML</b>");
+        Intent intent = IntentCreator.getShareIntent(clipData, getContext());
+
+        assertEquals(Intent.ACTION_CHOOSER, intent.getAction());
+        assertFlags(intent, EXTERNAL_INTENT_FLAGS);
+        Intent target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent.class);
+        assertEquals("Some HTML", target.getStringExtra(Intent.EXTRA_TEXT));
+        assertEquals("text/plain", target.getType());
+    }
+
+    @Test
+    public void test_getShareIntent_image() {
+        Uri uri = Uri.parse("content://something");
+        ClipData clipData = new ClipData("Test", new String[]{"image/png"},
+                new ClipData.Item(uri));
+        Intent intent = IntentCreator.getShareIntent(clipData, getContext());
+
+        assertEquals(Intent.ACTION_CHOOSER, intent.getAction());
+        assertFlags(intent, EXTERNAL_INTENT_FLAGS);
+        Intent target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent.class);
+        assertEquals(uri, target.getData());
+        assertEquals("image/png", target.getType());
+    }
+
+    // Assert that the given flags are set
+    private void assertFlags(Intent intent, int flags) {
+        assertTrue((intent.getFlags() & flags) == flags);
+    }
+
+}
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 7f6b79b..4ebae98 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -310,7 +310,7 @@
     @Test
     public void testOnViewDetachedRemovesViews() {
         mController.onViewDetached();
-        verify(mView).removeAllStatusBarItemViews();
+        verify(mView).removeAllExtraStatusBarItemViews();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index eecbee5..a78c902 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -27,11 +27,11 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor.forClass
 import org.mockito.Mock
+import org.mockito.Mockito.`when`
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -60,7 +60,18 @@
     @Mock
     private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController.Stub
 
-    private lateinit var remoteAnimationTarget: RemoteAnimationTarget
+    private var surfaceControl1 = mock(SurfaceControl::class.java)
+    private var remoteTarget1 = RemoteAnimationTarget(
+            0 /* taskId */, 0, surfaceControl1, false, Rect(), Rect(), 0, Point(), Rect(), Rect(),
+            mock(WindowConfiguration::class.java), false, surfaceControl1, Rect(),
+            mock(ActivityManager.RunningTaskInfo::class.java), false)
+
+    private var surfaceControl2 = mock(SurfaceControl::class.java)
+    private var remoteTarget2 = RemoteAnimationTarget(
+            1 /* taskId */, 0, surfaceControl2, false, Rect(), Rect(), 0, Point(), Rect(), Rect(),
+            mock(WindowConfiguration::class.java), false, surfaceControl2, Rect(),
+            mock(ActivityManager.RunningTaskInfo::class.java), false)
+    private lateinit var remoteAnimationTargets: Array<RemoteAnimationTarget>
 
     @Before
     fun setUp() {
@@ -77,10 +88,7 @@
 
         // All of these fields are final, so we can't mock them, but are needed so that the surface
         // appear amount setter doesn't short circuit.
-        remoteAnimationTarget = RemoteAnimationTarget(
-            0, 0, null, false, Rect(), Rect(), 0, Point(), Rect(), Rect(),
-            mock(WindowConfiguration::class.java), false, mock(SurfaceControl::class.java), Rect(),
-            mock(ActivityManager.RunningTaskInfo::class.java), false)
+        remoteAnimationTargets = arrayOf(remoteTarget1)
 
         // Set the surface applier to our mock so that we can verify the arguments passed to it.
         // This applier does not have any side effects within the unlock animation controller, so
@@ -99,7 +107,7 @@
         `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
-            remoteAnimationTarget,
+            remoteAnimationTargets,
             0 /* startTime */,
             false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -130,7 +138,7 @@
         `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(false)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
-            remoteAnimationTarget,
+            remoteAnimationTargets,
             0 /* startTime */,
             false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -154,7 +162,7 @@
         `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
-            remoteAnimationTarget,
+            remoteAnimationTargets,
             0 /* startTime */,
             true /* requestedShowSurfaceBehindKeyguard */
         )
@@ -176,7 +184,7 @@
         `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
-            remoteAnimationTarget,
+            remoteAnimationTargets,
             0 /* startTime */,
             true /* requestedShowSurfaceBehindKeyguard */
         )
@@ -196,7 +204,7 @@
     @Test
     fun playCannedUnlockAnimation_ifDidNotRequestShowSurface() {
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
-            remoteAnimationTarget,
+            remoteAnimationTargets,
             0 /* startTime */,
             false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -210,7 +218,7 @@
         `when`(notificationShadeWindowController.isLaunchingActivity).thenReturn(true)
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
-            remoteAnimationTarget,
+            remoteAnimationTargets,
             0 /* startTime */,
             true /* requestedShowSurfaceBehindKeyguard */
         )
@@ -225,11 +233,46 @@
         keyguardUnlockAnimationController.willUnlockWithInWindowLauncherAnimations = true
 
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
-                remoteAnimationTarget,
+                remoteAnimationTargets,
                 0 /* startTime */,
                 false /* requestedShowSurfaceBehindKeyguard */
         )
 
         assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
     }
+
+    /**
+     * If we are not wake and unlocking, we expect the unlock animation to play normally.
+     */
+    @Test
+    fun surfaceAnimation_multipleTargets() {
+        keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+                arrayOf(remoteTarget1, remoteTarget2),
+                0 /* startTime */,
+                false /* requestedShowSurfaceBehindKeyguard */
+        )
+
+        // Set appear to 50%, we'll just verify that we're not applying the identity matrix which
+        // means an animation is in progress.
+        keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(0.5f)
+
+        val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java)
+        verify(surfaceTransactionApplier, times(2)).scheduleApply(captor.capture())
+
+        val allParams = captor.allValues
+
+        val remainingTargets = mutableListOf(surfaceControl1, surfaceControl2)
+        allParams.forEach { params ->
+            assertTrue(!params.matrix.isIdentity)
+            remainingTargets.remove(params.surface)
+        }
+
+        // Make sure we called applyParams with each of the surface controls once. The order does
+        // not matter, so don't explicitly check for that.
+        assertTrue(remainingTargets.isEmpty())
+
+        // Since the animation is running, we should not have finished the remote animation.
+        verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished(
+                false /* cancelled */)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
index 5a50a9f..5dd1cfc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.animation.TransitionLayout
@@ -78,6 +79,7 @@
     @Mock lateinit var mediaViewController: MediaViewController
     @Mock lateinit var smartspaceMediaData: SmartspaceMediaData
     @Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener>
+    @Captor lateinit var visualStabilityCallback: ArgumentCaptor<OnReorderingAllowedListener>
 
     private val clock = FakeSystemClock()
     private lateinit var mediaCarouselController: MediaCarouselController
@@ -102,6 +104,8 @@
             debugLogger
         )
         verify(mediaDataManager).addListener(capture(listener))
+        verify(visualStabilityProvider)
+            .addPersistentReorderingAllowedListener(capture(visualStabilityCallback))
         whenever(mediaControlPanelFactory.get()).thenReturn(mediaPlayer)
         whenever(mediaPlayer.mediaViewController).thenReturn(mediaViewController)
         whenever(mediaDataManager.smartspaceMediaData).thenReturn(smartspaceMediaData)
@@ -374,4 +378,28 @@
         playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
         assertEquals(playerIndex, 0)
     }
+
+    @Test
+    fun testRecommendationRemovedWhileNotVisible_updateHostVisibility() {
+        var result = false
+        mediaCarouselController.updateHostVisibility = { result = true }
+
+        whenever(visualStabilityProvider.isReorderingAllowed).thenReturn(true)
+        listener.value.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY, false)
+
+        assertEquals(true, result)
+    }
+
+    @Test
+    fun testRecommendationRemovedWhileVisible_thenReorders_updateHostVisibility() {
+        var result = false
+        mediaCarouselController.updateHostVisibility = { result = true }
+
+        whenever(visualStabilityProvider.isReorderingAllowed).thenReturn(false)
+        listener.value.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY, false)
+        assertEquals(false, result)
+
+        visualStabilityCallback.value.onReorderingAllowed()
+        assertEquals(true, result)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index bef4695..7de5719 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -591,14 +591,20 @@
 
     @Test
     fun bindAlbumView_bitmapInLaterStates_setAfterExecutors() {
-        val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
-        val canvas = Canvas(bmp)
-        canvas.drawColor(Color.RED)
-        val albumArt = Icon.createWithBitmap(bmp)
+        val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+        val redCanvas = Canvas(redBmp)
+        redCanvas.drawColor(Color.RED)
+        val redArt = Icon.createWithBitmap(redBmp)
+
+        val greenBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+        val greenCanvas = Canvas(greenBmp)
+        greenCanvas.drawColor(Color.GREEN)
+        val greenArt = Icon.createWithBitmap(greenBmp)
 
         val state0 = mediaData.copy(artwork = null)
-        val state1 = mediaData.copy(artwork = albumArt)
-        val state2 = mediaData.copy(artwork = albumArt)
+        val state1 = mediaData.copy(artwork = redArt)
+        val state2 = mediaData.copy(artwork = redArt)
+        val state3 = mediaData.copy(artwork = greenArt)
         player.attachPlayer(viewHolder)
 
         // First binding sets (empty) drawable
@@ -627,6 +633,12 @@
         bgExecutor.runAllReady()
         mainExecutor.runAllReady()
         verify(albumView, times(2)).setImageDrawable(any(Drawable::class.java))
+
+        // Fourth binding to new image runs transition due to color scheme change
+        player.bindPlayer(state3, PACKAGE)
+        bgExecutor.runAllReady()
+        mainExecutor.runAllReady()
+        verify(albumView, times(3)).setImageDrawable(any(Drawable::class.java))
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
index d95e5c4..1078cda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
@@ -23,11 +23,11 @@
 import com.android.systemui.log.LogBufferFactory
 import com.android.systemui.log.LogcatEchoTracker
 import com.google.common.truth.Truth.assertThat
+import java.io.PrintWriter
+import java.io.StringWriter
 import org.junit.Before
 import org.junit.Test
 import org.mockito.Mockito.mock
-import java.io.PrintWriter
-import java.io.StringWriter
 
 @SmallTest
 class MediaTttLoggerTest : SysuiTestCase() {
@@ -43,32 +43,46 @@
     }
 
     @Test
-    fun logStateChange_bufferHasDeviceTypeTagAndStateNameAndId() {
+    fun logStateChange_bufferHasDeviceTypeTagAndParamInfo() {
         val stateName = "test state name"
         val id = "test id"
+        val packageName = "this.is.a.package"
 
-        logger.logStateChange(stateName, id)
+        logger.logStateChange(stateName, id, packageName)
 
-        val stringWriter = StringWriter()
-        buffer.dump(PrintWriter(stringWriter), tailLength = 0)
-        val actualString = stringWriter.toString()
-
+        val actualString = getStringFromBuffer()
         assertThat(actualString).contains(DEVICE_TYPE_TAG)
         assertThat(actualString).contains(stateName)
         assertThat(actualString).contains(id)
+        assertThat(actualString).contains(packageName)
     }
 
     @Test
-    fun logChipRemoval_bufferHasDeviceTypeAndReason() {
-        val reason = "test reason"
-        logger.logChipRemoval(reason)
+    fun logPackageNotFound_bufferHasPackageName() {
+        val packageName = "this.is.a.package"
 
+        logger.logPackageNotFound(packageName)
+
+        val actualString = getStringFromBuffer()
+        assertThat(actualString).contains(packageName)
+    }
+
+    @Test
+    fun logRemovalBypass_bufferHasReasons() {
+        val removalReason = "fakeRemovalReason"
+        val bypassReason = "fakeBypassReason"
+
+        logger.logRemovalBypass(removalReason, bypassReason)
+
+        val actualString = getStringFromBuffer()
+        assertThat(actualString).contains(removalReason)
+        assertThat(actualString).contains(bypassReason)
+    }
+
+    private fun getStringFromBuffer(): String {
         val stringWriter = StringWriter()
         buffer.dump(PrintWriter(stringWriter), tailLength = 0)
-        val actualString = stringWriter.toString()
-
-        assertThat(actualString).contains(DEVICE_TYPE_TAG)
-        assertThat(actualString).contains(reason)
+        return stringWriter.toString()
     }
 }
 
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
new file mode 100644
index 0000000..37f6434
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.taptotransfer.common
+
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.graphics.drawable.Drawable
+import android.widget.FrameLayout
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.CachingIconView
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+class MediaTttUtilsTest : SysuiTestCase() {
+
+    private lateinit var appIconFromPackageName: Drawable
+    @Mock private lateinit var packageManager: PackageManager
+    @Mock private lateinit var applicationInfo: ApplicationInfo
+    @Mock private lateinit var logger: MediaTttLogger
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        // Set up our package manager to give valid information for [PACKAGE_NAME] only
+        appIconFromPackageName = context.getDrawable(R.drawable.ic_cake)!!
+        whenever(packageManager.getApplicationIcon(PACKAGE_NAME)).thenReturn(appIconFromPackageName)
+        whenever(applicationInfo.loadLabel(packageManager)).thenReturn(APP_NAME)
+        whenever(
+                packageManager.getApplicationInfo(any(), any<PackageManager.ApplicationInfoFlags>())
+            )
+            .thenThrow(PackageManager.NameNotFoundException())
+        whenever(
+                packageManager.getApplicationInfo(
+                    Mockito.eq(PACKAGE_NAME),
+                    any<PackageManager.ApplicationInfoFlags>()
+                )
+            )
+            .thenReturn(applicationInfo)
+        context.setMockPackageManager(packageManager)
+    }
+
+    @Test
+    fun getIconInfoFromPackageName_nullPackageName_returnsDefault() {
+        val iconInfo =
+            MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = null, logger)
+
+        assertThat(iconInfo.isAppIcon).isFalse()
+        assertThat(iconInfo.contentDescription)
+            .isEqualTo(context.getString(R.string.media_output_dialog_unknown_launch_app_name))
+    }
+
+    @Test
+    fun getIconInfoFromPackageName_invalidPackageName_returnsDefault() {
+        val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, "fakePackageName", logger)
+
+        assertThat(iconInfo.isAppIcon).isFalse()
+        assertThat(iconInfo.contentDescription)
+            .isEqualTo(context.getString(R.string.media_output_dialog_unknown_launch_app_name))
+    }
+
+    @Test
+    fun getIconInfoFromPackageName_validPackageName_returnsAppInfo() {
+        val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME, logger)
+
+        assertThat(iconInfo.isAppIcon).isTrue()
+        assertThat(iconInfo.drawable).isEqualTo(appIconFromPackageName)
+        assertThat(iconInfo.contentDescription).isEqualTo(APP_NAME)
+    }
+
+    @Test
+    fun setIcon_viewHasIconAndContentDescription() {
+        val view = CachingIconView(context)
+        val icon = context.getDrawable(R.drawable.ic_celebration)!!
+        val contentDescription = "Happy birthday!"
+
+        MediaTttUtils.setIcon(view, icon, contentDescription)
+
+        assertThat(view.drawable).isEqualTo(icon)
+        assertThat(view.contentDescription).isEqualTo(contentDescription)
+    }
+
+    @Test
+    fun setIcon_iconSizeNull_viewSizeDoesNotChange() {
+        val view = CachingIconView(context)
+        val size = 456
+        view.layoutParams = FrameLayout.LayoutParams(size, size)
+
+        MediaTttUtils.setIcon(view, context.getDrawable(R.drawable.ic_cake)!!, "desc")
+
+        assertThat(view.layoutParams.width).isEqualTo(size)
+        assertThat(view.layoutParams.height).isEqualTo(size)
+    }
+
+    @Test
+    fun setIcon_iconSizeProvided_viewSizeUpdates() {
+        val view = CachingIconView(context)
+        val size = 456
+        view.layoutParams = FrameLayout.LayoutParams(size, size)
+
+        val newSize = 40
+        MediaTttUtils.setIcon(
+            view,
+            context.getDrawable(R.drawable.ic_cake)!!,
+            "desc",
+            iconSize = newSize
+        )
+
+        assertThat(view.layoutParams.width).isEqualTo(newSize)
+        assertThat(view.layoutParams.height).isEqualTo(newSize)
+    }
+}
+
+private const val PACKAGE_NAME = "com.android.systemui"
+private const val APP_NAME = "Fake App Name"
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 e7b4593..d41ad48 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
@@ -173,37 +173,72 @@
             null
         )
 
-        verify(logger).logStateChange(any(), any())
+        verify(logger).logStateChange(any(), any(), any())
     }
 
     @Test
-    fun setIcon_isAppIcon_usesAppIconSize() {
-        controllerReceiver.displayView(getChipReceiverInfo())
+    fun updateView_noOverrides_usesInfoFromAppIcon() {
+        controllerReceiver.displayView(
+            ChipReceiverInfo(routeInfo, appIconDrawableOverride = null, appNameOverride = null)
+        )
+
+        val view = getChipView()
+        assertThat(view.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
+        assertThat(view.getAppIconView().contentDescription).isEqualTo(APP_NAME)
+    }
+
+    @Test
+    fun updateView_appIconOverride_usesOverride() {
+        val drawableOverride = context.getDrawable(R.drawable.ic_celebration)!!
+
+        controllerReceiver.displayView(
+            ChipReceiverInfo(routeInfo, drawableOverride, appNameOverride = null)
+        )
+
+        val view = getChipView()
+        assertThat(view.getAppIconView().drawable).isEqualTo(drawableOverride)
+    }
+
+    @Test
+    fun updateView_appNameOverride_usesOverride() {
+        val appNameOverride = "Sweet New App"
+
+        controllerReceiver.displayView(
+            ChipReceiverInfo(routeInfo, appIconDrawableOverride = null, appNameOverride)
+        )
+
+        val view = getChipView()
+        assertThat(view.getAppIconView().contentDescription).isEqualTo(appNameOverride)
+    }
+
+    @Test
+    fun updateView_isAppIcon_usesAppIconSize() {
+        controllerReceiver.displayView(getChipReceiverInfo(packageName = PACKAGE_NAME))
         val chipView = getChipView()
 
-        controllerReceiver.setIcon(chipView, PACKAGE_NAME)
         chipView.measure(
             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
         )
 
-        val expectedSize = controllerReceiver.getIconSize(isAppIcon = true)
+        val expectedSize =
+            context.resources.getDimensionPixelSize(R.dimen.media_ttt_icon_size_receiver)
         assertThat(chipView.getAppIconView().measuredWidth).isEqualTo(expectedSize)
         assertThat(chipView.getAppIconView().measuredHeight).isEqualTo(expectedSize)
     }
 
     @Test
-    fun setIcon_notAppIcon_usesGenericIconSize() {
-        controllerReceiver.displayView(getChipReceiverInfo())
+    fun updateView_notAppIcon_usesGenericIconSize() {
+        controllerReceiver.displayView(getChipReceiverInfo(packageName = null))
         val chipView = getChipView()
 
-        controllerReceiver.setIcon(chipView, appPackageName = null)
         chipView.measure(
             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
         )
 
-        val expectedSize = controllerReceiver.getIconSize(isAppIcon = false)
+        val expectedSize =
+            context.resources.getDimensionPixelSize(R.dimen.media_ttt_generic_icon_size_receiver)
         assertThat(chipView.getAppIconView().measuredWidth).isEqualTo(expectedSize)
         assertThat(chipView.getAppIconView().measuredHeight).isEqualTo(expectedSize)
     }
@@ -226,8 +261,13 @@
         return viewCaptor.value as ViewGroup
     }
 
-    private fun getChipReceiverInfo(): ChipReceiverInfo =
-        ChipReceiverInfo(routeInfo, null, null)
+    private fun getChipReceiverInfo(packageName: String?): ChipReceiverInfo {
+        val routeInfo = MediaRoute2Info.Builder("id", "Test route name")
+            .addFeature("feature")
+            .setClientPackageName(packageName)
+            .build()
+        return ChipReceiverInfo(routeInfo, null, null)
+    }
 
     private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
index 52b6eed..ff0faf9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
@@ -299,7 +299,7 @@
             null
         )
 
-        verify(logger).logStateChange(any(), any())
+        verify(logger).logStateChange(any(), any(), any())
     }
 
     @Test
@@ -587,15 +587,29 @@
         fakeExecutor.runAllReady()
 
         verify(windowManager, never()).removeView(any())
+        verify(logger).logRemovalBypass(any(), any())
     }
 
     @Test
-    fun transferToReceiverTriggeredThenFarFromReceiver_eventuallyTimesOut() {
-        val state = transferToReceiverTriggered()
-        controllerSender.displayView(state)
-        fakeClock.advanceTime(1000L)
-        controllerSender.removeView("fakeRemovalReason")
+    fun transferToReceiverTriggeredThenFarFromReceiver_viewStillDisplayed() {
+        controllerSender.displayView(transferToReceiverTriggered())
 
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+            routeInfo,
+            null
+        )
+        fakeExecutor.runAllReady()
+
+        verify(windowManager, never()).removeView(any())
+        verify(logger).logRemovalBypass(any(), any())
+    }
+
+    @Test
+    fun transferToReceiverTriggeredThenRemoveView_eventuallyTimesOut() {
+        controllerSender.displayView(transferToReceiverTriggered())
+
+        controllerSender.removeView("fakeRemovalReason")
         fakeClock.advanceTime(TIMEOUT + 1L)
 
         verify(windowManager).removeView(any())
@@ -610,20 +624,106 @@
         fakeExecutor.runAllReady()
 
         verify(windowManager, never()).removeView(any())
+        verify(logger).logRemovalBypass(any(), any())
     }
 
     @Test
-    fun transferToThisDeviceTriggeredThenFarFromReceiver_eventuallyTimesOut() {
-        val state = transferToThisDeviceTriggered()
-        controllerSender.displayView(state)
-        fakeClock.advanceTime(1000L)
-        controllerSender.removeView("fakeRemovalReason")
+    fun transferToThisDeviceTriggeredThenRemoveView_eventuallyTimesOut() {
+        controllerSender.displayView(transferToThisDeviceTriggered())
 
+        controllerSender.removeView("fakeRemovalReason")
         fakeClock.advanceTime(TIMEOUT + 1L)
 
         verify(windowManager).removeView(any())
     }
 
+    @Test
+    fun transferToThisDeviceTriggeredThenFarFromReceiver_viewStillDisplayed() {
+        controllerSender.displayView(transferToThisDeviceTriggered())
+
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+            routeInfo,
+            null
+        )
+        fakeExecutor.runAllReady()
+
+        verify(windowManager, never()).removeView(any())
+        verify(logger).logRemovalBypass(any(), any())
+    }
+
+    @Test
+    fun transferToReceiverSucceededThenRemoveView_viewStillDisplayed() {
+        controllerSender.displayView(transferToReceiverSucceeded())
+
+        controllerSender.removeView("fakeRemovalReason")
+        fakeExecutor.runAllReady()
+
+        verify(windowManager, never()).removeView(any())
+        verify(logger).logRemovalBypass(any(), any())
+    }
+
+    @Test
+    fun transferToReceiverSucceededThenRemoveView_eventuallyTimesOut() {
+        controllerSender.displayView(transferToReceiverSucceeded())
+
+        controllerSender.removeView("fakeRemovalReason")
+        fakeClock.advanceTime(TIMEOUT + 1L)
+
+        verify(windowManager).removeView(any())
+    }
+
+    @Test
+    fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayed() {
+        controllerSender.displayView(transferToReceiverSucceeded())
+
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+            routeInfo,
+            null
+        )
+        fakeExecutor.runAllReady()
+
+        verify(windowManager, never()).removeView(any())
+        verify(logger).logRemovalBypass(any(), any())
+    }
+
+    @Test
+    fun transferToThisDeviceSucceededThenRemoveView_viewStillDisplayed() {
+        controllerSender.displayView(transferToThisDeviceSucceeded())
+
+        controllerSender.removeView("fakeRemovalReason")
+        fakeExecutor.runAllReady()
+
+        verify(windowManager, never()).removeView(any())
+        verify(logger).logRemovalBypass(any(), any())
+    }
+
+    @Test
+    fun transferToThisDeviceSucceededThenRemoveView_eventuallyTimesOut() {
+        controllerSender.displayView(transferToThisDeviceSucceeded())
+
+        controllerSender.removeView("fakeRemovalReason")
+        fakeClock.advanceTime(TIMEOUT + 1L)
+
+        verify(windowManager).removeView(any())
+    }
+
+    @Test
+    fun transferToThisDeviceSucceededThenFarFromReceiver_viewStillDisplayed() {
+        controllerSender.displayView(transferToThisDeviceSucceeded())
+
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+            routeInfo,
+            null
+        )
+        fakeExecutor.runAllReady()
+
+        verify(windowManager, never()).removeView(any())
+        verify(logger).logRemovalBypass(any(), any())
+    }
+
     private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
 
     private fun ViewGroup.getChipText(): String =
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 bf682a8..3fd2501 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
@@ -33,12 +33,15 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.util.settings.FakeSettings;
 import com.android.systemui.util.settings.SecureSettings;
@@ -54,6 +57,8 @@
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class ColorInversionTileTest extends SysuiTestCase {
+    private static final Integer COLOR_INVERSION_DISABLED = 0;
+    private static final Integer COLOR_INVERSION_ENABLED = 1;
 
     @Mock
     private QSTileHost mHost;
@@ -113,4 +118,24 @@
         assertThat(IntentCaptor.getValue().getAction()).isEqualTo(
                 Settings.ACTION_COLOR_INVERSION_SETTINGS);
     }
+
+    @Test
+    public void testIcon_whenColorInversionDisabled_isOffState() {
+        QSTile.BooleanState state = new QSTile.BooleanState();
+
+        mTile.handleUpdateState(state, COLOR_INVERSION_DISABLED);
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_invert_colors_icon_off));
+    }
+
+    @Test
+    public void testIcon_whenColorInversionEnabled_isOnState() {
+        QSTile.BooleanState state = new QSTile.BooleanState();
+
+        mTile.handleUpdateState(state, COLOR_INVERSION_ENABLED);
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_invert_colors_icon_on));
+    }
 }
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
new file mode 100644
index 0000000..ce62f2d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+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.SysuiTestCase
+import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.DataSaverController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class DataSaverTileTest : SysuiTestCase() {
+
+    @Mock private lateinit var mHost: QSHost
+    @Mock private lateinit var mMetricsLogger: MetricsLogger
+    @Mock private lateinit var mStatusBarStateController: StatusBarStateController
+    @Mock private lateinit var mActivityStarter: ActivityStarter
+    @Mock private lateinit var mQsLogger: QSLogger
+    private val falsingManager = FalsingManagerFake()
+    @Mock private lateinit var statusBarStateController: StatusBarStateController
+    @Mock private lateinit var activityStarter: ActivityStarter
+    @Mock private lateinit var dataSaverController: DataSaverController
+    @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
+
+    private val uiEventLogger = UiEventLoggerFake()
+    private lateinit var testableLooper: TestableLooper
+    private lateinit var tile: DataSaverTile
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+
+        Mockito.`when`(mHost.context).thenReturn(mContext)
+        Mockito.`when`(mHost.uiEventLogger).thenReturn(uiEventLogger)
+
+        tile =
+            DataSaverTile(
+                mHost,
+                testableLooper.looper,
+                Handler(testableLooper.looper),
+                falsingManager,
+                mMetricsLogger,
+                statusBarStateController,
+                activityStarter,
+                mQsLogger,
+                dataSaverController,
+                dialogLaunchAnimator
+            )
+    }
+
+    @Test
+    fun testIcon_whenDataSaverEnabled_isOnState() {
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, true)
+
+        assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_data_saver_icon_on))
+    }
+
+    @Test
+    fun testIcon_whenDataSaverDisabled_isOffState() {
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, false)
+
+        assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_data_saver_icon_off))
+    }
+}
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
new file mode 100644
index 0000000..d0f851b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
@@ -0,0 +1,108 @@
+package com.android.systemui.qs.tiles
+
+import android.content.Context
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+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.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.FlashlightController
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class FlashlightTileTest : SysuiTestCase() {
+
+    @Mock private lateinit var mockContext: Context
+
+    @Mock private lateinit var qsLogger: QSLogger
+
+    @Mock private lateinit var qsHost: QSTileHost
+
+    @Mock private lateinit var metricsLogger: MetricsLogger
+
+    @Mock private lateinit var statusBarStateController: StatusBarStateController
+
+    @Mock private lateinit var activityStarter: ActivityStarter
+
+    @Mock private lateinit var flashlightController: FlashlightController
+
+    private val uiEventLogger = UiEventLoggerFake()
+    private val falsingManager = FalsingManagerFake()
+    private lateinit var testableLooper: TestableLooper
+    private lateinit var tile: FlashlightTile
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+
+        Mockito.`when`(qsHost.context).thenReturn(mockContext)
+        Mockito.`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+
+        tile =
+            FlashlightTile(
+                qsHost,
+                testableLooper.looper,
+                Handler(testableLooper.looper),
+                falsingManager,
+                metricsLogger,
+                statusBarStateController,
+                activityStarter,
+                qsLogger,
+                flashlightController
+            )
+    }
+
+    @Test
+    fun testIcon_whenFlashlightEnabled_isOnState() {
+        Mockito.`when`(flashlightController.isAvailable).thenReturn(true)
+        Mockito.`when`(flashlightController.isEnabled).thenReturn(true)
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        Truth.assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_flashlight_icon_on))
+    }
+
+    @Test
+    fun testIcon_whenFlashlightDisabled_isOffState() {
+        Mockito.`when`(flashlightController.isAvailable).thenReturn(true)
+        Mockito.`when`(flashlightController.isEnabled).thenReturn(false)
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        Truth.assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_flashlight_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenFlashlightUnavailable_isOffState() {
+        Mockito.`when`(flashlightController.isAvailable).thenReturn(false)
+        val state = QSTile.BooleanState()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        Truth.assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_flashlight_icon_off))
+    }
+}
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
new file mode 100644
index 0000000..188c3a3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.hardware.display.ColorDisplayManager
+import android.hardware.display.NightDisplayListener
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.dagger.NightDisplayListenerModule
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.LocationController
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class NightDisplayTileTest : SysuiTestCase() {
+    @Mock
+    private lateinit var mHost: QSHost
+
+    @Mock
+    private lateinit var mMetricsLogger: MetricsLogger
+
+    @Mock
+    private lateinit var mStatusBarStateController: StatusBarStateController
+
+    @Mock
+    private lateinit var mActivityStarter: ActivityStarter
+
+    @Mock
+    private lateinit var mQsLogger: QSLogger
+
+    @Mock
+    private lateinit var mLocationController: LocationController
+
+    @Mock
+    private lateinit var mColorDisplayManager: ColorDisplayManager
+
+    @Mock
+    private lateinit var mNightDisplayListenerBuilder: NightDisplayListenerModule.Builder
+
+    @Mock
+    private lateinit var mNightDisplayListener: NightDisplayListener
+
+    private lateinit var mTestableLooper: TestableLooper
+    private lateinit var mTile: NightDisplayTile
+
+    private val mUiEventLogger: UiEventLogger = UiEventLoggerFake()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        mTestableLooper = TestableLooper.get(this)
+        whenever(mHost.context).thenReturn(mContext)
+        whenever(mHost.uiEventLogger).thenReturn(mUiEventLogger)
+        whenever(mHost.userContext).thenReturn(mContext)
+        whenever(mNightDisplayListenerBuilder.setUser(anyInt())).thenReturn(
+            mNightDisplayListenerBuilder
+        )
+        whenever(mNightDisplayListenerBuilder.build()).thenReturn(mNightDisplayListener)
+
+        mTile = NightDisplayTile(
+            mHost,
+            mTestableLooper.looper,
+            Handler(mTestableLooper.looper),
+            FalsingManagerFake(),
+            mMetricsLogger,
+            mStatusBarStateController,
+            mActivityStarter,
+            mQsLogger,
+            mLocationController,
+            mColorDisplayManager,
+            mNightDisplayListenerBuilder
+        )
+    }
+
+    @Test
+    fun testIcon_whenDisabled_showsOffState() {
+        whenever(mColorDisplayManager.isNightDisplayActivated).thenReturn(false)
+        val state = QSTile.BooleanState()
+
+        mTile.handleUpdateState(state, /* arg= */ null)
+
+        Truth.assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_nightlight_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenEnabled_showsOnState() {
+        whenever(mColorDisplayManager.isNightDisplayActivated).thenReturn(true)
+        val state = QSTile.BooleanState()
+
+        mTile.handleUpdateState(state, /* arg= */ null)
+
+        Truth.assertThat(state.icon)
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_nightlight_icon_on))
+    }
+}
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 9eb688d..8601d6c 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,13 +32,16 @@
 
 import com.android.internal.R;
 import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R.drawable;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.ReduceBrightColorsController;
 import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.settings.UserTracker;
 
 import org.junit.Before;
@@ -130,4 +133,26 @@
                 .setReduceBrightColorsActivated(eq(true));
     }
 
+    @Test
+    public void testIcon_whenTileEnabled_isOnState() {
+        when(mReduceBrightColorsController.isReduceBrightColorsActivated()).thenReturn(true);
+        mTile.refreshState();
+        QSTile.BooleanState state = new QSTile.BooleanState();
+
+        mTile.handleUpdateState(state, /* arg= */ null);
+
+        assertEquals(state.icon, QSTileImpl.ResourceIcon.get(drawable.qs_extra_dim_icon_on));
+    }
+
+    @Test
+    public void testIcon_whenTileDisabled_isOffState() {
+        when(mReduceBrightColorsController.isReduceBrightColorsActivated()).thenReturn(false);
+        mTile.refreshState();
+        QSTile.BooleanState state = new QSTile.BooleanState();
+
+        mTile.handleUpdateState(state, /* arg= */ null);
+
+        assertEquals(state.icon, QSTileImpl.ResourceIcon.get(drawable.qs_extra_dim_icon_off));
+    }
+
 }
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 e6bd396..30debdf 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
@@ -41,9 +41,11 @@
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.screenrecord.RecordingController;
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -229,4 +231,38 @@
 
         assertFalse(mTile.getState().forceExpandIcon);
     }
+
+    @Test
+    public void testIcon_whenRecording_isOnState() {
+        when(mController.isStarting()).thenReturn(false);
+        when(mController.isRecording()).thenReturn(true);
+        QSTile.BooleanState state = new QSTile.BooleanState();
+
+        mTile.handleUpdateState(state, /* arg= */ null);
+
+        assertEquals(state.icon, QSTileImpl.ResourceIcon.get(R.drawable.qs_screen_record_icon_on));
+    }
+
+    @Test
+    public void testIcon_whenStarting_isOnState() {
+        when(mController.isStarting()).thenReturn(true);
+        when(mController.isRecording()).thenReturn(false);
+        QSTile.BooleanState state = new QSTile.BooleanState();
+
+        mTile.handleUpdateState(state, /* arg= */ null);
+
+        assertEquals(state.icon, QSTileImpl.ResourceIcon.get(R.drawable.qs_screen_record_icon_on));
+    }
+
+    @Test
+    public void testIcon_whenRecordingOff_isOffState() {
+        when(mController.isStarting()).thenReturn(false);
+        when(mController.isRecording()).thenReturn(false);
+        QSTile.BooleanState state = new QSTile.BooleanState();
+
+        mTile.handleUpdateState(state, /* arg= */ null);
+
+        assertEquals(state.icon, QSTileImpl.ResourceIcon.get(R.drawable.qs_screen_record_icon_off));
+    }
+
 }
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 ea70c26..0c070da 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
@@ -21,9 +21,9 @@
 import android.content.res.Configuration
 import android.content.res.Resources
 import android.os.Handler
-import android.test.suitebuilder.annotation.SmallTest
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.R
@@ -51,28 +51,17 @@
 @SmallTest
 class UiModeNightTileTest : SysuiTestCase() {
 
-    @Mock
-    private lateinit var mockContext: Context
-    @Mock
-    private lateinit var uiModeManager: UiModeManager
-    @Mock
-    private lateinit var resources: Resources
-    @Mock
-    private lateinit var qsLogger: QSLogger
-    @Mock
-    private lateinit var qsHost: QSTileHost
-    @Mock
-    private lateinit var metricsLogger: MetricsLogger
-    @Mock
-    private lateinit var statusBarStateController: StatusBarStateController
-    @Mock
-    private lateinit var activityStarter: ActivityStarter
-    @Mock
-    private lateinit var configurationController: ConfigurationController
-    @Mock
-    private lateinit var batteryController: BatteryController
-    @Mock
-    private lateinit var locationController: LocationController
+    @Mock private lateinit var mockContext: Context
+    @Mock private lateinit var uiModeManager: UiModeManager
+    @Mock private lateinit var resources: Resources
+    @Mock private lateinit var qsLogger: QSLogger
+    @Mock private lateinit var qsHost: QSTileHost
+    @Mock private lateinit var metricsLogger: MetricsLogger
+    @Mock private lateinit var statusBarStateController: StatusBarStateController
+    @Mock private lateinit var activityStarter: ActivityStarter
+    @Mock private lateinit var configurationController: ConfigurationController
+    @Mock private lateinit var batteryController: BatteryController
+    @Mock private lateinit var locationController: LocationController
 
     private val uiEventLogger = UiEventLoggerFake()
     private val falsingManager = FalsingManagerFake()
@@ -85,7 +74,7 @@
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
         configuration = Configuration()
-        mContext.addMockSystemService(Context.UI_MODE_SERVICE, uiModeManager)
+        mContext.addMockSystemService(UiModeManager::class.java, uiModeManager)
 
         `when`(qsHost.context).thenReturn(mockContext)
         `when`(qsHost.userContext).thenReturn(mContext)
@@ -93,7 +82,8 @@
         `when`(resources.configuration).thenReturn(configuration)
         `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
 
-        tile = UiModeNightTile(
+        tile =
+            UiModeNightTile(
                 qsHost,
                 testableLooper.looper,
                 Handler(testableLooper.looper),
@@ -104,7 +94,8 @@
                 qsLogger,
                 configurationController,
                 batteryController,
-                locationController)
+                locationController
+            )
     }
 
     @Test
@@ -115,7 +106,7 @@
         tile.handleUpdateState(state, /* arg= */ null)
 
         assertThat(state.icon)
-                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_light_dark_theme_icon_on))
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_light_dark_theme_icon_on))
     }
 
     @Test
@@ -126,7 +117,7 @@
         tile.handleUpdateState(state, /* arg= */ null)
 
         assertThat(state.icon)
-                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_light_dark_theme_icon_off))
+            .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_light_dark_theme_icon_off))
     }
 
     private fun setNightModeOn() {
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 d09a5a1..f922475 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
@@ -143,6 +143,12 @@
     }
 
     @Test
+    public void createInternetDialog_setAccessibilityPaneTitleToQuickSettings() {
+        assertThat(mDialogView.getAccessibilityPaneTitle())
+                .isEqualTo(mContext.getText(R.string.accessibility_desc_quick_settings));
+    }
+
+    @Test
     public void hideWifiViews_WifiViewsGone() {
         mInternetDialog.hideWifiViews();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt
index 00f3808..5a4bafc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt
@@ -23,7 +23,7 @@
 import android.os.IBinder
 import android.testing.AndroidTestingRunner
 import android.view.Display
-import android.view.SurfaceControl.ScreenshotHardwareBuffer
+import android.window.ScreenCapture.ScreenshotHardwareBuffer
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
@@ -84,7 +84,12 @@
             this.width = width
             this.height = height
             this.crop = crop
-            return ScreenshotHardwareBuffer(null, null, false, false)
+            return ScreenshotHardwareBuffer(
+                null,
+                null,
+                false,
+                false
+            )
         }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
index 6ce9cff..002ef29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
@@ -34,6 +34,7 @@
 import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN
 import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
 import android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION
+import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.util.ScreenshotHelper
 import com.android.internal.util.ScreenshotHelper.ScreenshotRequest
@@ -65,6 +66,7 @@
 private const val TASK_ID = 1
 
 @RunWith(AndroidTestingRunner::class)
+@SmallTest
 class TakeScreenshotServiceTest : SysuiTestCase() {
 
     private val application = mock<Application>()
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 e730713..b40d5ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -1022,7 +1022,7 @@
         FalsingManager.FalsingTapListener listener = getFalsingTapListener();
         mStatusBarStateController.setState(KEYGUARD);
 
-        listener.onDoubleTapRequired();
+        listener.onAdditionalTapRequired();
 
         verify(mKeyguardIndicationController).showTransientIndication(anyInt());
     }
@@ -1032,7 +1032,7 @@
         FalsingManager.FalsingTapListener listener = getFalsingTapListener();
         mStatusBarStateController.setState(SHADE_LOCKED);
 
-        listener.onDoubleTapRequired();
+        listener.onAdditionalTapRequired();
 
         verify(mTapAgainViewController).show();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
index 97c0bb2..09add65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
@@ -89,7 +89,7 @@
 
     @Test
     fun testGestureDetector_singleTapEnabled() {
-        whenever(statusBarStateController.isPulsing).thenReturn(true)
+        whenever(statusBarStateController.isDozing).thenReturn(true)
 
         // GIVEN tap is enabled, prox not covered
         whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
@@ -100,7 +100,7 @@
         whenever(falsingManager.isFalseTap(anyInt())).thenReturn(false)
 
         // WHEN there's a tap
-        underTest.onSingleTapConfirmed(downEv)
+        underTest.onSingleTapUp(upEv)
 
         // THEN wake up device if dozing
         verify(centralSurfaces).wakeUpIfDozing(anyLong(), anyObject(), anyString())
@@ -108,7 +108,7 @@
 
     @Test
     fun testGestureDetector_doubleTapEnabled() {
-        whenever(statusBarStateController.isPulsing).thenReturn(true)
+        whenever(statusBarStateController.isDozing).thenReturn(true)
 
         // GIVEN double tap is enabled, prox not covered
         whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
@@ -119,15 +119,27 @@
         whenever(falsingManager.isFalseDoubleTap).thenReturn(false)
 
         // WHEN there's a double tap
-        underTest.onDoubleTap(downEv)
+        underTest.onDoubleTapEvent(upEv)
 
         // THEN wake up device if dozing
         verify(centralSurfaces).wakeUpIfDozing(anyLong(), anyObject(), anyString())
     }
 
     @Test
+    fun testGestureDetector_doubleTapEnabled_onDownEvent_noFalsingCheck() {
+        // GIVEN tap is enabled
+        whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
+
+        // WHEN there's a double tap on DOWN event
+        underTest.onDoubleTapEvent(downEv)
+
+        // THEN don't check the falsing manager, should only be checked on the UP event
+        verify(falsingManager, never()).isFalseDoubleTap()
+    }
+
+    @Test
     fun testGestureDetector_singleTapEnabled_falsing() {
-        whenever(statusBarStateController.isPulsing).thenReturn(true)
+        whenever(statusBarStateController.isDozing).thenReturn(true)
 
         // GIVEN tap is enabled, prox not covered
         whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
@@ -138,29 +150,43 @@
         whenever(falsingManager.isFalseTap(anyInt())).thenReturn(true)
 
         // WHEN there's a tap
-        underTest.onSingleTapConfirmed(downEv)
+        underTest.onSingleTapUp(upEv)
 
         // THEN the device doesn't wake up
         verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
     }
 
     @Test
-    fun testGestureDetector_notPulsing_noFalsingCheck() {
-        whenever(statusBarStateController.isPulsing).thenReturn(false)
+    fun testSingleTap_notDozing_noFalsingCheck() {
+        whenever(statusBarStateController.isDozing).thenReturn(false)
 
-        // GIVEN tap is enabled, prox not covered
+        // GIVEN tap is enabled
         whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
         // WHEN there's a tap
-        underTest.onSingleTapConfirmed(downEv)
+        underTest.onSingleTapUp(upEv)
 
-        // THEN the falsing manager never gets a call (because the device wasn't pulsing
+        // THEN the falsing manager never gets a call (because the device wasn't dozing
+        // during the tap)
+        verify(falsingManager, never()).isFalseTap(anyInt())
+    }
+
+    @Test
+    fun testDoubleTap_notDozing_noFalsingCheck() {
+        whenever(statusBarStateController.isDozing).thenReturn(false)
+
+        // GIVEN tap is enabled
+        whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
+        // WHEN there's a tap
+        underTest.onDoubleTapEvent(upEv)
+
+        // THEN the falsing manager never gets a call (because the device wasn't dozing
         // during the tap)
         verify(falsingManager, never()).isFalseTap(anyInt())
     }
 
     @Test
     fun testGestureDetector_doubleTapEnabled_falsing() {
-        whenever(statusBarStateController.isPulsing).thenReturn(true)
+        whenever(statusBarStateController.isDozing).thenReturn(true)
 
         // GIVEN double tap is enabled, prox not covered
         whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
@@ -170,8 +196,8 @@
         // GIVEN the falsing manager thinks the tap is a false tap
         whenever(falsingManager.isFalseDoubleTap).thenReturn(true)
 
-        // WHEN there's a tap
-        underTest.onDoubleTap(downEv)
+        // WHEN there's a double tap ACTION_UP event
+        underTest.onDoubleTapEvent(upEv)
 
         // THEN the device doesn't wake up
         verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
@@ -179,7 +205,7 @@
 
     @Test
     fun testGestureDetector_singleTapEnabled_proxCovered() {
-        whenever(statusBarStateController.isPulsing).thenReturn(true)
+        whenever(statusBarStateController.isDozing).thenReturn(true)
 
         // GIVEN tap is enabled, not a false tap based on classifiers
         whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
@@ -190,7 +216,7 @@
         whenever(falsingManager.isProximityNear()).thenReturn(true)
 
         // WHEN there's a tap
-        underTest.onSingleTapConfirmed(downEv)
+        underTest.onSingleTapUp(upEv)
 
         // THEN the device doesn't wake up
         verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
@@ -198,7 +224,7 @@
 
     @Test
     fun testGestureDetector_doubleTapEnabled_proxCovered() {
-        whenever(statusBarStateController.isPulsing).thenReturn(true)
+        whenever(statusBarStateController.isDozing).thenReturn(true)
 
         // GIVEN double tap is enabled, not a false tap based on classifiers
         whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
@@ -209,7 +235,7 @@
         whenever(falsingManager.isProximityNear()).thenReturn(true)
 
         // WHEN there's a tap
-        underTest.onDoubleTap(downEv)
+        underTest.onDoubleTapEvent(upEv)
 
         // THEN the device doesn't wake up
         verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
@@ -227,3 +253,4 @@
 }
 
 private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+private val upEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
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
new file mode 100644
index 0000000..eb34561
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.shared.clocks
+
+import android.testing.AndroidTestingRunner
+import android.view.LayoutInflater
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.TextAnimator
+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.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.junit.MockitoJUnit
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class AnimatableClockViewTest : SysuiTestCase() {
+
+    @JvmField @Rule val mockito = MockitoJUnit.rule()
+
+    @Mock private lateinit var mockTextAnimator: TextAnimator
+    private lateinit var clockView: AnimatableClockView
+
+    @Before
+    fun setUp() {
+        val layoutInflater = LayoutInflater.from(context)
+        clockView =
+            layoutInflater.inflate(R.layout.clock_default_small, null) as AnimatableClockView
+        clockView.textAnimatorFactory = { _, _ -> mockTextAnimator }
+    }
+
+    @Test
+    fun validateColorAnimationRunsBeforeMeasure() {
+        clockView.setColors(100, 200)
+        clockView.animateAppearOnLockscreen()
+        clockView.measure(50, 50)
+
+        verify(mockTextAnimator).glyphFilter = null
+        verify(mockTextAnimator).setTextStyle(300, -1.0f, 200, false, 350L, null, 0L, null)
+        verifyNoMoreInteractions(mockTextAnimator)
+    }
+
+    @Test
+    fun validateColorAnimationRunsAfterMeasure() {
+        clockView.setColors(100, 200)
+        clockView.measure(50, 50)
+        clockView.animateAppearOnLockscreen()
+
+        verify(mockTextAnimator, times(2)).glyphFilter = null
+        verify(mockTextAnimator).setTextStyle(100, -1.0f, 200, false, 0L, null, 0L, null)
+        verify(mockTextAnimator).setTextStyle(300, -1.0f, 200, true, 350L, null, 0L, null)
+        verifyNoMoreInteractions(mockTextAnimator)
+    }
+}
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 74e2747..464dfe2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -19,8 +19,10 @@
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT;
 
+import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
@@ -86,6 +88,7 @@
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.biometrics.FaceHelpMessageDeferral;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.KeyguardIndication;
@@ -167,6 +170,8 @@
     @Mock
     private AccessibilityManager mAccessibilityManager;
     @Mock
+    private FaceHelpMessageDeferral mFaceHelpMessageDeferral;
+    @Mock
     private ScreenLifecycle mScreenLifecycle;
     @Captor
     private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
@@ -259,7 +264,8 @@
                 mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
                 mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
                 mUserManager, mExecutor, mExecutor,  mFalsingManager, mLockPatternUtils,
-                mScreenLifecycle, mKeyguardBypassController, mAccessibilityManager);
+                mScreenLifecycle, mKeyguardBypassController, mAccessibilityManager,
+                mFaceHelpMessageDeferral);
         mController.init();
         mController.setIndicationArea(mIndicationArea);
         verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
@@ -535,7 +541,7 @@
 
         mController.setVisible(true);
         mController.getKeyguardCallback().onBiometricHelp(
-                KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
+                BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
                 BiometricSourceType.FACE);
         verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message);
         reset(mRotateTextViewController);
@@ -582,7 +588,7 @@
 
         // WHEN there's a face not recognized message
         mController.getKeyguardCallback().onBiometricHelp(
-                KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
+                BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
                 message,
                 BiometricSourceType.FACE);
 
@@ -748,8 +754,10 @@
         when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
                 0)).thenReturn(false);
 
-        // WHEN help message received
+        // WHEN help message received and deferred message is valid
         final String helpString = "helpMsg";
+        when(mFaceHelpMessageDeferral.getDeferredMessage()).thenReturn(helpString);
+        when(mFaceHelpMessageDeferral.shouldDefer(FACE_ACQUIRED_TOO_DARK)).thenReturn(true);
         mKeyguardUpdateMonitorCallback.onBiometricHelp(
                 BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK,
                 helpString,
@@ -777,8 +785,10 @@
         when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
                 0)).thenReturn(true);
 
-        // WHEN help message received
+        // WHEN help message received and deferredMessage is valid
         final String helpString = "helpMsg";
+        when(mFaceHelpMessageDeferral.getDeferredMessage()).thenReturn(helpString);
+        when(mFaceHelpMessageDeferral.shouldDefer(FACE_ACQUIRED_TOO_DARK)).thenReturn(true);
         mKeyguardUpdateMonitorCallback.onBiometricHelp(
                 BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK,
                 helpString,
@@ -1126,7 +1136,6 @@
         verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, pressToOpen);
     }
 
-
     @Test
     public void coEx_faceSuccess_touchExplorationEnabled_showsFaceUnlockedSwipeToOpen() {
         // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y enabled
@@ -1272,6 +1281,87 @@
         verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
     }
 
+    @Test
+    public void faceOnAcquired_processFrame() {
+        createController();
+
+        // WHEN face sends an acquired message
+        final int acquireInfo = 1;
+        mKeyguardUpdateMonitorCallback.onBiometricAcquired(BiometricSourceType.FACE, acquireInfo);
+
+        // THEN face help message deferral should process the acquired frame
+        verify(mFaceHelpMessageDeferral).processFrame(acquireInfo);
+    }
+
+    @Test
+    public void fingerprintOnAcquired_noProcessFrame() {
+        createController();
+
+        // WHEN fingerprint sends an acquired message
+        mKeyguardUpdateMonitorCallback.onBiometricAcquired(BiometricSourceType.FINGERPRINT, 1);
+
+        // THEN face help message deferral should NOT process any acquired frames
+        verify(mFaceHelpMessageDeferral, never()).processFrame(anyInt());
+    }
+
+    @Test
+    public void onBiometricHelp_fingerprint_faceHelpMessageDeferralDoesNothing() {
+        createController();
+
+        // WHEN fingerprint sends an onBiometricHelp
+        mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                1,
+                "placeholder",
+                BiometricSourceType.FINGERPRINT);
+
+        // THEN face help message deferral is NOT: reset, updated, or checked for shouldDefer
+        verify(mFaceHelpMessageDeferral, never()).reset();
+        verify(mFaceHelpMessageDeferral, never()).updateMessage(anyInt(), anyString());
+        verify(mFaceHelpMessageDeferral, never()).shouldDefer(anyInt());
+    }
+
+    @Test
+    public void onBiometricFailed_resetFaceHelpMessageDeferral() {
+        createController();
+
+        // WHEN face sends an onBiometricHelp BIOMETRIC_HELP_FACE_NOT_RECOGNIZED
+        mKeyguardUpdateMonitorCallback.onBiometricAuthFailed(BiometricSourceType.FACE);
+
+        // THEN face help message deferral is reset
+        verify(mFaceHelpMessageDeferral).reset();
+    }
+
+    @Test
+    public void onBiometricError_resetFaceHelpMessageDeferral() {
+        createController();
+
+        // WHEN face has an error
+        mKeyguardUpdateMonitorCallback.onBiometricError(4, "string",
+                BiometricSourceType.FACE);
+
+        // THEN face help message deferral is reset
+        verify(mFaceHelpMessageDeferral).reset();
+    }
+
+    @Test
+    public void onBiometricHelp_faceAcquiredInfo_faceHelpMessageDeferral() {
+        createController();
+
+        // WHEN face sends an onBiometricHelp BIOMETRIC_HELP_FACE_NOT_RECOGNIZED
+        final int msgId = 1;
+        final String helpString = "test";
+        mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                msgId,
+                "test",
+                BiometricSourceType.FACE);
+
+        // THEN face help message deferral is NOT reset and message IS updated
+        verify(mFaceHelpMessageDeferral, never()).reset();
+        verify(mFaceHelpMessageDeferral).updateMessage(msgId, helpString);
+    }
+
+
+
     private void sendUpdateDisclosureBroadcast() {
         mBroadcastReceiver.onReceive(mContext, new Intent());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index d3c1dc9..a95a49c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification.stack;
 
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -32,8 +34,10 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.logging.NotificationRoundnessLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
@@ -57,6 +61,7 @@
     private Runnable mRoundnessCallback = mock(Runnable.class);
     private ExpandableNotificationRow mFirst;
     private ExpandableNotificationRow mSecond;
+    private NotificationRoundnessLogger mLogger = mock(NotificationRoundnessLogger.class);
     private float mSmallRadiusRatio;
 
     @Before
@@ -66,7 +71,9 @@
         mSmallRadiusRatio = resources.getDimension(R.dimen.notification_corner_radius_small)
                 / resources.getDimension(R.dimen.notification_corner_radius);
         mRoundnessManager = new NotificationRoundnessManager(
-                new NotificationSectionsFeatureManager(new DeviceConfigProxy(), mContext));
+                new NotificationSectionsFeatureManager(new DeviceConfigProxy(), mContext),
+                mLogger,
+                mock(DumpManager.class));
         allowTestableLooperAsMainThread();
         NotificationTestHelper testHelper = new NotificationTestHelper(
                 mContext,
@@ -337,6 +344,20 @@
         Assert.assertTrue(mSecond.isLastInSection());
     }
 
+    @Test
+    public void testLoggingOnRoundingUpdate() {
+        NotificationSection[] sections = new NotificationSection[]{
+                createSection(mFirst, mSecond),
+                createSection(null, null)
+        };
+        mRoundnessManager.updateRoundedChildren(sections);
+        verify(mLogger).onSectionCornersUpdated(sections, /*anyChanged=*/ true);
+        verify(mLogger, atLeast(1)).onCornersUpdated(eq(mFirst), anyBoolean(),
+                anyBoolean(), anyBoolean(), anyBoolean());
+        verify(mLogger, atLeast(1)).onCornersUpdated(eq(mSecond), anyBoolean(),
+                anyBoolean(), anyBoolean(), anyBoolean());
+    }
+
     private NotificationSection createSection(ExpandableNotificationRow first,
             ExpandableNotificationRow last) {
         NotificationSection section = mock(NotificationSection.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index e790d85..a4453f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -505,4 +506,21 @@
         mBouncerExpansionCallback.onVisibilityChanged(false);
         verify(mCentralSurfaces).setBouncerShowingOverDream(false);
     }
+
+    @Test
+    public void testSetDozing_Dozing() {
+        clearInvocations(mBouncer);
+        mStatusBarKeyguardViewManager.onDozingChanged(true);
+        // Once when shown and once with dozing changed.
+        verify(mBouncer, times(1)).hide(false);
+    }
+
+    @Test
+    public void testSetDozing_notDozing() {
+        mStatusBarKeyguardViewManager.onDozingChanged(true);
+        clearInvocations(mBouncer);
+        mStatusBarKeyguardViewManager.onDozingChanged(false);
+        // Once when shown and twice with dozing changed.
+        verify(mBouncer, times(1)).hide(false);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index fda80a2..43d0fe9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -42,6 +42,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 
@@ -80,6 +81,7 @@
                 mPowerManager,
                 mBroadcastDispatcher,
                 mDemoModeController,
+                mock(DumpManager.class),
                 new Handler(),
                 new Handler());
         // Can throw if updateEstimate is called on the main thread
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index 3dd36d1..d0391ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -41,6 +41,7 @@
 import com.android.settingslib.bluetooth.LocalBluetoothProfile;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.bluetooth.BluetoothLogger;
 import com.android.systemui.dump.DumpManager;
 
 import org.junit.Before;
@@ -81,6 +82,7 @@
 
         mBluetoothControllerImpl = new BluetoothControllerImpl(mContext,
                 mMockDumpManager,
+                mock(BluetoothLogger.class),
                 mTestableLooper.getLooper(),
                 mTestableLooper.getLooper(),
                 mMockBluetoothManager);
@@ -233,4 +235,11 @@
         assertTrue(mBluetoothControllerImpl.isBluetoothAudioActive());
         assertTrue(mBluetoothControllerImpl.isBluetoothAudioProfileOnly());
     }
+
+    /** Regression test for b/246876230. */
+    @Test
+    public void testOnActiveDeviceChanged_null_noCrash() {
+        mBluetoothControllerImpl.onActiveDeviceChanged(null, BluetoothProfile.HEADSET);
+        // No assert, just need no crash.
+    }
 }
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 e616c26..921b7ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -17,20 +17,14 @@
 package com.android.systemui.temporarydisplay
 
 import android.content.Context
-import android.content.pm.ApplicationInfo
-import android.content.pm.PackageManager
-import android.graphics.drawable.Drawable
 import android.os.PowerManager
-import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
-import android.widget.ImageView
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
 import com.android.systemui.util.concurrency.DelayableExecutor
@@ -42,9 +36,7 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
-import org.mockito.ArgumentCaptor
 import org.mockito.Mock
-import org.mockito.Mockito.eq
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
@@ -58,13 +50,8 @@
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var fakeExecutor: FakeExecutor
 
-    private lateinit var appIconFromPackageName: Drawable
     @Mock
-    private lateinit var packageManager: PackageManager
-    @Mock
-    private lateinit var applicationInfo: ApplicationInfo
-    @Mock
-    private lateinit var logger: MediaTttLogger
+    private lateinit var logger: TemporaryViewLogger
     @Mock
     private lateinit var accessibilityManager: AccessibilityManager
     @Mock
@@ -78,17 +65,6 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
-        appIconFromPackageName = context.getDrawable(R.drawable.ic_cake)!!
-        whenever(packageManager.getApplicationIcon(PACKAGE_NAME)).thenReturn(appIconFromPackageName)
-        whenever(applicationInfo.loadLabel(packageManager)).thenReturn(APP_NAME)
-        whenever(packageManager.getApplicationInfo(
-            any(), any<PackageManager.ApplicationInfoFlags>()
-        )).thenThrow(PackageManager.NameNotFoundException())
-        whenever(packageManager.getApplicationInfo(
-            eq(PACKAGE_NAME), any<PackageManager.ApplicationInfoFlags>()
-        )).thenReturn(applicationInfo)
-        context.setMockPackageManager(packageManager)
-
         whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any()))
             .thenReturn(TIMEOUT_MS.toInt())
 
@@ -229,117 +205,8 @@
         verify(windowManager, never()).removeView(any())
     }
 
-    @Test
-    fun setIcon_nullAppIconDrawableAndNullPackageName_stillHasIcon() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        underTest.setIcon(view, appPackageName = null, appIconDrawableOverride = null)
-
-        assertThat(view.getAppIconView().drawable).isNotNull()
-    }
-
-    @Test
-    fun setIcon_nullAppIconDrawableAndInvalidPackageName_stillHasIcon() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        underTest.setIcon(
-            view, appPackageName = "fakePackageName", appIconDrawableOverride = null
-        )
-
-        assertThat(view.getAppIconView().drawable).isNotNull()
-    }
-
-    @Test
-    fun setIcon_nullAppIconDrawable_iconIsFromPackageName() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        underTest.setIcon(view, PACKAGE_NAME, appIconDrawableOverride = null, null)
-
-        assertThat(view.getAppIconView().drawable).isEqualTo(appIconFromPackageName)
-    }
-
-    @Test
-    fun setIcon_hasAppIconDrawable_iconIsDrawable() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        val drawable = context.getDrawable(R.drawable.ic_alarm)!!
-        underTest.setIcon(view, PACKAGE_NAME, drawable, null)
-
-        assertThat(view.getAppIconView().drawable).isEqualTo(drawable)
-    }
-
-    @Test
-    fun setIcon_nullAppNameAndNullPackageName_stillHasContentDescription() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        underTest.setIcon(view, appPackageName = null, appNameOverride = null)
-
-        assertThat(view.getAppIconView().contentDescription.toString()).isNotEmpty()
-    }
-
-    @Test
-    fun setIcon_nullAppNameAndInvalidPackageName_stillHasContentDescription() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        underTest.setIcon(
-            view, appPackageName = "fakePackageName", appNameOverride = null
-        )
-
-        assertThat(view.getAppIconView().contentDescription.toString()).isNotEmpty()
-    }
-
-    @Test
-    fun setIcon_nullAppName_iconContentDescriptionIsFromPackageName() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        underTest.setIcon(view, PACKAGE_NAME, null, appNameOverride = null)
-
-        assertThat(view.getAppIconView().contentDescription).isEqualTo(APP_NAME)
-    }
-
-    @Test
-    fun setIcon_hasAppName_iconContentDescriptionIsAppNameOverride() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        val appName = "Override App Name"
-        underTest.setIcon(view, PACKAGE_NAME, null, appName)
-
-        assertThat(view.getAppIconView().contentDescription).isEqualTo(appName)
-    }
-
-    @Test
-    fun setIcon_iconSizeMatchesGetIconSize() {
-        underTest.displayView(getState())
-        val view = getView()
-
-        underTest.setIcon(view, PACKAGE_NAME)
-        view.measure(
-            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
-            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
-        )
-
-        assertThat(view.getAppIconView().measuredWidth).isEqualTo(ICON_SIZE)
-        assertThat(view.getAppIconView().measuredHeight).isEqualTo(ICON_SIZE)
-    }
-
     private fun getState(name: String = "name") = ViewInfo(name)
 
-    private fun getView(): ViewGroup {
-        val viewCaptor = ArgumentCaptor.forClass(View::class.java)
-        verify(windowManager).addView(viewCaptor.capture(), any())
-        return viewCaptor.value as ViewGroup
-    }
-
-    private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
-
     private fun getConfigurationListener(): ConfigurationListener {
         val callbackCaptor = argumentCaptor<ConfigurationListener>()
         verify(configurationController).addCallback(capture(callbackCaptor))
@@ -348,13 +215,13 @@
 
     inner class TestController(
         context: Context,
-        logger: MediaTttLogger,
+        logger: TemporaryViewLogger,
         windowManager: WindowManager,
         @Main mainExecutor: DelayableExecutor,
         accessibilityManager: AccessibilityManager,
         configurationController: ConfigurationController,
         powerManager: PowerManager,
-    ) : TemporaryViewDisplayController<ViewInfo>(
+    ) : TemporaryViewDisplayController<ViewInfo, TemporaryViewLogger>(
         context,
         logger,
         windowManager,
@@ -363,6 +230,8 @@
         configurationController,
         powerManager,
         R.layout.media_ttt_chip,
+        "Window Title",
+        "WAKE_REASON",
     ) {
         var mostRecentViewInfo: ViewInfo? = null
 
@@ -371,7 +240,6 @@
             super.updateView(newInfo, currentView)
             mostRecentViewInfo = newInfo
         }
-        override fun getIconSize(isAppIcon: Boolean): Int = ICON_SIZE
     }
 
     inner class ViewInfo(val name: String) : TemporaryViewInfo {
@@ -379,7 +247,4 @@
     }
 }
 
-private const val PACKAGE_NAME = "com.android.systemui"
-private const val APP_NAME = "Fake App Name"
 private const val TIMEOUT_MS = 10000L
-private const val ICON_SIZE = 47
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
new file mode 100644
index 0000000..c9f2b4d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.temporarydisplay
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.log.LogcatEchoTracker
+import com.google.common.truth.Truth.assertThat
+import java.io.PrintWriter
+import java.io.StringWriter
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito
+
+@SmallTest
+class TemporaryViewLoggerTest : SysuiTestCase() {
+    private lateinit var buffer: LogBuffer
+    private lateinit var logger: TemporaryViewLogger
+
+    @Before
+    fun setUp() {
+        buffer =
+            LogBufferFactory(DumpManager(), Mockito.mock(LogcatEchoTracker::class.java))
+                .create("buffer", 10)
+        logger = TemporaryViewLogger(buffer, TAG)
+    }
+
+    @Test
+    fun logChipAddition_bufferHasLog() {
+        logger.logChipAddition()
+
+        val stringWriter = StringWriter()
+        buffer.dump(PrintWriter(stringWriter), tailLength = 0)
+        val actualString = stringWriter.toString()
+
+        assertThat(actualString).contains(TAG)
+    }
+
+    @Test
+    fun logChipRemoval_bufferHasTagAndReason() {
+        val reason = "test reason"
+        logger.logChipRemoval(reason)
+
+        val stringWriter = StringWriter()
+        buffer.dump(PrintWriter(stringWriter), tailLength = 0)
+        val actualString = stringWriter.toString()
+
+        assertThat(actualString).contains(TAG)
+        assertThat(actualString).contains(reason)
+    }
+}
+
+private const val TAG = "TestTag"
diff --git a/packages/VpnDialogs/res/values-ro/strings.xml b/packages/VpnDialogs/res/values-ro/strings.xml
index 5bda87e..a63f592 100644
--- a/packages/VpnDialogs/res/values-ro/strings.xml
+++ b/packages/VpnDialogs/res/values-ro/strings.xml
@@ -17,21 +17,21 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="3183836924226407828">"Solicitare de conexiune"</string>
-    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> dorește să configureze o conexiune VPN care să îi permită să monitorizeze traficul în rețea. Acceptați numai dacă aveți încredere în sursă. Atunci când conexiunea VPN este activă, &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; se afișează în partea de sus a ecranului."</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> dorește să configureze o conexiune VPN care să îi permită să monitorizeze traficul în rețea. Acceptă numai dacă ai încredere în sursă. Când conexiunea VPN e activă, &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; se afișează în partea de sus a ecranului."</string>
     <string name="warning" product="tv" msgid="5188957997628124947">"<xliff:g id="APP">%s</xliff:g> solicită permisiunea de a configura o conexiune VPN care să îi permită să monitorizeze traficul de rețea. Acceptați numai dacă aveți încredere în sursă. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; va apărea pe ecran atunci când conexiunea VPN este activă."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN este conectat"</string>
     <string name="session" msgid="6470628549473641030">"Sesiune:"</string>
     <string name="duration" msgid="3584782459928719435">"Durată:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Trimise:"</string>
     <string name="data_received" msgid="4062776929376067820">"Primite:"</string>
-    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g>   octeți/<xliff:g id="NUMBER_1">%2$s</xliff:g>   pachete"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g>   byți/<xliff:g id="NUMBER_1">%2$s</xliff:g>   pachete"</string>
     <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nu se poate conecta la rețeaua VPN activată permanent"</string>
     <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> este setată să rămână conectată permanent, dar momentan nu se poate conecta. Telefonul dvs. va folosi o rețea publică până când se va putea reconecta la <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
     <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> este setată să rămână conectată permanent, dar momentan nu se poate conecta. Nu veți avea conexiune până când se va putea reconecta rețeaua VPN."</string>
     <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
     <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Modificați setările VPN"</string>
-    <string name="configure" msgid="4905518375574791375">"Configurați"</string>
-    <string name="disconnect" msgid="971412338304200056">"Deconectați"</string>
-    <string name="open_app" msgid="3717639178595958667">"Deschideți aplicația"</string>
-    <string name="dismiss" msgid="6192859333764711227">"Închideți"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurează"</string>
+    <string name="disconnect" msgid="971412338304200056">"Deconectează"</string>
+    <string name="open_app" msgid="3717639178595958667">"Deschide aplicația"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Închide"</string>
 </resources>
diff --git a/packages/overlays/NoCutoutOverlay/res/values-ro/strings.xml b/packages/overlays/NoCutoutOverlay/res/values-ro/strings.xml
index e6281fd..2d7aaf6 100644
--- a/packages/overlays/NoCutoutOverlay/res/values-ro/strings.xml
+++ b/packages/overlays/NoCutoutOverlay/res/values-ro/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"Ascundeți"</string>
+    <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"Ascunde"</string>
 </resources>
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 3324c52..799c759 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -75,7 +75,6 @@
 import android.view.Display;
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
-import android.view.SurfaceControl.ScreenshotHardwareBuffer;
 import android.view.View;
 import android.view.WindowInfo;
 import android.view.accessibility.AccessibilityCache;
@@ -84,6 +83,7 @@
 import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 import android.view.inputmethod.EditorInfo;
+import android.window.ScreenCapture.ScreenshotHardwareBuffer;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.compat.IPlatformCompat;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index f55cfb1..8d94f95 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1113,7 +1113,8 @@
             final List<AccessibilityServiceInfo> result = new ArrayList<>(serviceCount);
             for (int i = 0; i < serviceCount; ++i) {
                 final AccessibilityServiceConnection service = services.get(i);
-                if ((service.mFeedbackType & feedbackType) != 0) {
+                if ((service.mFeedbackType & feedbackType) != 0
+                        || feedbackType == AccessibilityServiceInfo.FEEDBACK_ALL_MASK) {
                     result.add(service.getServiceInfo());
                 }
             }
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceServiceConnector.java b/services/companion/java/com/android/server/companion/CompanionDeviceServiceConnector.java
index 93cc611..82628a6 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceServiceConnector.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceServiceConnector.java
@@ -46,6 +46,9 @@
     private static final String TAG = "CDM_CompanionServiceConnector";
     private static final boolean DEBUG = false;
 
+    /* Unbinding before executing the callbacks can cause problems. Wait 5-seconds before unbind. */
+    private static final long UNBIND_POST_DELAY_MS = 5_000;
+
     /** Listener for changes to the state of the {@link CompanionDeviceServiceConnector}  */
     interface Listener {
         void onBindingDied(@UserIdInt int userId, @NonNull String packageName,
@@ -110,9 +113,15 @@
      * IMPORTANT: use this method instead of invoking {@link ServiceConnector#unbind()} directly,
      * because the latter may cause previously posted callback, such as
      * {@link ICompanionDeviceService#onDeviceDisappeared(AssociationInfo)} to be dropped.
+     *
+     * {@link ICompanionDeviceService} is a non-blocking interface and doesn't wait for job
+     * completion, which makes {@link ServiceConnector#post(VoidJob)} obsolete for ensuring the
+     * order of execution. Give 5 seconds for all the callbacks to finish before unbinding. They
+     * may or may not have finished executing, but we shouldn't let user-overridden methods block
+     * the service from unbinding indefinitely.
      */
     void postUnbind() {
-        post(it -> unbind());
+        getJobHandler().postDelayed(this::unbind, UNBIND_POST_DELAY_MS);
     }
 
     boolean isPrimary() {
diff --git a/services/companion/java/com/android/server/companion/virtual/InputController.java b/services/companion/java/com/android/server/companion/virtual/InputController.java
index 05e85e3..838cbd9 100644
--- a/services/companion/java/com/android/server/companion/virtual/InputController.java
+++ b/services/companion/java/com/android/server/companion/virtual/InputController.java
@@ -61,10 +61,12 @@
 
     private static final AtomicLong sNextPhysId = new AtomicLong(1);
 
+    static final String PHYS_TYPE_DPAD = "Dpad";
     static final String PHYS_TYPE_KEYBOARD = "Keyboard";
     static final String PHYS_TYPE_MOUSE = "Mouse";
     static final String PHYS_TYPE_TOUCHSCREEN = "Touchscreen";
     @StringDef(prefix = { "PHYS_TYPE_" }, value = {
+            PHYS_TYPE_DPAD,
             PHYS_TYPE_KEYBOARD,
             PHYS_TYPE_MOUSE,
             PHYS_TYPE_TOUCHSCREEN,
@@ -121,6 +123,22 @@
         }
     }
 
+    void createDpad(@NonNull String deviceName,
+                        int vendorId,
+                        int productId,
+                        @NonNull IBinder deviceToken,
+                        int displayId) {
+        final String phys = createPhys(PHYS_TYPE_DPAD);
+        try {
+            createDeviceInternal(InputDeviceDescriptor.TYPE_DPAD, deviceName, vendorId,
+                    productId, deviceToken, displayId, phys,
+                    () -> mNativeWrapper.openUinputDpad(deviceName, vendorId, productId, phys));
+        } catch (DeviceCreationException e) {
+            throw new RuntimeException(
+                    "Failed to create virtual dpad device '" + deviceName + "'.", e);
+        }
+    }
+
     void createKeyboard(@NonNull String deviceName,
             int vendorId,
             int productId,
@@ -253,6 +271,19 @@
         InputManager.getInstance().addUniqueIdAssociation(phys, displayUniqueId);
     }
 
+    boolean sendDpadKeyEvent(@NonNull IBinder token, @NonNull VirtualKeyEvent event) {
+        synchronized (mLock) {
+            final InputDeviceDescriptor inputDeviceDescriptor = mInputDeviceDescriptors.get(
+                    token);
+            if (inputDeviceDescriptor == null) {
+                throw new IllegalArgumentException(
+                        "Could not send key event to input device for given token");
+            }
+            return mNativeWrapper.writeDpadKeyEvent(inputDeviceDescriptor.getFileDescriptor(),
+                    event.getKeyCode(), event.getAction());
+        }
+    }
+
     boolean sendKeyEvent(@NonNull IBinder token, @NonNull VirtualKeyEvent event) {
         synchronized (mLock) {
             final InputDeviceDescriptor inputDeviceDescriptor = mInputDeviceDescriptors.get(
@@ -366,6 +397,8 @@
         }
     }
 
+    private static native int nativeOpenUinputDpad(String deviceName, int vendorId,
+            int productId, String phys);
     private static native int nativeOpenUinputKeyboard(String deviceName, int vendorId,
             int productId, String phys);
     private static native int nativeOpenUinputMouse(String deviceName, int vendorId, int productId,
@@ -373,6 +406,7 @@
     private static native int nativeOpenUinputTouchscreen(String deviceName, int vendorId,
             int productId, String phys, int height, int width);
     private static native boolean nativeCloseUinput(int fd);
+    private static native boolean nativeWriteDpadKeyEvent(int fd, int androidKeyCode, int action);
     private static native boolean nativeWriteKeyEvent(int fd, int androidKeyCode, int action);
     private static native boolean nativeWriteButtonEvent(int fd, int buttonCode, int action);
     private static native boolean nativeWriteTouchEvent(int fd, int pointerId, int toolType,
@@ -385,6 +419,10 @@
     /** Wrapper around the static native methods for tests. */
     @VisibleForTesting
     protected static class NativeWrapper {
+        public int openUinputDpad(String deviceName, int vendorId, int productId, String phys) {
+            return nativeOpenUinputDpad(deviceName, vendorId, productId, phys);
+        }
+
         public int openUinputKeyboard(String deviceName, int vendorId, int productId, String phys) {
             return nativeOpenUinputKeyboard(deviceName, vendorId, productId, phys);
         }
@@ -403,6 +441,10 @@
             return nativeCloseUinput(fd);
         }
 
+        public boolean writeDpadKeyEvent(int fd, int androidKeyCode, int action) {
+            return nativeWriteDpadKeyEvent(fd, androidKeyCode, action);
+        }
+
         public boolean writeKeyEvent(int fd, int androidKeyCode, int action) {
             return nativeWriteKeyEvent(fd, androidKeyCode, action);
         }
@@ -433,10 +475,12 @@
         static final int TYPE_KEYBOARD = 1;
         static final int TYPE_MOUSE = 2;
         static final int TYPE_TOUCHSCREEN = 3;
+        static final int TYPE_DPAD = 4;
         @IntDef(prefix = { "TYPE_" }, value = {
                 TYPE_KEYBOARD,
                 TYPE_MOUSE,
                 TYPE_TOUCHSCREEN,
+                TYPE_DPAD,
         })
         @Retention(RetentionPolicy.SOURCE)
         @interface Type {
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 cca3212..4204162 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -344,6 +344,33 @@
         }
     }
 
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    @Override // Binder call
+    public void createVirtualDpad(
+            int displayId,
+            @NonNull String deviceName,
+            int vendorId,
+            int productId,
+            @NonNull IBinder deviceToken) {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CREATE_VIRTUAL_DEVICE,
+                "Permission required to create a virtual dpad");
+        synchronized (mVirtualDeviceLock) {
+            if (!mVirtualDisplayIds.contains(displayId)) {
+                throw new SecurityException(
+                        "Cannot create a virtual dpad for a display not associated with "
+                                + "this virtual device");
+            }
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mInputController.createDpad(deviceName, vendorId, productId, deviceToken,
+                    displayId);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     @Override // Binder call
     public void createVirtualKeyboard(
             int displayId,
@@ -437,6 +464,16 @@
     }
 
     @Override // Binder call
+    public boolean sendDpadKeyEvent(IBinder token, VirtualKeyEvent event) {
+        final long binderToken = Binder.clearCallingIdentity();
+        try {
+            return mInputController.sendDpadKeyEvent(token, event);
+        } finally {
+            Binder.restoreCallingIdentity(binderToken);
+        }
+    }
+
+    @Override // Binder call
     public boolean sendKeyEvent(IBinder token, VirtualKeyEvent event) {
         final long binderToken = Binder.clearCallingIdentity();
         try {
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 8b13cc8..cbd3f60 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -134,6 +134,7 @@
         "service-permission.stubs.system_server",
         "service-sdksandbox.stubs.system_server",
     ],
+    plugins: ["ImmutabilityAnnotationProcessor"],
 
     required: [
         "default_television.xml",
@@ -172,6 +173,7 @@
         "overlayable_policy_aidl-java",
         "SurfaceFlingerProperties",
         "com.android.sysprop.watchdog",
+        "ImmutabilityAnnotation",
     ],
     javac_shard_size: 50,
 }
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 7ca6254..9f3f761 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -577,6 +577,14 @@
             int filterCallingUid);
 
     /**
+     * Resolves an exported activity intent, allowing instant apps to be resolved.
+     */
+    public abstract ResolveInfo resolveIntentExported(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags,
+            @PrivateResolveFlags long privateResolveFlags, int userId, boolean resolveForStart,
+            int filterCallingUid);
+
+    /**
     * Resolves a service intent, allowing instant apps to be resolved.
     */
     public abstract ResolveInfo resolveService(Intent intent, String resolvedType,
diff --git a/services/core/java/com/android/server/SystemServerInitThreadPool.java b/services/core/java/com/android/server/SystemServerInitThreadPool.java
index 63e7563..9323d95 100644
--- a/services/core/java/com/android/server/SystemServerInitThreadPool.java
+++ b/services/core/java/com/android/server/SystemServerInitThreadPool.java
@@ -192,8 +192,10 @@
     private static void dumpStackTraces() {
         final ArrayList<Integer> pids = new ArrayList<>();
         pids.add(Process.myPid());
-        ActivityManagerService.dumpStackTraces(pids, null, null,
-                Watchdog.getInterestingNativePids(), null, null, null);
+        ActivityManagerService.dumpStackTraces(pids, /* processCpuTracker= */null,
+                /* lastPids= */null, Watchdog.getInterestingNativePids(),
+                /* logExceptionCreatingFile= */null, /* subject= */null,
+                /* criticalEventSection= */null, /* latencyTracker= */null);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index a6e5aa4..b00dec0 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -895,7 +895,7 @@
         StringWriter tracesFileException = new StringWriter();
         final File stack = ActivityManagerService.dumpStackTraces(
                 pids, processCpuTracker, new SparseArray<>(), getInterestingNativePids(),
-                tracesFileException, subject, criticalEvents);
+                tracesFileException, subject, criticalEvents, /* latencyTracker= */null);
         // Give some extra time to make sure the stack traces get written.
         // The system's been hanging for a whlie, another second or two won't hurt much.
         SystemClock.sleep(5000);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 3b299a2..c677edc 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1227,31 +1227,39 @@
     }
 
     private void stopServiceLocked(ServiceRecord service, boolean enqueueOomAdj) {
-        if (service.delayed) {
-            // If service isn't actually running, but is being held in the
-            // delayed list, then we need to keep it started but note that it
-            // should be stopped once no longer delayed.
-            if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Delaying stop of pending: " + service);
-            service.delayedStop = true;
-            return;
-        }
-
-        final int uid = service.appInfo.uid;
-        final String packageName = service.name.getPackageName();
-        final String serviceName = service.name.getClassName();
-        FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, uid, packageName,
-                serviceName, FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__STOP);
-        mAm.mBatteryStatsService.noteServiceStopRunning(uid, packageName, serviceName);
-        service.startRequested = false;
-        if (service.tracker != null) {
-            synchronized (mAm.mProcessStats.mLock) {
-                service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
-                        SystemClock.uptimeMillis());
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "stopServiceLocked()");
+            if (service.delayed) {
+                // If service isn't actually running, but is being held in the
+                // delayed list, then we need to keep it started but note that it
+                // should be stopped once no longer delayed.
+                if (DEBUG_DELAYED_STARTS) {
+                    Slog.v(TAG_SERVICE, "Delaying stop of pending: " + service);
+                }
+                service.delayedStop = true;
+                return;
             }
-        }
-        service.callStart = false;
 
-        bringDownServiceIfNeededLocked(service, false, false, enqueueOomAdj);
+            final int uid = service.appInfo.uid;
+            final String packageName = service.name.getPackageName();
+            final String serviceName = service.name.getClassName();
+            FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, uid, packageName,
+                    serviceName, FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__STOP);
+            mAm.mBatteryStatsService.noteServiceStopRunning(uid, packageName, serviceName);
+            service.startRequested = false;
+            if (service.tracker != null) {
+                synchronized (mAm.mProcessStats.mLock) {
+                    service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
+                            SystemClock.uptimeMillis());
+                }
+            }
+            service.callStart = false;
+
+            bringDownServiceIfNeededLocked(service, false, false, enqueueOomAdj);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
+
     }
 
     int stopServiceLocked(IApplicationThread caller, Intent service,
@@ -3303,7 +3311,7 @@
         }
 
         public void run() {
-            synchronized(mAm) {
+            synchronized (mAm) {
                 performServiceRestartLocked(mService);
             }
         }
@@ -5780,92 +5788,108 @@
     }
 
     void serviceTimeout(ProcessRecord proc) {
-        TimeoutRecord timeoutRecord = null;
-        synchronized(mAm) {
-            if (proc.isDebugging()) {
-                // The app's being debugged, ignore timeout.
-                return;
-            }
-            final ProcessServiceRecord psr = proc.mServices;
-            if (psr.numberOfExecutingServices() == 0 || proc.getThread() == null) {
-                return;
-            }
-            final long now = SystemClock.uptimeMillis();
-            final long maxTime =  now -
-                    (psr.shouldExecServicesFg() ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
-            ServiceRecord timeout = null;
-            long nextTime = 0;
-            for (int i = psr.numberOfExecutingServices() - 1; i >= 0; i--) {
-                ServiceRecord sr = psr.getExecutingServiceAt(i);
-                if (sr.executingStart < maxTime) {
-                    timeout = sr;
-                    break;
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceTimeout()");
+            TimeoutRecord timeoutRecord = null;
+            synchronized (mAm) {
+                if (proc.isDebugging()) {
+                    // The app's being debugged, ignore timeout.
+                    return;
                 }
-                if (sr.executingStart > nextTime) {
-                    nextTime = sr.executingStart;
+                final ProcessServiceRecord psr = proc.mServices;
+                if (psr.numberOfExecutingServices() == 0 || proc.getThread() == null) {
+                    return;
+                }
+                final long now = SystemClock.uptimeMillis();
+                final long maxTime =  now
+                        - (psr.shouldExecServicesFg()
+                        ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
+                ServiceRecord timeout = null;
+                long nextTime = 0;
+                for (int i = psr.numberOfExecutingServices() - 1; i >= 0; i--) {
+                    ServiceRecord sr = psr.getExecutingServiceAt(i);
+                    if (sr.executingStart < maxTime) {
+                        timeout = sr;
+                        break;
+                    }
+                    if (sr.executingStart > nextTime) {
+                        nextTime = sr.executingStart;
+                    }
+                }
+                if (timeout != null && mAm.mProcessList.isInLruListLOSP(proc)) {
+                    Slog.w(TAG, "Timeout executing service: " + timeout);
+                    StringWriter sw = new StringWriter();
+                    PrintWriter pw = new FastPrintWriter(sw, false, 1024);
+                    pw.println(timeout);
+                    timeout.dump(pw, "    ");
+                    pw.close();
+                    mLastAnrDump = sw.toString();
+                    mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
+                    mAm.mHandler.postDelayed(mLastAnrDumpClearer,
+                            LAST_ANR_LIFETIME_DURATION_MSECS);
+                    String anrMessage = "executing service " + timeout.shortInstanceName;
+                    timeoutRecord = TimeoutRecord.forServiceExec(anrMessage);
+                } else {
+                    Message msg = mAm.mHandler.obtainMessage(
+                            ActivityManagerService.SERVICE_TIMEOUT_MSG);
+                    msg.obj = proc;
+                    mAm.mHandler.sendMessageAtTime(msg, psr.shouldExecServicesFg()
+                            ? (nextTime + SERVICE_TIMEOUT) :
+                            (nextTime + SERVICE_BACKGROUND_TIMEOUT));
                 }
             }
-            if (timeout != null && mAm.mProcessList.isInLruListLOSP(proc)) {
-                Slog.w(TAG, "Timeout executing service: " + timeout);
-                StringWriter sw = new StringWriter();
-                PrintWriter pw = new FastPrintWriter(sw, false, 1024);
-                pw.println(timeout);
-                timeout.dump(pw, "    ");
-                pw.close();
-                mLastAnrDump = sw.toString();
-                mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
-                mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
-                String anrMessage = "executing service " + timeout.shortInstanceName;
-                timeoutRecord = TimeoutRecord.forServiceExec(anrMessage);
-            } else {
-                Message msg = mAm.mHandler.obtainMessage(
-                        ActivityManagerService.SERVICE_TIMEOUT_MSG);
-                msg.obj = proc;
-                mAm.mHandler.sendMessageAtTime(msg, psr.shouldExecServicesFg()
-                        ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
-            }
-        }
 
-        if (timeoutRecord != null) {
-            mAm.mAnrHelper.appNotResponding(proc, timeoutRecord);
+            if (timeoutRecord != null) {
+                mAm.mAnrHelper.appNotResponding(proc, timeoutRecord);
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
     void serviceForegroundTimeout(ServiceRecord r) {
-        ProcessRecord app;
-        // Grab a timestamp before lock is taken.
-        long timeoutEndMs = SystemClock.uptimeMillis();
-        synchronized (mAm) {
-            if (!r.fgRequired || !r.fgWaiting || r.destroying) {
-                return;
-            }
-
-            app = r.app;
-            if (app != null && app.isDebugging()) {
-                // The app's being debugged; let it ride
-                return;
-            }
-
-            if (DEBUG_BACKGROUND_CHECK) {
-                Slog.i(TAG, "Service foreground-required timeout for " + r);
-            }
-            r.fgWaiting = false;
-            stopServiceLocked(r, false);
-        }
-
-        if (app != null) {
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceForegroundTimeout()");
+            ProcessRecord app;
+            // Create a TimeoutRecord .
             final String annotation = "Context.startForegroundService() did not then call "
                     + "Service.startForeground(): " + r;
-            Message msg = mAm.mHandler.obtainMessage(
-                    ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG);
             TimeoutRecord timeoutRecord = TimeoutRecord.forServiceStartWithEndTime(annotation,
-                    timeoutEndMs);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = app;
-            args.arg2 = timeoutRecord;
-            msg.obj = args;
-            mAm.mHandler.sendMessageDelayed(msg,
-                    mAm.mConstants.mServiceStartForegroundAnrDelayMs);
+                    SystemClock.uptimeMillis());
+
+            timeoutRecord.mLatencyTracker.waitingOnAMSLockEnded();
+            synchronized (mAm) {
+                timeoutRecord.mLatencyTracker.waitingOnAMSLockEnded();
+                if (!r.fgRequired || !r.fgWaiting || r.destroying) {
+                    return;
+                }
+
+                app = r.app;
+                if (app != null && app.isDebugging()) {
+                    // The app's being debugged; let it ride
+                    return;
+                }
+
+                if (DEBUG_BACKGROUND_CHECK) {
+                    Slog.i(TAG, "Service foreground-required timeout for " + r);
+                }
+                r.fgWaiting = false;
+                stopServiceLocked(r, false);
+            }
+
+            if (app != null) {
+
+                Message msg = mAm.mHandler.obtainMessage(
+                        ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG);
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = app;
+                args.arg2 = timeoutRecord;
+                msg.obj = args;
+                mAm.mHandler.sendMessageDelayed(msg,
+                        mAm.mConstants.mServiceStartForegroundAnrDelayMs);
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 842498d..7be3dca 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -215,6 +215,7 @@
 import android.appwidget.AppWidgetManagerInternal;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.Disabled;
+import android.compat.annotation.EnabledAfter;
 import android.content.AttributionSource;
 import android.content.AutofillOptions;
 import android.content.BroadcastReceiver;
@@ -361,6 +362,7 @@
 import com.android.internal.os.TimeoutRecord;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.os.Zygote;
+import com.android.internal.os.anr.AnrLatencyTracker;
 import com.android.internal.policy.AttributeCache;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.ArrayUtils;
@@ -585,6 +587,17 @@
     private static final long DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED = 161145287L;
 
     /**
+     * Apps targeting Android U and above will need to export components in order to invoke them
+     * through implicit intents.
+     *
+     * If a component is not exported and invoked, it will be removed from the list of receivers.
+     * This applies specifically to activities and broadcasts.
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    public static final long IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS = 229362273;
+
+    /**
      * The maximum number of bytes that {@link #setProcessStateSummary} accepts.
      *
      * @see {@link android.app.ActivityManager#setProcessStateSummary(byte[])}
@@ -655,10 +668,17 @@
     // we still create this new offload queue, but never ever put anything on it.
     final boolean mEnableOffloadQueue;
 
-    final BroadcastQueue mFgBroadcastQueue;
-    final BroadcastQueue mBgBroadcastQueue;
-    final BroadcastQueue mBgOffloadBroadcastQueue;
-    final BroadcastQueue mFgOffloadBroadcastQueue;
+    /**
+     * Flag indicating if we should use {@link BroadcastQueueModernImpl} instead
+     * of the default {@link BroadcastQueueImpl}.
+     */
+    final boolean mEnableModernQueue;
+
+    static final int BROADCAST_QUEUE_FG = 0;
+    static final int BROADCAST_QUEUE_BG = 1;
+    static final int BROADCAST_QUEUE_BG_OFFLOAD = 2;
+    static final int BROADCAST_QUEUE_FG_OFFLOAD = 3;
+
     // Convenient for easy iteration over the queues. Foreground is first
     // so that dispatch of foreground broadcasts gets precedence.
     final BroadcastQueue[] mBroadcastQueues;
@@ -680,12 +700,16 @@
     }
 
     BroadcastQueue broadcastQueueForFlags(int flags, Object cookie) {
+        if (mEnableModernQueue) {
+            return mBroadcastQueues[0];
+        }
+
         if (isOnFgOffloadQueue(flags)) {
             if (DEBUG_BROADCAST_BACKGROUND) {
                 Slog.i(TAG_BROADCAST,
                         "Broadcast intent " + cookie + " on foreground offload queue");
             }
-            return mFgOffloadBroadcastQueue;
+            return mBroadcastQueues[BROADCAST_QUEUE_FG_OFFLOAD];
         }
 
         if (isOnBgOffloadQueue(flags)) {
@@ -693,14 +717,15 @@
                 Slog.i(TAG_BROADCAST,
                         "Broadcast intent " + cookie + " on background offload queue");
             }
-            return mBgOffloadBroadcastQueue;
+            return mBroadcastQueues[BROADCAST_QUEUE_BG_OFFLOAD];
         }
 
         final boolean isFg = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
                 "Broadcast intent " + cookie + " on "
                 + (isFg ? "foreground" : "background") + " queue");
-        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
+        return (isFg) ? mBroadcastQueues[BROADCAST_QUEUE_FG]
+                : mBroadcastQueues[BROADCAST_QUEUE_BG];
     }
 
     private volatile int mDeviceOwnerUid = INVALID_UID;
@@ -2353,9 +2378,8 @@
         mPendingStartActivityUids = new PendingStartActivityUids();
         mUseFifoUiScheduling = false;
         mEnableOffloadQueue = false;
+        mEnableModernQueue = false;
         mBroadcastQueues = new BroadcastQueue[0];
-        mFgBroadcastQueue = mBgBroadcastQueue = mBgOffloadBroadcastQueue =
-                mFgOffloadBroadcastQueue = null;
         mComponentAliasResolver = new ComponentAliasResolver(this);
     }
 
@@ -2411,20 +2435,23 @@
 
         mEnableOffloadQueue = SystemProperties.getBoolean(
                 "persist.device_config.activity_manager_native_boot.offload_queue_enabled", true);
+        mEnableModernQueue = SystemProperties.getBoolean(
+                "persist.device_config.activity_manager_native_boot.modern_queue_enabled", false);
 
-        mBroadcastQueues = new BroadcastQueue[4];
-        mFgBroadcastQueue = new BroadcastQueueImpl(this, mHandler,
-                "foreground", foreConstants, false, ProcessList.SCHED_GROUP_DEFAULT);
-        mBgBroadcastQueue = new BroadcastQueueImpl(this, mHandler,
-                "background", backConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
-        mBgOffloadBroadcastQueue = new BroadcastQueueImpl(this, mHandler,
-                "offload_bg", offloadConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
-        mFgOffloadBroadcastQueue = new BroadcastQueueImpl(this, mHandler,
-                "offload_fg", foreConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
-        mBroadcastQueues[0] = mFgBroadcastQueue;
-        mBroadcastQueues[1] = mBgBroadcastQueue;
-        mBroadcastQueues[2] = mBgOffloadBroadcastQueue;
-        mBroadcastQueues[3] = mFgOffloadBroadcastQueue;
+        if (mEnableModernQueue) {
+            mBroadcastQueues = new BroadcastQueue[1];
+            mBroadcastQueues[0] = new BroadcastQueueModernImpl(this, mHandler, foreConstants);
+        } else {
+            mBroadcastQueues = new BroadcastQueue[4];
+            mBroadcastQueues[BROADCAST_QUEUE_FG] = new BroadcastQueueImpl(this, mHandler,
+                    "foreground", foreConstants, false, ProcessList.SCHED_GROUP_DEFAULT);
+            mBroadcastQueues[BROADCAST_QUEUE_BG] = new BroadcastQueueImpl(this, mHandler,
+                    "background", backConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
+            mBroadcastQueues[BROADCAST_QUEUE_BG_OFFLOAD] = new BroadcastQueueImpl(this, mHandler,
+                    "offload_bg", offloadConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
+            mBroadcastQueues[BROADCAST_QUEUE_FG_OFFLOAD] = new BroadcastQueueImpl(this, mHandler,
+                    "offload_fg", foreConstants, true, ProcessList.SCHED_GROUP_BACKGROUND);
+        }
 
         mServices = new ActiveServices(this);
         mCpHelper = new ContentProviderHelper(this, true);
@@ -3388,12 +3415,14 @@
      * @param lastPids of dalvik VM processes to dump stack traces for last
      * @param nativePids optional list of native pids to dump stack crawls
      * @param logExceptionCreatingFile optional writer to which we log errors creating the file
+     * @param latencyTracker the latency tracker instance of the current ANR.
      */
     public static File dumpStackTraces(ArrayList<Integer> firstPids,
             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
-            ArrayList<Integer> nativePids, StringWriter logExceptionCreatingFile) {
+            ArrayList<Integer> nativePids, StringWriter logExceptionCreatingFile,
+            AnrLatencyTracker latencyTracker) {
         return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePids,
-                logExceptionCreatingFile, null, null, null);
+                logExceptionCreatingFile, null, null, null, latencyTracker);
     }
 
     /**
@@ -3404,13 +3433,14 @@
      * @param logExceptionCreatingFile optional writer to which we log errors creating the file
      * @param subject optional line related to the error
      * @param criticalEventSection optional lines containing recent critical events.
+     * @param latencyTracker the latency tracker instance of the current ANR.
      */
     public static File dumpStackTraces(ArrayList<Integer> firstPids,
             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
             ArrayList<Integer> nativePids, StringWriter logExceptionCreatingFile,
-            String subject, String criticalEventSection) {
+            String subject, String criticalEventSection, AnrLatencyTracker latencyTracker) {
         return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePids,
-                logExceptionCreatingFile, null, subject, criticalEventSection);
+                logExceptionCreatingFile, null, subject, criticalEventSection, latencyTracker);
     }
 
     /**
@@ -3420,83 +3450,97 @@
     /* package */ static File dumpStackTraces(ArrayList<Integer> firstPids,
             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
             ArrayList<Integer> nativePids, StringWriter logExceptionCreatingFile,
-            long[] firstPidOffsets, String subject, String criticalEventSection) {
-        ArrayList<Integer> extraPids = null;
-
-        Slog.i(TAG, "dumpStackTraces pids=" + lastPids + " nativepids=" + nativePids);
-
-        // Measure CPU usage as soon as we're called in order to get a realistic sampling
-        // of the top users at the time of the request.
-        if (processCpuTracker != null) {
-            processCpuTracker.init();
-            try {
-                Thread.sleep(200);
-            } catch (InterruptedException ignored) {
-            }
-
-            processCpuTracker.update();
-
-            // We'll take the stack crawls of just the top apps using CPU.
-            final int N = processCpuTracker.countWorkingStats();
-            extraPids = new ArrayList<>();
-            for (int i = 0; i < N && extraPids.size() < 5; i++) {
-                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
-                if (lastPids.indexOfKey(stats.pid) >= 0) {
-                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
-
-                    extraPids.add(stats.pid);
-                } else {
-                    Slog.i(TAG, "Skipping next CPU consuming process, not a java proc: "
-                            + stats.pid);
-                }
-            }
-        }
-
-        final File tracesDir = new File(ANR_TRACE_DIR);
-        // Each set of ANR traces is written to a separate file and dumpstate will process
-        // all such files and add them to a captured bug report if they're recent enough.
-        maybePruneOldTraces(tracesDir);
-
-        // NOTE: We should consider creating the file in native code atomically once we've
-        // gotten rid of the old scheme of dumping and lot of the code that deals with paths
-        // can be removed.
-        File tracesFile;
+            long[] firstPidOffsets, String subject, String criticalEventSection,
+            AnrLatencyTracker latencyTracker) {
         try {
-            tracesFile = createAnrDumpFile(tracesDir);
-        } catch (IOException e) {
-            Slog.w(TAG, "Exception creating ANR dump file:", e);
-            if (logExceptionCreatingFile != null) {
-                logExceptionCreatingFile.append("----- Exception creating ANR dump file -----\n");
-                e.printStackTrace(new PrintWriter(logExceptionCreatingFile));
+            if (latencyTracker != null) {
+                latencyTracker.dumpStackTracesStarted();
             }
-            return null;
-        }
+            ArrayList<Integer> extraPids = null;
 
-        if (subject != null || criticalEventSection != null) {
-            try (FileOutputStream fos = new FileOutputStream(tracesFile, true)) {
-                if (subject != null) {
-                    String header = "Subject: " + subject + "\n\n";
-                    fos.write(header.getBytes(StandardCharsets.UTF_8));
+            Slog.i(TAG, "dumpStackTraces pids=" + lastPids + " nativepids=" + nativePids);
+
+            // Measure CPU usage as soon as we're called in order to get a realistic sampling
+            // of the top users at the time of the request.
+            if (processCpuTracker != null) {
+                if (latencyTracker != null) {
+                    latencyTracker.processCpuTrackerMethodsCalled();
                 }
-                if (criticalEventSection != null) {
-                    fos.write(criticalEventSection.getBytes(StandardCharsets.UTF_8));
+                processCpuTracker.init();
+                try {
+                    Thread.sleep(200);
+                } catch (InterruptedException ignored) {
                 }
+
+                processCpuTracker.update();
+
+                // We'll take the stack crawls of just the top apps using CPU.
+                final int workingStatsNumber = processCpuTracker.countWorkingStats();
+                extraPids = new ArrayList<>();
+                for (int i = 0; i < workingStatsNumber && extraPids.size() < 5; i++) {
+                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
+                    if (lastPids.indexOfKey(stats.pid) >= 0) {
+                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
+
+                        extraPids.add(stats.pid);
+                    } else {
+                        Slog.i(TAG, "Skipping next CPU consuming process, not a java proc: "
+                                + stats.pid);
+                    }
+                }
+                if (latencyTracker != null) {
+                    latencyTracker.processCpuTrackerMethodsReturned();
+                }
+            }
+
+            final File tracesDir = new File(ANR_TRACE_DIR);
+            // Each set of ANR traces is written to a separate file and dumpstate will process
+            // all such files and add them to a captured bug report if they're recent enough.
+            maybePruneOldTraces(tracesDir);
+
+            // NOTE: We should consider creating the file in native code atomically once we've
+            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
+            // can be removed.
+            File tracesFile;
+            try {
+                tracesFile = createAnrDumpFile(tracesDir);
             } catch (IOException e) {
-                Slog.w(TAG, "Exception writing to ANR dump file:", e);
+                Slog.w(TAG, "Exception creating ANR dump file:", e);
+                if (logExceptionCreatingFile != null) {
+                    logExceptionCreatingFile.append(
+                            "----- Exception creating ANR dump file -----\n");
+                    e.printStackTrace(new PrintWriter(logExceptionCreatingFile));
+                }
+                if (latencyTracker != null) {
+                    latencyTracker.anrSkippedDumpStackTraces();
+                }
+                return null;
+            }
+
+            if (subject != null || criticalEventSection != null) {
+                appendtoANRFile(tracesFile.getAbsolutePath(),
+                        (subject != null ? "Subject: " + subject + "\n\n" : "")
+                        + criticalEventSection != null ? criticalEventSection : "");
+            }
+
+            Pair<Long, Long> offsets = dumpStackTraces(
+                    tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids, latencyTracker);
+            if (firstPidOffsets != null) {
+                if (offsets == null) {
+                    firstPidOffsets[0] = firstPidOffsets[1] = -1;
+                } else {
+                    firstPidOffsets[0] = offsets.first; // Start offset to the ANR trace file
+                    firstPidOffsets[1] = offsets.second; // End offset to the ANR trace file
+                }
+            }
+
+            return tracesFile;
+        } finally {
+            if (latencyTracker != null) {
+                latencyTracker.dumpStackTracesEnded();
             }
         }
 
-        Pair<Long, Long> offsets = dumpStackTraces(
-                tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids);
-        if (firstPidOffsets != null) {
-            if (offsets == null) {
-                firstPidOffsets[0] = firstPidOffsets[1] = -1;
-            } else {
-                firstPidOffsets[0] = offsets.first; // Start offset to the ANR trace file
-                firstPidOffsets[1] = offsets.second; // End offset to the ANR trace file
-            }
-        }
-        return tracesFile;
     }
 
     @GuardedBy("ActivityManagerService.class")
@@ -3557,6 +3601,7 @@
      */
     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
         final long timeStart = SystemClock.elapsedRealtime();
+        int headerSize = writeUptimeStartHeaderForPid(pid, fileName);
         boolean javaSuccess = Debug.dumpJavaBacktraceToFileTimeout(pid, fileName,
                 (int) (timeoutMs / 1000));
         if (javaSuccess) {
@@ -3564,7 +3609,7 @@
             // but better safe than sorry.
             try {
                 long size = new File(fileName).length();
-                if (size < JAVA_DUMP_MINIMUM_SIZE) {
+                if ((size - headerSize) < JAVA_DUMP_MINIMUM_SIZE) {
                     Slog.w(TAG, "Successfully created Java ANR file is empty!");
                     javaSuccess = false;
                 }
@@ -3584,11 +3629,32 @@
         return SystemClock.elapsedRealtime() - timeStart;
     }
 
+    private static int appendtoANRFile(String fileName, String text) {
+        try (FileOutputStream fos = new FileOutputStream(fileName, true)) {
+            byte[] header = text.getBytes(StandardCharsets.UTF_8);
+            fos.write(header);
+            return header.length;
+        } catch (IOException e) {
+            Slog.w(TAG, "Exception writing to ANR dump file:", e);
+            return 0;
+        }
+    }
+
+    /*
+     * Writes a header containing the process id and the current system uptime.
+     */
+    private static int writeUptimeStartHeaderForPid(int pid, String fileName) {
+        return appendtoANRFile(fileName, "----- dumping pid: " + pid + " at "
+            + SystemClock.uptimeMillis() + "\n");
+    }
+
+
     /**
      * @return The start/end offset of the trace of the very first PID
      */
-    public static Pair<Long, Long> dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
-            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids) {
+    public static Pair<Long, Long> dumpStackTraces(String tracesFile,
+            ArrayList<Integer> firstPids, ArrayList<Integer> nativePids,
+            ArrayList<Integer> extraPids, AnrLatencyTracker latencyTracker) {
 
         Slog.i(TAG, "Dumping to " + tracesFile);
 
@@ -3607,6 +3673,9 @@
 
         // First collect all of the stacks of the most important pids.
         if (firstPids != null) {
+            if (latencyTracker != null) {
+                latencyTracker.dumpingFirstPidsStarted();
+            }
             int num = firstPids.size();
             for (int i = 0; i < num; i++) {
                 final int pid = firstPids.get(i);
@@ -3617,10 +3686,16 @@
                     tf = new File(tracesFile);
                     firstPidStart = tf.exists() ? tf.length() : 0;
                 }
+                if (latencyTracker != null) {
+                    latencyTracker.dumpingPidStarted(pid);
+                }
 
                 Slog.i(TAG, "Collecting stacks for pid " + pid);
                 final long timeTaken = dumpJavaTracesTombstoned(pid, tracesFile,
                                                                 remainingTime);
+                if (latencyTracker != null) {
+                    latencyTracker.dumpingPidEnded();
+                }
 
                 remainingTime -= timeTaken;
                 if (remainingTime <= 0) {
@@ -3631,24 +3706,40 @@
 
                 if (firstPid) {
                     firstPidEnd = tf.length();
+                    // Full latency dump
+                    if (latencyTracker != null) {
+                        appendtoANRFile(tracesFile,
+                                latencyTracker.dumpAsCommaSeparatedArrayWithHeader());
+                    }
                 }
                 if (DEBUG_ANR) {
                     Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
                 }
             }
+            if (latencyTracker != null) {
+                latencyTracker.dumpingFirstPidsEnded();
+            }
         }
 
         // Next collect the stacks of the native pids
         if (nativePids != null) {
+            if (latencyTracker != null) {
+                latencyTracker.dumpingNativePidsStarted();
+            }
             for (int pid : nativePids) {
                 Slog.i(TAG, "Collecting stacks for native pid " + pid);
                 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
 
+                if (latencyTracker != null) {
+                    latencyTracker.dumpingPidStarted(pid);
+                }
                 final long start = SystemClock.elapsedRealtime();
                 Debug.dumpNativeBacktraceToFileTimeout(
                         pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
                 final long timeTaken = SystemClock.elapsedRealtime() - start;
-
+                if (latencyTracker != null) {
+                    latencyTracker.dumpingPidEnded();
+                }
                 remainingTime -= timeTaken;
                 if (remainingTime <= 0) {
                     Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
@@ -3660,15 +3751,25 @@
                     Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
                 }
             }
+            if (latencyTracker != null) {
+                latencyTracker.dumpingNativePidsEnded();
+            }
         }
 
         // Lastly, dump stacks for all extra PIDs from the CPU tracker.
         if (extraPids != null) {
+            if (latencyTracker != null) {
+                latencyTracker.dumpingExtraPidsStarted();
+            }
             for (int pid : extraPids) {
                 Slog.i(TAG, "Collecting stacks for extra pid " + pid);
-
+                if (latencyTracker != null) {
+                    latencyTracker.dumpingPidStarted(pid);
+                }
                 final long timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
-
+                if (latencyTracker != null) {
+                    latencyTracker.dumpingPidEnded();
+                }
                 remainingTime -= timeTaken;
                 if (remainingTime <= 0) {
                     Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
@@ -3680,8 +3781,14 @@
                     Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
                 }
             }
+            if (latencyTracker != null) {
+                latencyTracker.dumpingExtraPidsEnded();
+            }
         }
+        // Append the dumping footer with the current uptime
+        appendtoANRFile(tracesFile, "----- dumping ended at " + SystemClock.uptimeMillis() + "\n");
         Slog.i(TAG, "Done dumping");
+
         return firstPidStart >= 0 ? new Pair<>(firstPidStart, firstPidEnd) : null;
     }
 
@@ -4643,7 +4750,7 @@
                 final String packageName = app.info.packageName;
                 mHandler.post(new Runnable() {
                 @Override
-                    public void run(){
+                    public void run() {
                         try {
                             IBackupManager bm = IBackupManager.Stub.asInterface(
                                     ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -6437,7 +6544,9 @@
         TimeoutRecord timeoutRecord = TimeoutRecord.forApp("App requested: " + reason);
         final int callingPid = Binder.getCallingPid();
 
+        timeoutRecord.mLatencyTracker.waitingOnPidLockStarted();
         synchronized (mPidsSelfLocked) {
+            timeoutRecord.mLatencyTracker.waitingOnPidLockEnded();
             final ProcessRecord app = mPidsSelfLocked.get(callingPid);
             if (app == null) {
                 throw new SecurityException("Unknown process: " + callingPid);
@@ -8085,7 +8194,7 @@
         synchronized(mPidsSelfLocked) {
             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
-                if (!isAllowedWhileBooting(proc.info)){
+                if (!isAllowedWhileBooting(proc.info)) {
                     if (procsToKill == null) {
                         procsToKill = new ArrayList<ProcessRecord>();
                     }
@@ -12379,6 +12488,58 @@
     }
 
     /**
+     * Filters out non-exported components in a given list of broadcast filters
+     * @param intent the original intent
+     * @param callingUid the calling UID
+     * @param query the list of broadcast filters
+     * @param platformCompat the instance of platform compat
+     */
+    private static void filterNonExportedComponents(Intent intent, int callingUid,
+            List query, PlatformCompat platformCompat, String callerPackage) {
+        if (query == null
+                || intent.getPackage() != null
+                || intent.getComponent() != null
+                || ActivityManager.canAccessUnexportedComponents(callingUid)) {
+            return;
+        }
+        for (int i = query.size() - 1; i >= 0; i--) {
+            String componentInfo;
+            ResolveInfo resolveInfo;
+            BroadcastFilter broadcastFilter;
+            if (query.get(i) instanceof ResolveInfo) {
+                resolveInfo = (ResolveInfo) query.get(i);
+                if (resolveInfo.getComponentInfo().exported) {
+                    continue;
+                }
+                componentInfo = resolveInfo.getComponentInfo()
+                        .getComponentName().flattenToShortString();
+            } else if (query.get(i) instanceof BroadcastFilter) {
+                broadcastFilter = (BroadcastFilter) query.get(i);
+                if (broadcastFilter.exported) {
+                    continue;
+                }
+                componentInfo = broadcastFilter.packageName;
+            } else {
+                continue;
+            }
+            if (!platformCompat.isChangeEnabledByUid(
+                    IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS, callingUid)) {
+                Slog.w(TAG, "Non-exported component not filtered out "
+                        + "(will be filtered out once the app targets U+)- intent: "
+                        + intent.getAction() + ", component: "
+                        + componentInfo + ", sender: "
+                        + callerPackage);
+                return;
+            }
+            Slog.w(TAG, "Non-exported component filtered out - intent: "
+                    + intent.getAction() + ", component: "
+                    + componentInfo + ", sender: "
+                    + callerPackage);
+            query.remove(i);
+        }
+    }
+
+    /**
      * Main code for cleaning up a process when it has gone away.  This is
      * called both as a result of the process dying, or directly when stopping
      * a process when running in single process mode.
@@ -12420,7 +12581,7 @@
                     + backupTarget.appInfo + " died during backup");
             mHandler.post(new Runnable() {
                 @Override
-                public void run(){
+                public void run() {
                     try {
                         IBackupManager bm = IBackupManager.Stub.asInterface(
                                 ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -14217,6 +14378,8 @@
             }
         }
 
+        filterNonExportedComponents(intent, callingUid, registeredReceivers,
+                mPlatformCompat, callerPackage);
         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
         if (!ordered && NR > 0) {
             // If we are not serializing this broadcast, then send the
@@ -14319,6 +14482,8 @@
         if ((receivers != null && receivers.size() > 0)
                 || resultTo != null) {
             BroadcastQueue queue = broadcastQueueForIntent(intent);
+            filterNonExportedComponents(intent, callingUid, receivers,
+                    mPlatformCompat, callerPackage);
             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
                     callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
                     requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions,
@@ -14953,59 +15118,66 @@
 
     @GuardedBy("this")
     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
-        final ActiveInstrumentation instr = app.getActiveInstrumentation();
-        if (instr == null) {
-            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
-            return;
-        }
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "finishInstrumentationLocked()");
+            final ActiveInstrumentation instr = app.getActiveInstrumentation();
+            if (instr == null) {
+                Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
+                return;
+            }
 
-        synchronized (mProcLock) {
-            if (!instr.mFinished) {
-                if (instr.mWatcher != null) {
-                    Bundle finalResults = instr.mCurResults;
-                    if (finalResults != null) {
-                        if (instr.mCurResults != null && results != null) {
-                            finalResults.putAll(results);
+            synchronized (mProcLock) {
+                if (!instr.mFinished) {
+                    if (instr.mWatcher != null) {
+                        Bundle finalResults = instr.mCurResults;
+                        if (finalResults != null) {
+                            if (instr.mCurResults != null && results != null) {
+                                finalResults.putAll(results);
+                            }
+                        } else {
+                            finalResults = results;
                         }
-                    } else {
-                        finalResults = results;
+                        mInstrumentationReporter.reportFinished(instr.mWatcher,
+                                instr.mClass, resultCode, finalResults);
                     }
-                    mInstrumentationReporter.reportFinished(instr.mWatcher,
-                            instr.mClass, resultCode, finalResults);
+
+                    // Can't call out of the system process with a lock held, so post a message.
+                    if (instr.mUiAutomationConnection != null) {
+                        // Go back to the default mode of denying OP_NO_ISOLATED_STORAGE app op.
+                        mAppOpsService.setMode(AppOpsManager.OP_NO_ISOLATED_STORAGE, app.uid,
+                                app.info.packageName, AppOpsManager.MODE_ERRORED);
+                        mAppOpsService.setAppOpsServiceDelegate(null);
+                        getPermissionManagerInternal().stopShellPermissionIdentityDelegation();
+                        mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
+                                instr.mUiAutomationConnection).sendToTarget();
+                    }
+                    instr.mFinished = true;
                 }
 
-                // Can't call out of the system process with a lock held, so post a message.
-                if (instr.mUiAutomationConnection != null) {
-                    // Go back to the default mode of denying OP_NO_ISOLATED_STORAGE app op.
-                    mAppOpsService.setMode(AppOpsManager.OP_NO_ISOLATED_STORAGE, app.uid,
-                            app.info.packageName, AppOpsManager.MODE_ERRORED);
-                    mAppOpsService.setAppOpsServiceDelegate(null);
-                    getPermissionManagerInternal().stopShellPermissionIdentityDelegation();
-                    mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
-                            instr.mUiAutomationConnection).sendToTarget();
+                instr.removeProcess(app);
+                app.setActiveInstrumentation(null);
+            }
+            app.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_INSTRUMENTATION);
+
+            if (app.isSdkSandbox) {
+                // For sharedUid apps this will kill all sdk sandbox processes, which is not ideal.
+                // TODO(b/209061624): should we call ProcessList.removeProcessLocked instead?
+                killUid(UserHandle.getAppId(app.uid), UserHandle.getUserId(app.uid),
+                        "finished instr");
+                final SdkSandboxManagerLocal sandboxManagerLocal =
+                        LocalManagerRegistry.getManager(SdkSandboxManagerLocal.class);
+                if (sandboxManagerLocal != null) {
+                    sandboxManagerLocal.notifyInstrumentationFinished(
+                            app.sdkSandboxClientAppPackage,
+                            Process.getAppUidForSdkSandboxUid(app.uid));
                 }
-                instr.mFinished = true;
+            } else if (!instr.mNoRestart) {
+                forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false,
+                        app.userId,
+                        "finished inst");
             }
-
-            instr.removeProcess(app);
-            app.setActiveInstrumentation(null);
-        }
-        app.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_INSTRUMENTATION);
-
-        if (app.isSdkSandbox) {
-            // For sharedUid apps this will kill all sdk sandbox processes, which is not ideal.
-            // TODO(b/209061624): should we call ProcessList.removeProcessLocked instead?
-            killUid(UserHandle.getAppId(app.uid), UserHandle.getUserId(app.uid), "finished instr");
-            final SdkSandboxManagerLocal sandboxManagerLocal =
-                    LocalManagerRegistry.getManager(SdkSandboxManagerLocal.class);
-            if (sandboxManagerLocal != null) {
-                sandboxManagerLocal.notifyInstrumentationFinished(
-                        app.sdkSandboxClientAppPackage, Process.getAppUidForSdkSandboxUid(app.uid));
-            }
-        } else if (!instr.mNoRestart) {
-            forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false,
-                    app.userId,
-                    "finished inst");
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
@@ -17699,7 +17871,9 @@
             throw new SecurityException("Requires permission " + FILTER_EVENTS);
         }
         ProcessRecord proc;
+        timeoutRecord.mLatencyTracker.waitingOnPidLockStarted();
         synchronized (mPidsSelfLocked) {
+            timeoutRecord.mLatencyTracker.waitingOnPidLockEnded();
             proc = mPidsSelfLocked.get(pid);
         }
         final long timeoutMillis = proc != null ? proc.getInputDispatchingTimeoutMillis() :
@@ -17720,29 +17894,36 @@
             ApplicationInfo aInfo, String parentShortComponentName,
             WindowProcessController parentProcess, boolean aboveSystem,
             TimeoutRecord timeoutRecord) {
-        if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires permission " + FILTER_EVENTS);
-        }
-
-        if (proc != null) {
-            synchronized (this) {
-                if (proc.isDebugging()) {
-                    return false;
-                }
-
-                if (proc.getActiveInstrumentation() != null) {
-                    Bundle info = new Bundle();
-                    info.putString("shortMsg", "keyDispatchingTimedOut");
-                    info.putString("longMsg", timeoutRecord.mReason);
-                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
-                    return true;
-                }
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "inputDispatchingTimedOut()");
+            if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("Requires permission " + FILTER_EVENTS);
             }
-            mAnrHelper.appNotResponding(proc, activityShortComponentName, aInfo,
-                    parentShortComponentName, parentProcess, aboveSystem, timeoutRecord);
-        }
 
-        return true;
+            if (proc != null) {
+                timeoutRecord.mLatencyTracker.waitingOnAMSLockStarted();
+                synchronized (this) {
+                    timeoutRecord.mLatencyTracker.waitingOnAMSLockEnded();
+                    if (proc.isDebugging()) {
+                        return false;
+                    }
+
+                    if (proc.getActiveInstrumentation() != null) {
+                        Bundle info = new Bundle();
+                        info.putString("shortMsg", "keyDispatchingTimedOut");
+                        info.putString("longMsg", timeoutRecord.mReason);
+                        finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
+                        return true;
+                    }
+                }
+                mAnrHelper.appNotResponding(proc, activityShortComponentName, aInfo,
+                        parentShortComponentName, parentProcess, aboveSystem, timeoutRecord);
+            }
+
+            return true;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/AnrHelper.java b/services/core/java/com/android/server/am/AnrHelper.java
index f1d8353..6de4118 100644
--- a/services/core/java/com/android/server/am/AnrHelper.java
+++ b/services/core/java/com/android/server/am/AnrHelper.java
@@ -21,6 +21,7 @@
 
 import android.content.pm.ApplicationInfo;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -79,29 +80,41 @@
             ApplicationInfo aInfo, String parentShortComponentName,
             WindowProcessController parentProcess, boolean aboveSystem,
             TimeoutRecord timeoutRecord) {
-        final int incomingPid = anrProcess.mPid;
-        synchronized (mAnrRecords) {
-            if (incomingPid == 0) {
-                // Extreme corner case such as zygote is no response to return pid for the process.
-                Slog.i(TAG, "Skip zero pid ANR, process=" + anrProcess.processName);
-                return;
-            }
-            if (mProcessingPid == incomingPid) {
-                Slog.i(TAG,
-                        "Skip duplicated ANR, pid=" + incomingPid + " " + timeoutRecord.mReason);
-                return;
-            }
-            for (int i = mAnrRecords.size() - 1; i >= 0; i--) {
-                if (mAnrRecords.get(i).mPid == incomingPid) {
-                    Slog.i(TAG,
-                            "Skip queued ANR, pid=" + incomingPid + " " + timeoutRecord.mReason);
+        try {
+            timeoutRecord.mLatencyTracker.appNotRespondingStarted();
+            final int incomingPid = anrProcess.mPid;
+            timeoutRecord.mLatencyTracker.waitingOnAnrRecordLockStarted();
+            synchronized (mAnrRecords) {
+                timeoutRecord.mLatencyTracker.waitingOnAnrRecordLockEnded();
+                if (incomingPid == 0) {
+                    // Extreme corner case such as zygote is no response
+                    // to return pid for the process.
+                    Slog.i(TAG, "Skip zero pid ANR, process=" + anrProcess.processName);
                     return;
                 }
+                if (mProcessingPid == incomingPid) {
+                    Slog.i(TAG,
+                            "Skip duplicated ANR, pid=" + incomingPid + " "
+                            + timeoutRecord.mReason);
+                    return;
+                }
+                for (int i = mAnrRecords.size() - 1; i >= 0; i--) {
+                    if (mAnrRecords.get(i).mPid == incomingPid) {
+                        Slog.i(TAG,
+                                "Skip queued ANR, pid=" + incomingPid + " "
+                                + timeoutRecord.mReason);
+                        return;
+                    }
+                }
+                timeoutRecord.mLatencyTracker.anrRecordPlacingOnQueueWithSize(mAnrRecords.size());
+                mAnrRecords.add(new AnrRecord(anrProcess, activityShortComponentName, aInfo,
+                        parentShortComponentName, parentProcess, aboveSystem, timeoutRecord));
             }
-            mAnrRecords.add(new AnrRecord(anrProcess, activityShortComponentName, aInfo,
-                    parentShortComponentName, parentProcess, aboveSystem, timeoutRecord));
+            startAnrConsumerIfNeeded();
+        } finally {
+            timeoutRecord.mLatencyTracker.appNotRespondingEnded();
         }
-        startAnrConsumerIfNeeded();
+
     }
 
     private void startAnrConsumerIfNeeded() {
@@ -126,6 +139,8 @@
                 }
                 final AnrRecord record = mAnrRecords.remove(0);
                 mProcessingPid = record.mPid;
+                record.mTimeoutRecord.mLatencyTracker.anrRecordsQueueSizeWhenPopped(
+                        mAnrRecords.size());
                 return record;
             }
         }
@@ -143,8 +158,8 @@
                     continue;
                 }
                 final long startTime = SystemClock.uptimeMillis();
-                // If there are many ANR at the same time, the latency may be larger. If the latency
-                // is too large, the stack trace might not be meaningful.
+                // If there are many ANR at the same time, the latency may be larger.
+                // If the latency is too large, the stack trace might not be meaningful.
                 final long reportLatency = startTime - r.mTimestamp;
                 final boolean onlyDumpSelf = reportLatency > EXPIRED_REPORT_TIME_MS;
                 r.appNotResponding(onlyDumpSelf);
@@ -167,11 +182,17 @@
     }
 
     private void scheduleBinderHeavyHitterAutoSamplerIfNecessary() {
-        final long now = SystemClock.uptimeMillis();
-        if (mLastAnrTimeMs + CONSECUTIVE_ANR_TIME_MS > now) {
-            mService.scheduleBinderHeavyHitterAutoSampler();
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    "scheduleBinderHeavyHitterAutoSamplerIfNecessary()");
+            final long now = SystemClock.uptimeMillis();
+            if (mLastAnrTimeMs + CONSECUTIVE_ANR_TIME_MS > now) {
+                mService.scheduleBinderHeavyHitterAutoSampler();
+            }
+            mLastAnrTimeMs = now;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
-        mLastAnrTimeMs = now;
     }
 
     private static class AnrRecord {
@@ -184,7 +205,6 @@
         final WindowProcessController mParentProcess;
         final boolean mAboveSystem;
         final long mTimestamp = SystemClock.uptimeMillis();
-
         AnrRecord(ProcessRecord anrProcess, String activityShortComponentName,
                 ApplicationInfo aInfo, String parentShortComponentName,
                 WindowProcessController parentProcess, boolean aboveSystem,
@@ -200,10 +220,14 @@
         }
 
         void appNotResponding(boolean onlyDumpSelf) {
-            mApp.mErrorState.appNotResponding(mActivityShortComponentName, mAppInfo,
-                    mParentShortComponentName, mParentProcess, mAboveSystem,
-                    mTimeoutRecord,
-                    onlyDumpSelf);
+            try {
+                mTimeoutRecord.mLatencyTracker.anrProcessingStarted();
+                mApp.mErrorState.appNotResponding(mActivityShortComponentName, mAppInfo,
+                        mParentShortComponentName, mParentProcess, mAboveSystem,
+                        mTimeoutRecord, onlyDumpSelf);
+            } finally {
+                mTimeoutRecord.mLatencyTracker.anrProcessingEnded();
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
new file mode 100644
index 0000000..c18c65e
--- /dev/null
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static com.android.server.am.BroadcastQueue.checkState;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UptimeMillisLong;
+import android.os.UserHandle;
+import android.util.IndentingPrintWriter;
+
+import com.android.internal.os.SomeArgs;
+
+import java.util.ArrayDeque;
+
+/**
+ * Queue of pending {@link BroadcastRecord} entries intended for delivery to a
+ * specific process.
+ * <p>
+ * Each queue has a concept of being "runnable at" a particular time in the
+ * future, which supports arbitrarily pausing or delaying delivery on a
+ * per-process basis.
+ * <p>
+ * Internally each queue consists of a pending broadcasts which are waiting to
+ * be dispatched, and a single active broadcast which is currently being
+ * dispatched.
+ */
+class BroadcastProcessQueue implements Comparable<BroadcastProcessQueue> {
+    /**
+     * Default delay to apply to background broadcasts, giving a chance for
+     * debouncing of rapidly changing events.
+     */
+    // TODO: shift hard-coded defaults to BroadcastConstants
+    private static final long DELAY_DEFAULT_MILLIS = 10_000;
+
+    /**
+     * Default delay to apply to broadcasts targeting cached applications.
+     */
+    // TODO: shift hard-coded defaults to BroadcastConstants
+    private static final long DELAY_CACHED_MILLIS = 30_000;
+
+    final @NonNull String processName;
+    final int uid;
+
+    /**
+     * Linked list connection to another process under this {@link #uid} which
+     * has a different {@link #processName}.
+     */
+    @Nullable BroadcastProcessQueue next;
+
+    /**
+     * Currently known details about the target process; typically undefined
+     * when the process isn't actively running.
+     */
+    @Nullable ProcessRecord app;
+
+    /**
+     * Ordered collection of broadcasts that are waiting to be dispatched to
+     * this process, as a pair of {@link BroadcastRecord} and the index into
+     * {@link BroadcastRecord#receivers} that represents the receiver.
+     */
+    private final ArrayDeque<SomeArgs> mPending = new ArrayDeque<>();
+
+    /**
+     * Broadcast actively being dispatched to this process.
+     */
+    private @Nullable BroadcastRecord mActive;
+
+    /**
+     * Receiver actively being dispatched to in this process. This is an index
+     * into the {@link BroadcastRecord#receivers} list of {@link #mActive}.
+     */
+    private int mActiveIndex;
+
+    private int mCountForeground;
+    private int mCountOrdered;
+    private int mCountAlarm;
+
+    private @UptimeMillisLong long mRunnableAt = Long.MAX_VALUE;
+    private boolean mRunnableAtInvalidated;
+
+    private boolean mProcessCached;
+
+    public BroadcastProcessQueue(@NonNull String processName, int uid) {
+        this.processName = processName;
+        this.uid = uid;
+    }
+
+    /**
+     * Enqueue the given broadcast to be dispatched to this process at some
+     * future point in time. The target receiver is indicated by the given index
+     * into {@link BroadcastRecord#receivers}.
+     */
+    public void enqueueBroadcast(@NonNull BroadcastRecord record, int recordIndex) {
+        // Detect situations where the incoming broadcast should cause us to
+        // recalculate when we'll be runnable
+        if (mPending.isEmpty()) {
+            invalidateRunnableAt();
+        }
+        if (record.isForeground()) {
+            mCountForeground++;
+            invalidateRunnableAt();
+        }
+        if (record.ordered) {
+            mCountOrdered++;
+            invalidateRunnableAt();
+        }
+        if (record.alarm) {
+            mCountAlarm++;
+            invalidateRunnableAt();
+        }
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = record;
+        args.argi1 = recordIndex;
+        mPending.addLast(args);
+    }
+
+    /**
+     * Update if this process is in the "cached" state, typically signaling that
+     * broadcast dispatch should be paused or delayed.
+     */
+    public void setProcessCached(boolean cached) {
+        if (mProcessCached != cached) {
+            mProcessCached = cached;
+            invalidateRunnableAt();
+        }
+    }
+
+    /**
+     * Return if we know of an actively running "warm" process for this queue.
+     */
+    public boolean isProcessWarm() {
+        return (app != null) && (app.getThread() != null) && !app.isKilled();
+    }
+
+    public int getPreferredSchedulingGroupLocked() {
+        if (mCountForeground > 0 || mCountOrdered > 0 || mCountAlarm > 0) {
+            // We have an important broadcast somewhere down the queue, so
+            // boost priority until we drain them all
+            return ProcessList.SCHED_GROUP_DEFAULT;
+        } else if ((mActive != null)
+                && (mActive.isForeground() || mActive.ordered || mActive.alarm)) {
+            // We have an important broadcast right now, so boost priority
+            return ProcessList.SCHED_GROUP_DEFAULT;
+        } else {
+            return ProcessList.SCHED_GROUP_BACKGROUND;
+        }
+    }
+
+    /**
+     * Set the currently active broadcast to the next pending broadcast.
+     */
+    public void makeActiveNextPending() {
+        // TODO: what if the next broadcast isn't runnable yet?
+        checkState(isRunnable(), "isRunnable");
+        final SomeArgs next = mPending.removeFirst();
+        mActive = (BroadcastRecord) next.arg1;
+        mActiveIndex = next.argi1;
+        next.recycle();
+        if (mActive.isForeground()) {
+            mCountForeground--;
+        }
+        if (mActive.ordered) {
+            mCountOrdered--;
+        }
+        if (mActive.alarm) {
+            mCountAlarm--;
+        }
+        invalidateRunnableAt();
+    }
+
+    /**
+     * Set the currently running broadcast to be idle.
+     */
+    public void makeActiveIdle() {
+        mActive = null;
+        mActiveIndex = 0;
+    }
+
+    public void setActiveDeliveryState(int deliveryState) {
+        checkState(isActive(), "isActive");
+        mActive.setDeliveryState(mActiveIndex, deliveryState);
+    }
+
+    public @NonNull BroadcastRecord getActive() {
+        checkState(isActive(), "isActive");
+        return mActive;
+    }
+
+    public @NonNull Object getActiveReceiver() {
+        checkState(isActive(), "isActive");
+        return mActive.receivers.get(mActiveIndex);
+    }
+
+    public boolean isActive() {
+        return mActive != null;
+    }
+
+    public boolean isRunnable() {
+        if (mRunnableAtInvalidated) updateRunnableAt();
+        return mRunnableAt != Long.MAX_VALUE;
+    }
+
+    /**
+     * Return time at which this process is considered runnable. This is
+     * typically the time at which the next pending broadcast was first
+     * enqueued, but it also reflects any pauses or delays that should be
+     * applied to the process.
+     * <p>
+     * Returns {@link Long#MAX_VALUE} when this queue isn't currently runnable,
+     * typically when the queue is empty or when paused.
+     */
+    public @UptimeMillisLong long getRunnableAt() {
+        if (mRunnableAtInvalidated) updateRunnableAt();
+        return mRunnableAt;
+    }
+
+    private void invalidateRunnableAt() {
+        mRunnableAtInvalidated = true;
+    }
+
+    /**
+     * Update {@link #getRunnableAt()} if it's currently invalidated.
+     */
+    private void updateRunnableAt() {
+        final SomeArgs next = mPending.peekFirst();
+        if (next != null) {
+            final long runnableAt = ((BroadcastRecord) next.arg1).enqueueTime;
+            if (mCountForeground > 0) {
+                mRunnableAt = runnableAt;
+            } else if (mCountOrdered > 0) {
+                mRunnableAt = runnableAt;
+            } else if (mCountAlarm > 0) {
+                mRunnableAt = runnableAt;
+            } else if (mProcessCached) {
+                mRunnableAt = runnableAt + DELAY_CACHED_MILLIS;
+            } else {
+                mRunnableAt = runnableAt + DELAY_DEFAULT_MILLIS;
+            }
+        } else {
+            mRunnableAt = Long.MAX_VALUE;
+        }
+    }
+
+    @Override
+    public int compareTo(BroadcastProcessQueue o) {
+        if (mRunnableAtInvalidated) updateRunnableAt();
+        if (o.mRunnableAtInvalidated) o.updateRunnableAt();
+        return Long.compare(mRunnableAt, o.mRunnableAt);
+    }
+
+    @Override
+    public String toString() {
+        return "BroadcastProcessQueue{"
+                + Integer.toHexString(System.identityHashCode(this))
+                + " " + processName + "/" + UserHandle.formatUid(uid) + "}";
+    }
+
+    public String toShortString() {
+        return processName + "/" + UserHandle.formatUid(uid);
+    }
+
+    public void dumpLocked(@NonNull IndentingPrintWriter pw) {
+        if ((mActive == null) && mPending.isEmpty()) return;
+
+        pw.println(toShortString());
+        pw.increaseIndent();
+        if (mActive != null) {
+            pw.print("🏃 ");
+            pw.print(mActive.toShortString());
+            pw.print(' ');
+            pw.println(mActive.receivers.get(mActiveIndex));
+        }
+        for (SomeArgs args : mPending) {
+            final BroadcastRecord r = (BroadcastRecord) args.arg1;
+            pw.print("\u3000 ");
+            pw.print(r.toShortString());
+            pw.print(' ');
+            pw.println(r.receivers.get(args.argi1));
+        }
+        pw.decreaseIndent();
+    }
+}
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 6814509..e6c446a 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
+import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
@@ -59,6 +60,16 @@
         mConstants.startObserving(mHandler, resolver);
     }
 
+    static void checkState(boolean state, String msg) {
+        if (!state) {
+            Slog.wtf(TAG, msg, new Throwable());
+        }
+    }
+
+    static void logv(String msg) {
+        Slog.v(TAG, msg);
+    }
+
     @Override
     public String toString() {
         return mQueueName;
@@ -74,6 +85,7 @@
      *         otherwise {@link ProcessList#SCHED_GROUP_UNDEFINED} if this queue
      *         has no opinion.
      */
+    @GuardedBy("mService")
     public abstract int getPreferredSchedulingGroupLocked(@NonNull ProcessRecord app);
 
     /**
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index 56112cf..169f857 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -58,7 +58,6 @@
 import android.content.pm.UserInfo;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerExemptionManager.ReasonCode;
@@ -1409,7 +1408,7 @@
                 info.activityInfo.applicationInfo, true,
                 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
                 new HostingRecord(HostingRecord.HOSTING_TYPE_BROADCAST, r.curComponent,
-                        r.intent.getAction(), getHostingRecordTriggerType(r)),
+                        r.intent.getAction(), r.getHostingRecordTriggerType()),
                 isActivityCapable ? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE : ZYGOTE_POLICY_FLAG_EMPTY,
                 (r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false);
         if (r.curApp == null) {
@@ -1432,17 +1431,6 @@
         mPendingBroadcastRecvIndex = recIdx;
     }
 
-    private String getHostingRecordTriggerType(BroadcastRecord r) {
-        if (r.alarm) {
-            return HostingRecord.TRIGGER_TYPE_ALARM;
-        } else if (r.pushMessage) {
-            return HostingRecord.TRIGGER_TYPE_PUSH_MESSAGE;
-        } else if (r.pushMessageOverQuota) {
-            return HostingRecord.TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA;
-        }
-        return HostingRecord.TRIGGER_TYPE_UNKNOWN;
-    }
-
     @Nullable
     private String getTargetPackage(BroadcastRecord r) {
         if (r.intent == null) {
@@ -1566,110 +1554,116 @@
         if (mDispatcher.isEmpty() || mDispatcher.getActiveBroadcastLocked() == null) {
             return;
         }
-
-        long now = SystemClock.uptimeMillis();
-        BroadcastRecord r = mDispatcher.getActiveBroadcastLocked();
-        if (fromMsg) {
-            if (!mService.mProcessesReady) {
-                // Only process broadcast timeouts if the system is ready; some early
-                // broadcasts do heavy work setting up system facilities
-                return;
-            }
-
-            // If the broadcast is generally exempt from timeout tracking, we're done
-            if (r.timeoutExempt) {
-                if (DEBUG_BROADCAST) {
-                    Slog.i(TAG_BROADCAST, "Broadcast timeout but it's exempt: "
-                            + r.intent.getAction());
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastTimeoutLocked()");
+        try {
+            long now = SystemClock.uptimeMillis();
+            BroadcastRecord r = mDispatcher.getActiveBroadcastLocked();
+            if (fromMsg) {
+                if (!mService.mProcessesReady) {
+                    // Only process broadcast timeouts if the system is ready; some early
+                    // broadcasts do heavy work setting up system facilities
+                    return;
                 }
-                return;
-            }
 
-            long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
-            if (timeoutTime > now) {
-                // We can observe premature timeouts because we do not cancel and reset the
-                // broadcast timeout message after each receiver finishes.  Instead, we set up
-                // an initial timeout then kick it down the road a little further as needed
-                // when it expires.
-                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
-                        "Premature timeout ["
-                        + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
-                        + timeoutTime);
-                setBroadcastTimeoutLocked(timeoutTime);
-                return;
-            }
-        }
-
-        if (r.state == BroadcastRecord.WAITING_SERVICES) {
-            // In this case the broadcast had already finished, but we had decided to wait
-            // for started services to finish as well before going on.  So if we have actually
-            // waited long enough time timeout the broadcast, let's give up on the whole thing
-            // and just move on to the next.
-            Slog.i(TAG, "Waited long enough for: " + (r.curComponent != null
-                    ? r.curComponent.flattenToShortString() : "(null)"));
-            r.curComponent = null;
-            r.state = BroadcastRecord.IDLE;
-            processNextBroadcastLocked(false, false);
-            return;
-        }
-
-        // If the receiver app is being debugged we quietly ignore unresponsiveness, just
-        // tidying up and moving on to the next broadcast without crashing or ANRing this
-        // app just because it's stopped at a breakpoint.
-        final boolean debugging = (r.curApp != null && r.curApp.isDebugging());
-
-        long timeoutDurationMs = now - r.receiverTime;
-        Slog.w(TAG, "Timeout of broadcast " + r + " - curFilter=" + r.curFilter + " curReceiver="
-                + r.curReceiver + ", started " + timeoutDurationMs + "ms ago");
-        r.receiverTime = now;
-        if (!debugging) {
-            r.anrCount++;
-        }
-
-        ProcessRecord app = null;
-        TimeoutRecord timeoutRecord = null;
-
-        Object curReceiver;
-        if (r.nextReceiver > 0) {
-            curReceiver = r.receivers.get(r.nextReceiver-1);
-            r.delivery[r.nextReceiver-1] = BroadcastRecord.DELIVERY_TIMEOUT;
-        } else {
-            curReceiver = r.curReceiver;
-        }
-        Slog.w(TAG, "Receiver during timeout of " + r + " : " + curReceiver);
-        logBroadcastReceiverDiscardLocked(r);
-        if (curReceiver != null && curReceiver instanceof BroadcastFilter) {
-            BroadcastFilter bf = (BroadcastFilter)curReceiver;
-            if (bf.receiverList.pid != 0
-                    && bf.receiverList.pid != ActivityManagerService.MY_PID) {
-                synchronized (mService.mPidsSelfLocked) {
-                    app = mService.mPidsSelfLocked.get(
-                            bf.receiverList.pid);
+                // If the broadcast is generally exempt from timeout tracking, we're done
+                if (r.timeoutExempt) {
+                    if (DEBUG_BROADCAST) {
+                        Slog.i(TAG_BROADCAST, "Broadcast timeout but it's exempt: "
+                                + r.intent.getAction());
+                    }
+                    return;
+                }
+                long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
+                if (timeoutTime > now) {
+                    // We can observe premature timeouts because we do not cancel and reset the
+                    // broadcast timeout message after each receiver finishes.  Instead, we set up
+                    // an initial timeout then kick it down the road a little further as needed
+                    // when it expires.
+                    if (DEBUG_BROADCAST) {
+                        Slog.v(TAG_BROADCAST,
+                                "Premature timeout ["
+                                + mQueueName + "] @ " + now
+                                + ": resetting BROADCAST_TIMEOUT_MSG for "
+                                + timeoutTime);
+                    }
+                    setBroadcastTimeoutLocked(timeoutTime);
+                    return;
                 }
             }
-        } else {
-            app = r.curApp;
-        }
 
-        if (app != null) {
+            if (r.state == BroadcastRecord.WAITING_SERVICES) {
+                // In this case the broadcast had already finished, but we had decided to wait
+                // for started services to finish as well before going on.  So if we have actually
+                // waited long enough time timeout the broadcast, let's give up on the whole thing
+                // and just move on to the next.
+                Slog.i(TAG, "Waited long enough for: " + (r.curComponent != null
+                        ? r.curComponent.flattenToShortString() : "(null)"));
+                r.curComponent = null;
+                r.state = BroadcastRecord.IDLE;
+                processNextBroadcastLocked(false, false);
+                return;
+            }
+
+            // If the receiver app is being debugged we quietly ignore unresponsiveness, just
+            // tidying up and moving on to the next broadcast without crashing or ANRing this
+            // app just because it's stopped at a breakpoint.
+            final boolean debugging = (r.curApp != null && r.curApp.isDebugging());
+
+            long timeoutDurationMs = now - r.receiverTime;
+            Slog.w(TAG, "Timeout of broadcast " + r + " - curFilter=" + r.curFilter
+                    + " curReceiver=" + r.curReceiver + ", started " + timeoutDurationMs
+                    + "ms ago");
+            r.receiverTime = now;
+            if (!debugging) {
+                r.anrCount++;
+            }
+
+            ProcessRecord app = null;
+            Object curReceiver;
+            if (r.nextReceiver > 0) {
+                curReceiver = r.receivers.get(r.nextReceiver - 1);
+                r.delivery[r.nextReceiver - 1] = BroadcastRecord.DELIVERY_TIMEOUT;
+            } else {
+                curReceiver = r.curReceiver;
+            }
+            Slog.w(TAG, "Receiver during timeout of " + r + " : " + curReceiver);
+            logBroadcastReceiverDiscardLocked(r);
             String anrMessage =
-                    "Broadcast of " + r.intent.toString() + ", waited " + timeoutDurationMs
-                            + "ms";
-            timeoutRecord = TimeoutRecord.forBroadcastReceiver(anrMessage);
+                    "Broadcast of " + r.intent.toString() + ", waited " + timeoutDurationMs + "ms";
+            TimeoutRecord timeoutRecord = TimeoutRecord.forBroadcastReceiver(anrMessage);
+            if (curReceiver != null && curReceiver instanceof BroadcastFilter) {
+                BroadcastFilter bf = (BroadcastFilter) curReceiver;
+                if (bf.receiverList.pid != 0
+                        && bf.receiverList.pid != ActivityManagerService.MY_PID) {
+                    timeoutRecord.mLatencyTracker.waitingOnPidLockStarted();
+                    synchronized (mService.mPidsSelfLocked) {
+                        timeoutRecord.mLatencyTracker.waitingOnPidLockEnded();
+                        app = mService.mPidsSelfLocked.get(
+                                bf.receiverList.pid);
+                    }
+                }
+            } else {
+                app = r.curApp;
+            }
+
+            if (mPendingBroadcast == r) {
+                mPendingBroadcast = null;
+            }
+
+            // Move on to the next receiver.
+            finishReceiverLocked(r, r.resultCode, r.resultData,
+                    r.resultExtras, r.resultAbort, false);
+            scheduleBroadcastsLocked();
+
+            // The ANR should only be triggered if we have a process record (app is non-null)
+            if (!debugging && app != null) {
+                mService.mAnrHelper.appNotResponding(app, timeoutRecord);
+            }
+
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
 
-        if (mPendingBroadcast == r) {
-            mPendingBroadcast = null;
-        }
-
-        // Move on to the next receiver.
-        finishReceiverLocked(r, r.resultCode, r.resultData,
-                r.resultExtras, r.resultAbort, false);
-        scheduleBroadcastsLocked();
-
-        if (!debugging && timeoutRecord != null) {
-            mService.mAnrHelper.appNotResponding(app, timeoutRecord);
-        }
     }
 
     private final void addBroadcastToHistoryLocked(BroadcastRecord original) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
new file mode 100644
index 0000000..b5e7b86
--- /dev/null
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -0,0 +1,649 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
+import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE;
+
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
+import static com.android.server.am.BroadcastRecord.getReceiverProcessName;
+import static com.android.server.am.BroadcastRecord.getReceiverUid;
+import static com.android.server.am.OomAdjuster.OOM_ADJ_REASON_START_RECEIVER;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.IApplicationThread;
+import android.app.RemoteServiceException.CannotDeliverBroadcastException;
+import android.app.UidObserver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.IndentingPrintWriter;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Alternative {@link BroadcastQueue} implementation which pivots broadcasts to
+ * be dispatched on a per-process basis.
+ * <p>
+ * Each process now has its own broadcast queue represented by a
+ * {@link BroadcastProcessQueue} instance. Each queue has a concept of being
+ * "runnable at" a particular time in the future, which supports arbitrarily
+ * pausing or delaying delivery on a per-process basis.
+ */
+class BroadcastQueueModernImpl extends BroadcastQueue {
+    BroadcastQueueModernImpl(ActivityManagerService service, Handler handler,
+            BroadcastConstants constants) {
+        this(service, handler, constants, new BroadcastSkipPolicy(service),
+                new BroadcastHistory());
+    }
+
+    BroadcastQueueModernImpl(ActivityManagerService service, Handler handler,
+            BroadcastConstants constants, BroadcastSkipPolicy skipPolicy,
+            BroadcastHistory history) {
+        super(service, handler, "modern", constants, skipPolicy, history);
+        mLocalHandler = new Handler(handler.getLooper(), mLocalCallback);
+    }
+
+    // TODO: add support for ordered broadcasts
+    // TODO: add support for replacing pending broadcasts
+    // TODO: add support for merging pending broadcasts
+
+    // TODO: add trace points for debugging broadcast flows
+    // TODO: record broadcast state change timing statistics
+    // TODO: record historical broadcast statistics
+
+    // TODO: pause queues for apps involved in backup/restore
+    // TODO: pause queues when background services are running
+    // TODO: pause queues when processes are frozen
+
+    // TODO: clean up queues for removed apps
+
+    /**
+     * Maximum number of process queues to dispatch broadcasts to
+     * simultaneously.
+     */
+    // TODO: shift hard-coded defaults to BroadcastConstants
+    private static final int MAX_RUNNING_PROCESS_QUEUES = 4;
+
+    /**
+     * Map from UID to per-process broadcast queues. If a UID hosts more than
+     * one process, each additional process is stored as a linked list using
+     * {@link BroadcastProcessQueue#next}.
+     *
+     * @see #getProcessQueue
+     * @see #getOrCreateProcessQueue
+     */
+    @GuardedBy("mService")
+    private final SparseArray<BroadcastProcessQueue> mProcessQueues = new SparseArray<>();
+
+    /**
+     * Collection of queues which are "runnable". They're sorted by
+     * {@link BroadcastProcessQueue#getRunnableAt()} so that we prefer
+     * dispatching of longer-waiting broadcasts first.
+     */
+    @GuardedBy("mService")
+    private final ArrayList<BroadcastProcessQueue> mRunnable = new ArrayList<>();
+
+    /**
+     * Collection of queues which are "running". This will never be larger than
+     * {@link #MAX_RUNNING_PROCESS_QUEUES}.
+     */
+    @GuardedBy("mService")
+    private final ArrayList<BroadcastProcessQueue> mRunning = new ArrayList<>();
+
+    /**
+     * Single queue which is "running" but is awaiting a cold start to be
+     * completed via {@link #onApplicationAttachedLocked}. To optimize for
+     * system health we only request one cold start at a time.
+     */
+    @GuardedBy("mService")
+    private @Nullable BroadcastProcessQueue mRunningColdStart;
+
+    /**
+     * Collection of latches waiting for queue to go idle.
+     */
+    @GuardedBy("mService")
+    private final ArrayList<CountDownLatch> mWaitingForIdle = new ArrayList<>();
+
+    private static final int MSG_UPDATE_RUNNING_LIST = 1;
+
+    private void enqueueUpdateRunningList() {
+        mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST);
+        mLocalHandler.sendEmptyMessage(MSG_UPDATE_RUNNING_LIST);
+    }
+
+    private final Handler mLocalHandler;
+
+    private final Handler.Callback mLocalCallback = (msg) -> {
+        switch (msg.what) {
+            case MSG_UPDATE_RUNNING_LIST: {
+                synchronized (mService) {
+                    updateRunningList();
+                }
+                return true;
+            }
+        }
+        return false;
+    };
+
+    /**
+     * Consider updating the list of "runnable" queues, specifically with
+     * relation to the given queue.
+     * <p>
+     * Typically called when {@link BroadcastProcessQueue#getRunnableAt()} might
+     * have changed, since that influences the order in which we'll promote a
+     * "runnable" queue to be "running."
+     */
+    @GuardedBy("mService")
+    private void updateRunnableList(@NonNull BroadcastProcessQueue queue) {
+        if (mRunning.contains(queue)) {
+            // Already running; they'll be reinserted into the runnable list
+            // once they finish running, so no need to update them now
+            return;
+        }
+
+        // TODO: better optimize by using insertion sort data structure
+        mRunnable.remove(queue);
+        if (queue.isRunnable()) {
+            mRunnable.add(queue);
+        }
+        mRunnable.sort(null);
+    }
+
+    /**
+     * Consider updating the list of "running" queues.
+     * <p>
+     * This method can promote "runnable" queues to become "running", subject to
+     * a maximum of {@link #MAX_RUNNING_PROCESS_QUEUES} warm processes and only
+     * one pending cold-start.
+     */
+    @GuardedBy("mService")
+    private void updateRunningList() {
+        int avail = MAX_RUNNING_PROCESS_QUEUES - mRunning.size();
+        if (avail == 0) return;
+
+        // If someone is waiting to go idle, everything is runnable now
+        final boolean waitingForIdle = !mWaitingForIdle.isEmpty();
+
+        // We're doing an update now, so remove any future update requests;
+        // we'll repost below if needed
+        mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST);
+
+        boolean updateOomAdj = false;
+        final long now = SystemClock.uptimeMillis();
+        for (int i = 0; i < mRunnable.size() && avail > 0; i++) {
+            final BroadcastProcessQueue queue = mRunnable.get(i);
+            final long runnableAt = queue.getRunnableAt();
+
+            // If queues beyond this point aren't ready to run yet, schedule
+            // another pass when they'll be runnable
+            if (runnableAt > now && !waitingForIdle) {
+                mLocalHandler.sendEmptyMessageAtTime(MSG_UPDATE_RUNNING_LIST, runnableAt);
+                break;
+            }
+
+            // We might not have heard about a newly running process yet, so
+            // consider refreshing if we think we're cold
+            updateWarmProcess(queue);
+
+            final boolean processWarm = queue.isProcessWarm();
+            if (!processWarm) {
+                // We only offer to run one cold-start at a time to preserve
+                // system resources; below we either claim that single slot or
+                // skip to look for another warm process
+                if (mRunningColdStart == null) {
+                    mRunningColdStart = queue;
+                } else {
+                    continue;
+                }
+            }
+
+            if (DEBUG_BROADCAST) logv("Promoting " + queue
+                    + " from runnable to running; process is " + queue.app);
+
+            // Allocate this available permit and start running!
+            mRunnable.remove(i);
+            mRunning.add(queue);
+            avail--;
+            i--;
+
+            queue.makeActiveNextPending();
+
+            // If we're already warm, schedule it; otherwise we'll wait for the
+            // cold start to circle back around
+            if (processWarm) {
+                scheduleReceiverWarmLocked(queue);
+            } else {
+                scheduleReceiverColdLocked(queue);
+            }
+
+            mService.enqueueOomAdjTargetLocked(queue.app);
+            updateOomAdj = true;
+        }
+
+        if (updateOomAdj) {
+            mService.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_START_RECEIVER);
+        }
+
+        if (waitingForIdle && isIdleLocked()) {
+            mWaitingForIdle.forEach((latch) -> latch.countDown());
+            mWaitingForIdle.clear();
+        }
+    }
+
+    @Override
+    public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app) {
+        boolean didSomething = false;
+        if ((mRunningColdStart != null) && (mRunningColdStart.app == app)) {
+            // We've been waiting for this app to cold start, and it's ready
+            // now; dispatch its next broadcast and clear the slot
+            scheduleReceiverWarmLocked(mRunningColdStart);
+            mRunningColdStart = null;
+
+            // We might be willing to kick off another cold start
+            enqueueUpdateRunningList();
+            didSomething = true;
+        }
+        return didSomething;
+    }
+
+    @Override
+    public boolean onApplicationTimeoutLocked(@NonNull ProcessRecord app) {
+        return onApplicationCleanupLocked(app);
+    }
+
+    @Override
+    public boolean onApplicationProblemLocked(@NonNull ProcessRecord app) {
+        return onApplicationCleanupLocked(app);
+    }
+
+    @Override
+    public boolean onApplicationCleanupLocked(@NonNull ProcessRecord app) {
+        boolean didSomething = false;
+        if ((mRunningColdStart != null) && (mRunningColdStart.app == app)) {
+            // We've been waiting for this app to cold start, and it had
+            // trouble; clear the slot and fail delivery below
+            mRunningColdStart = null;
+
+            // We might be willing to kick off another cold start
+            enqueueUpdateRunningList();
+            didSomething = true;
+        }
+
+        final BroadcastProcessQueue queue = getProcessQueue(app);
+        if (queue != null) {
+            queue.app = null;
+
+            // If queue was running a broadcast, fail it
+            if (queue.isActive()) {
+                finishReceiverLocked(queue, BroadcastRecord.DELIVERY_FAILURE);
+                didSomething = true;
+            }
+        }
+
+        return didSomething;
+    }
+
+    @Override
+    public int getPreferredSchedulingGroupLocked(@NonNull ProcessRecord app) {
+        final BroadcastProcessQueue queue = getProcessQueue(app);
+        if ((queue != null) && mRunning.contains(queue)) {
+            return queue.getPreferredSchedulingGroupLocked();
+        }
+        return ProcessList.SCHED_GROUP_UNDEFINED;
+    }
+
+    @Override
+    public void enqueueBroadcastLocked(@NonNull BroadcastRecord r) {
+        // TODO: handle empty receivers to deliver result immediately
+        if (r.receivers == null) return;
+
+        r.enqueueTime = SystemClock.uptimeMillis();
+        r.enqueueRealTime = SystemClock.elapsedRealtime();
+        r.enqueueClockTime = System.currentTimeMillis();
+
+        for (int i = 0; i < r.receivers.size(); i++) {
+            final Object receiver = r.receivers.get(i);
+            final BroadcastProcessQueue queue = getOrCreateProcessQueue(
+                    getReceiverProcessName(receiver), getReceiverUid(receiver));
+            queue.enqueueBroadcast(r, i);
+            updateRunnableList(queue);
+            enqueueUpdateRunningList();
+        }
+    }
+
+    private void scheduleReceiverColdLocked(@NonNull BroadcastProcessQueue queue) {
+        checkState(queue.isActive(), "isActive");
+
+        final BroadcastRecord r = queue.getActive();
+        final Object receiver = queue.getActiveReceiver();
+
+        final ApplicationInfo info = ((ResolveInfo) receiver).activityInfo.applicationInfo;
+        final ComponentName component = ((ResolveInfo) receiver).activityInfo.getComponentName();
+
+        final int intentFlags = r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND;
+        final HostingRecord hostingRecord = new HostingRecord(HostingRecord.HOSTING_TYPE_BROADCAST,
+                component, r.intent.getAction(), r.getHostingRecordTriggerType());
+        final boolean isActivityCapable = (r.options != null
+                && r.options.getTemporaryAppAllowlistDuration() > 0);
+        final int zygotePolicyFlags = isActivityCapable ? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE
+                : ZYGOTE_POLICY_FLAG_EMPTY;
+        final boolean allowWhileBooting = (r.intent.getFlags()
+                & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0;
+
+        if (DEBUG_BROADCAST) logv("Scheduling " + r + " to cold " + queue);
+        queue.app = mService.startProcessLocked(queue.processName, info, true, intentFlags,
+                hostingRecord, zygotePolicyFlags, allowWhileBooting, false);
+        if (queue.app == null) {
+            mRunningColdStart = null;
+            finishReceiverLocked(queue, BroadcastRecord.DELIVERY_FAILURE);
+        }
+    }
+
+    private void scheduleReceiverWarmLocked(@NonNull BroadcastProcessQueue queue) {
+        checkState(queue.isActive(), "isActive");
+
+        final ProcessRecord app = queue.app;
+        final BroadcastRecord r = queue.getActive();
+        final Object receiver = queue.getActiveReceiver();
+
+        // TODO: schedule ANR timeout trigger event
+        // TODO: apply temp allowlist exemptions
+        // TODO: apply background activity launch exemptions
+
+        if (mSkipPolicy.shouldSkip(r, receiver)) {
+            finishReceiverLocked(queue, BroadcastRecord.DELIVERY_SKIPPED);
+            return;
+        }
+
+        final Intent receiverIntent = r.getReceiverIntent(receiver);
+        if (receiverIntent == null) {
+            finishReceiverLocked(queue, BroadcastRecord.DELIVERY_SKIPPED);
+            return;
+        }
+
+        if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app);
+        final IApplicationThread thread = app.getThread();
+        if (thread != null) {
+            try {
+                queue.setActiveDeliveryState(BroadcastRecord.DELIVERY_SCHEDULED);
+                if (receiver instanceof BroadcastFilter) {
+                    thread.scheduleRegisteredReceiver(
+                            ((BroadcastFilter) receiver).receiverList.receiver, receiverIntent,
+                            r.resultCode, r.resultData, r.resultExtras, r.ordered, r.initialSticky,
+                            r.userId, app.mState.getReportedProcState());
+
+                    // TODO: consider making registered receivers of unordered
+                    // broadcasts report results to detect ANRs
+                    if (!r.ordered) {
+                        finishReceiverLocked(queue, BroadcastRecord.DELIVERY_DELIVERED);
+                    }
+                } else {
+                    thread.scheduleReceiver(receiverIntent, ((ResolveInfo) receiver).activityInfo,
+                            null, r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
+                            app.mState.getReportedProcState());
+                }
+            } catch (RemoteException e) {
+                finishReceiverLocked(queue, BroadcastRecord.DELIVERY_FAILURE);
+                synchronized (app.mService) {
+                    app.scheduleCrashLocked(TAG, CannotDeliverBroadcastException.TYPE_ID, null);
+                }
+            }
+        } else {
+            finishReceiverLocked(queue, BroadcastRecord.DELIVERY_FAILURE);
+        }
+    }
+
+    @Override
+    public boolean finishReceiverLocked(@NonNull ProcessRecord app, int resultCode,
+            @Nullable String resultData, @Nullable Bundle resultExtras, boolean resultAbort,
+            boolean waitForServices) {
+        final BroadcastProcessQueue queue = getProcessQueue(app);
+        return finishReceiverLocked(queue, BroadcastRecord.DELIVERY_DELIVERED);
+    }
+
+    private boolean finishReceiverLocked(@NonNull BroadcastProcessQueue queue, int deliveryState) {
+        checkState(queue.isActive(), "isActive");
+
+        if (deliveryState != BroadcastRecord.DELIVERY_DELIVERED) {
+            Slog.w(TAG, "Failed delivery of " + queue.getActive() + " to " + queue);
+        }
+
+        queue.setActiveDeliveryState(deliveryState);
+
+        // TODO: cancel any outstanding ANR timeout
+        // TODO: limit number of broadcasts in a row to avoid starvation
+        // TODO: if we're the last receiver of this broadcast, record to history
+
+        if (queue.isRunnable() && queue.isProcessWarm()) {
+            // We're on a roll; move onto the next broadcast for this process
+            queue.makeActiveNextPending();
+            scheduleReceiverWarmLocked(queue);
+            return true;
+        } else {
+            // We've drained running broadcasts; maybe move back to runnable
+            queue.makeActiveIdle();
+            mRunning.remove(queue);
+            // App is no longer running a broadcast, so update its OOM
+            // adjust during our next pass; no need for an immediate update
+            mService.enqueueOomAdjTargetLocked(queue.app);
+            updateRunnableList(queue);
+            enqueueUpdateRunningList();
+            return false;
+        }
+    }
+
+    @Override
+    public boolean cleanupDisabledPackageReceiversLocked(String packageName,
+            Set<String> filterByClasses, int userId, boolean doit) {
+        // TODO: implement
+        return false;
+    }
+
+    @Override
+    void start(@NonNull ContentResolver resolver) {
+        super.start(resolver);
+
+        mService.registerUidObserver(new UidObserver() {
+            @Override
+            public void onUidCachedChanged(int uid, boolean cached) {
+                synchronized (mService) {
+                    BroadcastProcessQueue leaf = mProcessQueues.get(uid);
+                    while (leaf != null) {
+                        leaf.setProcessCached(cached);
+                        updateRunnableList(leaf);
+                        leaf = leaf.next;
+                    }
+                    enqueueUpdateRunningList();
+                }
+            }
+        }, ActivityManager.UID_OBSERVER_CACHED, 0, "android");
+    }
+
+    @Override
+    public boolean isIdleLocked() {
+        return mRunnable.isEmpty() && mRunning.isEmpty();
+    }
+
+    @Override
+    public void waitForIdle(@Nullable PrintWriter pw) {
+        final CountDownLatch latch = new CountDownLatch(1);
+        synchronized (mService) {
+            mWaitingForIdle.add(latch);
+        }
+        enqueueUpdateRunningList();
+        try {
+            latch.await();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void waitForBarrier(@Nullable PrintWriter pw) {
+        // TODO: implement
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String describeStateLocked() {
+        return mRunnable.size() + " runnable, " + mRunning.size() + " running";
+    }
+
+    @Override
+    public boolean isDelayBehindServices() {
+        // TODO: implement
+        return false;
+    }
+
+    @Override
+    public void backgroundServicesFinishedLocked(int userId) {
+        // TODO: implement
+    }
+
+    private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) {
+        if (!queue.isProcessWarm()) {
+            queue.app = mService.getProcessRecordLocked(queue.processName, queue.uid);
+        }
+    }
+
+    private @NonNull BroadcastProcessQueue getOrCreateProcessQueue(@NonNull ProcessRecord app) {
+        return getOrCreateProcessQueue(app.processName, app.info.uid);
+    }
+
+    private @NonNull BroadcastProcessQueue getOrCreateProcessQueue(@NonNull String processName,
+            int uid) {
+        BroadcastProcessQueue leaf = mProcessQueues.get(uid);
+        while (leaf != null) {
+            if (Objects.equals(leaf.processName, processName)) {
+                return leaf;
+            } else if (leaf.next == null) {
+                break;
+            }
+            leaf = leaf.next;
+        }
+
+        BroadcastProcessQueue created = new BroadcastProcessQueue(processName, uid);
+        created.app = mService.getProcessRecordLocked(processName, uid);
+
+        if (leaf == null) {
+            mProcessQueues.put(uid, created);
+        } else {
+            leaf.next = created;
+        }
+        return created;
+    }
+
+    private @Nullable BroadcastProcessQueue getProcessQueue(@NonNull ProcessRecord app) {
+        return getProcessQueue(app.processName, app.info.uid);
+    }
+
+    private @Nullable BroadcastProcessQueue getProcessQueue(@NonNull String processName, int uid) {
+        BroadcastProcessQueue leaf = mProcessQueues.get(uid);
+        while (leaf != null) {
+            if (Objects.equals(leaf.processName, processName)) {
+                return leaf;
+            }
+            leaf = leaf.next;
+        }
+        return null;
+    }
+
+    @Override
+    public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
+        long token = proto.start(fieldId);
+        proto.write(BroadcastQueueProto.QUEUE_NAME, mQueueName);
+        mHistory.dumpDebug(proto);
+        proto.end(token);
+    }
+
+    @Override
+    public boolean dumpLocked(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
+            @NonNull String[] args, int opti, boolean dumpAll, @Nullable String dumpPackage,
+            boolean needSep) {
+        final long now = SystemClock.uptimeMillis();
+        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
+        ipw.increaseIndent();
+
+        ipw.println();
+        ipw.println("📋 Per-process queues:");
+        ipw.increaseIndent();
+        for (int i = 0; i < mProcessQueues.size(); i++) {
+            BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
+            while (leaf != null) {
+                leaf.dumpLocked(ipw);
+                leaf = leaf.next;
+            }
+        }
+        ipw.decreaseIndent();
+
+        ipw.println();
+        ipw.println("🧍 Runnable:");
+        ipw.increaseIndent();
+        if (mRunnable.isEmpty()) {
+            ipw.println("(none)");
+        } else {
+            for (BroadcastProcessQueue queue : mRunnable) {
+                TimeUtils.formatDuration(queue.getRunnableAt(), now, ipw);
+                ipw.print(' ');
+                ipw.println(queue.toShortString());
+            }
+        }
+        ipw.decreaseIndent();
+
+        ipw.println();
+        ipw.println("🏃 Running:");
+        ipw.increaseIndent();
+        if (mRunning.isEmpty()) {
+            ipw.println("(none)");
+        } else {
+            for (BroadcastProcessQueue queue : mRunning) {
+                if (queue == mRunningColdStart) {
+                    ipw.print("🥶 ");
+                } else {
+                    ipw.print("\u3000 ");
+                }
+                ipw.println(queue.toShortString());
+            }
+        }
+        ipw.decreaseIndent();
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+        needSep = mHistory.dumpLocked(ipw, dumpPackage, mQueueName, sdf, dumpAll, needSep);
+        return needSep;
+    }
+}
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 817831c..96fd362 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -84,6 +84,7 @@
     final BroadcastOptions options; // BroadcastOptions supplied by caller
     final List receivers;   // contains BroadcastFilter and ResolveInfo
     final int[] delivery;   // delivery state of each receiver
+    final long[] scheduledTime; // uptimeMillis when each receiver was scheduled
     final long[] duration;   // duration a receiver took to process broadcast
     IIntentReceiver resultTo; // who receives final result if non-null
     boolean deferred;
@@ -127,10 +128,18 @@
     static final int CALL_DONE_RECEIVE = 3;
     static final int WAITING_SERVICES = 4;
 
+    /** Initial state: waiting to run in future */
     static final int DELIVERY_PENDING = 0;
+    /** Terminal state: finished successfully */
     static final int DELIVERY_DELIVERED = 1;
+    /** Terminal state: skipped due to internal policy */
     static final int DELIVERY_SKIPPED = 2;
+    /** Terminal state: timed out during attempted delivery */
     static final int DELIVERY_TIMEOUT = 3;
+    /** Intermediate state: currently executing */
+    static final int DELIVERY_SCHEDULED = 4;
+    /** Terminal state: failure to dispatch */
+    static final int DELIVERY_FAILURE = 5;
 
     ProcessRecord curApp;       // hosting application of current receiver.
     ComponentName curComponent; // the receiver class that is currently running.
@@ -253,6 +262,8 @@
                 case DELIVERY_DELIVERED: pw.print("Deliver"); break;
                 case DELIVERY_SKIPPED:   pw.print("Skipped"); break;
                 case DELIVERY_TIMEOUT:   pw.print("Timeout"); break;
+                case DELIVERY_SCHEDULED: pw.print("Schedul"); break;
+                case DELIVERY_FAILURE:   pw.print("Failure"); break;
                 default:                 pw.print("???????"); break;
             }
             pw.print(" "); TimeUtils.formatDuration(duration[i], pw);
@@ -300,6 +311,7 @@
         options = _options;
         receivers = _receivers;
         delivery = new int[_receivers != null ? _receivers.size() : 0];
+        scheduledTime = new long[delivery.length];
         duration = new long[delivery.length];
         resultTo = _resultTo;
         resultCode = _resultCode;
@@ -346,6 +358,7 @@
         options = from.options;
         receivers = from.receivers;
         delivery = from.delivery;
+        scheduledTime = from.scheduledTime;
         duration = from.duration;
         resultTo = from.resultTo;
         enqueueTime = from.enqueueTime;
@@ -497,7 +510,77 @@
         return ret;
     }
 
-    int getReceiverUid(Object receiver) {
+    /**
+     * Update the delivery state of the given {@link #receivers} index.
+     * Automatically updates any time measurements related to state changes.
+     */
+    void setDeliveryState(int index, int deliveryState) {
+        delivery[index] = deliveryState;
+
+        switch (deliveryState) {
+            case DELIVERY_DELIVERED:
+                duration[index] = SystemClock.uptimeMillis() - scheduledTime[index];
+                break;
+            case DELIVERY_SCHEDULED:
+                scheduledTime[index] = SystemClock.uptimeMillis();
+                break;
+        }
+    }
+
+    boolean isForeground() {
+        return (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
+    }
+
+    boolean isReplacePending() {
+        return (intent.getFlags() & Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
+    }
+
+    @NonNull String getHostingRecordTriggerType() {
+        if (alarm) {
+            return HostingRecord.TRIGGER_TYPE_ALARM;
+        } else if (pushMessage) {
+            return HostingRecord.TRIGGER_TYPE_PUSH_MESSAGE;
+        } else if (pushMessageOverQuota) {
+            return HostingRecord.TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA;
+        }
+        return HostingRecord.TRIGGER_TYPE_UNKNOWN;
+    }
+
+    /**
+     * Return an instance of {@link #intent} specialized for the given receiver.
+     * For example, this returns a new specialized instance if the extras need
+     * to be filtered, or a {@link ResolveInfo} needs to be configured.
+     *
+     * @return a specialized intent, otherwise {@code null} to indicate that the
+     *         broadcast should not be delivered to this receiver, typically due
+     *         to it being filtered away by {@link #filterExtrasForReceiver}.
+     */
+    @Nullable Intent getReceiverIntent(@NonNull Object receiver) {
+        Intent newIntent = null;
+        if (filterExtrasForReceiver != null) {
+            final Bundle extras = intent.getExtras();
+            if (extras != null) {
+                final int receiverUid = getReceiverUid(receiver);
+                final Bundle filteredExtras = filterExtrasForReceiver.apply(receiverUid, extras);
+                if (filteredExtras == null) {
+                    // Completely filtered; skip the broadcast!
+                    return null;
+                } else {
+                    newIntent = new Intent(intent);
+                    newIntent.replaceExtras(filteredExtras);
+                }
+            }
+        }
+        if (receiver instanceof ResolveInfo) {
+            if (newIntent == null) {
+                newIntent = new Intent(intent);
+            }
+            newIntent.setComponent(((ResolveInfo) receiver).activityInfo.getComponentName());
+        }
+        return (newIntent != null) ? newIntent : intent;
+    }
+
+    static int getReceiverUid(@NonNull Object receiver) {
         if (receiver instanceof BroadcastFilter) {
             return ((BroadcastFilter) receiver).owningUid;
         } else /* if (receiver instanceof ResolveInfo) */ {
@@ -505,6 +588,14 @@
         }
     }
 
+    static String getReceiverProcessName(@NonNull Object receiver) {
+        if (receiver instanceof BroadcastFilter) {
+            return ((BroadcastFilter) receiver).receiverList.app.processName;
+        } else /* if (receiver instanceof ResolveInfo) */ {
+            return ((ResolveInfo) receiver).activityInfo.processName;
+        }
+    }
+
     public BroadcastRecord maybeStripForHistory() {
         if (!intent.canStripForHistory()) {
             return this;
@@ -561,6 +652,10 @@
             + " u" + userId + " " + intent.getAction() + "}";
     }
 
+    public String toShortString() {
+        return intent.getAction() + "/u" + userId;
+    }
+
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         long token = proto.start(fieldId);
         proto.write(BroadcastRecordProto.USER_ID, userId);
diff --git a/services/core/java/com/android/server/am/BroadcastSkipPolicy.java b/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
index 9569848..e9b5030 100644
--- a/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
+++ b/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
@@ -16,7 +16,6 @@
 
 package com.android.server.am;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
 import static com.android.server.am.ActivityManagerService.checkComponentPermission;
 import static com.android.server.am.BroadcastQueue.TAG;
@@ -35,7 +34,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
-import android.os.Bundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -59,6 +57,18 @@
 
     /**
      * Determine if the given {@link BroadcastRecord} is eligible to be sent to
+     * the given {@link BroadcastFilter} or {@link ResolveInfo}.
+     */
+    public boolean shouldSkip(@NonNull BroadcastRecord r, @NonNull Object target) {
+        if (target instanceof BroadcastFilter) {
+            return shouldSkip(r, (BroadcastFilter) target);
+        } else {
+            return shouldSkip(r, (ResolveInfo) target);
+        }
+    }
+
+    /**
+     * Determine if the given {@link BroadcastRecord} is eligible to be sent to
      * the given {@link ResolveInfo}.
      */
     public boolean shouldSkip(@NonNull BroadcastRecord r, @NonNull ResolveInfo info) {
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index 86c9770..a97173d 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -29,6 +29,7 @@
 import static com.android.server.am.ActivityManagerService.TAG_MU;
 import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_PROVIDER;
 
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
@@ -48,7 +49,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
 import android.content.pm.UserInfo;
@@ -960,20 +960,22 @@
     String getProviderMimeType(Uri uri, int userId) {
         mService.enforceNotIsolatedCaller("getProviderMimeType");
         final String name = uri.getAuthority();
-        int callingUid = Binder.getCallingUid();
-        int callingPid = Binder.getCallingPid();
-        long ident = 0;
-        boolean clearedIdentity = false;
-        userId = mService.mUserController.unsafeConvertIncomingUser(userId);
-        if (canClearIdentity(callingPid, callingUid, userId)) {
-            clearedIdentity = true;
-            ident = Binder.clearCallingIdentity();
-        }
-        ContentProviderHolder holder = null;
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        final int safeUserId = mService.mUserController.unsafeConvertIncomingUser(userId);
+        final long ident = canClearIdentity(callingPid, callingUid, safeUserId)
+                ? Binder.clearCallingIdentity() : 0;
+        final ContentProviderHolder holder;
         try {
-            holder = getContentProviderExternalUnchecked(name, null, callingUid,
-                    "*getmimetype*", userId);
-            if (holder != null) {
+            holder = getContentProviderExternalUnchecked(name, null /* token */, callingUid,
+                    "*getmimetype*", safeUserId);
+        } finally {
+            if (ident != 0) {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+        try {
+            if (isHolderVisibleToCaller(holder, callingUid, safeUserId)) {
                 final IBinder providerConnection = holder.connection;
                 final ComponentName providerName = holder.info.getComponentName();
                 // Note: creating a new Runnable instead of using a lambda here since lambdas in
@@ -992,6 +994,13 @@
                     return holder.provider.getType(uri);
                 } finally {
                     mService.mHandler.removeCallbacks(providerNotResponding);
+                    // We need to clear the identity to call removeContentProviderExternalUnchecked
+                    final long token = Binder.clearCallingIdentity();
+                    try {
+                        removeContentProviderExternalUnchecked(name, null /* token */, safeUserId);
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
                 }
             }
         } catch (RemoteException e) {
@@ -1000,18 +1009,6 @@
         } catch (Exception e) {
             Log.w(TAG, "Exception while determining type of " + uri, e);
             return null;
-        } finally {
-            // We need to clear the identity to call removeContentProviderExternalUnchecked
-            if (!clearedIdentity) {
-                ident = Binder.clearCallingIdentity();
-            }
-            try {
-                if (holder != null) {
-                    removeContentProviderExternalUnchecked(name, null, userId);
-                }
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
         }
 
         return null;
@@ -1029,12 +1026,20 @@
         final int callingUid = Binder.getCallingUid();
         final int callingPid = Binder.getCallingPid();
         final int safeUserId = mService.mUserController.unsafeConvertIncomingUser(userId);
-        final long ident = canClearIdentity(callingPid, callingUid, userId)
+        final long ident = canClearIdentity(callingPid, callingUid, safeUserId)
                 ? Binder.clearCallingIdentity() : 0;
+        final ContentProviderHolder holder;
         try {
-            final ContentProviderHolder holder = getContentProviderExternalUnchecked(name, null,
-                    callingUid, "*getmimetype*", safeUserId);
-            if (holder != null) {
+            holder = getContentProviderExternalUnchecked(name, null /* token */, callingUid,
+                    "*getmimetype*", safeUserId);
+        } finally {
+            if (ident != 0) {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        try {
+            if (isHolderVisibleToCaller(holder, callingUid, safeUserId)) {
                 holder.provider.getTypeAsync(uri, new RemoteCallback(result -> {
                     final long identity = Binder.clearCallingIdentity();
                     try {
@@ -1050,8 +1055,6 @@
         } catch (RemoteException e) {
             Log.w(TAG, "Content provider dead retrieving " + uri, e);
             resultCallback.sendResult(Bundle.EMPTY);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
         }
     }
 
@@ -1067,6 +1070,35 @@
                         callingUid, -1, true) == PackageManager.PERMISSION_GRANTED;
     }
 
+    private boolean isHolderVisibleToCaller(@Nullable ContentProviderHolder holder, int callingUid,
+            @UserIdInt int userId) {
+        if (holder == null || holder.info == null) {
+            return false;
+        }
+
+        if (isAuthorityRedirectedForCloneProfile(holder.info.authority)
+                && resolveParentUserIdForCloneProfile(userId) != userId) {
+            // Since clone profile shares certain providers with its parent and the access is
+            // re-directed as well, the holder may not actually be installed on the clone profile.
+            return !mService.getPackageManagerInternal().filterAppAccess(holder.info.packageName,
+                    callingUid, userId, false /* filterUninstalled */);
+        }
+
+        return !mService.getPackageManagerInternal().filterAppAccess(holder.info.packageName,
+                callingUid, userId);
+    }
+
+    private static @UserIdInt int resolveParentUserIdForCloneProfile(@UserIdInt int userId) {
+        final UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
+        final UserInfo userInfo = umInternal.getUserInfo(userId);
+
+        if (userInfo == null || !userInfo.isCloneProfile()) {
+            return userId;
+        }
+
+        return umInternal.getProfileParentId(userId);
+    }
+
     /**
      * Check if the calling UID has a possible chance at accessing the provider
      * at the given authority and user.
@@ -1135,9 +1167,7 @@
                     "*checkContentProviderUriPermission*", userId);
             if (holder != null) {
 
-                final PackageManagerInternal packageManagerInt = LocalServices.getService(
-                        PackageManagerInternal.class);
-                final AndroidPackage androidPackage = packageManagerInt
+                final AndroidPackage androidPackage = mService.getPackageManagerInternal()
                         .getPackage(Binder.getCallingUid());
                 if (androidPackage == null) {
                     return PackageManager.PERMISSION_DENIED;
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index ceea01b..71d39964 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -51,6 +51,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.ProcessCpuTracker;
 import com.android.internal.os.TimeoutRecord;
+import com.android.internal.os.anr.AnrLatencyTracker;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.ResourcePressureUtil;
 import com.android.server.criticalevents.CriticalEventLog;
@@ -258,11 +259,15 @@
             boolean aboveSystem, TimeoutRecord timeoutRecord,
             boolean onlyDumpSelf) {
         String annotation = timeoutRecord.mReason;
+        AnrLatencyTracker latencyTracker = timeoutRecord.mLatencyTracker;
+
         ArrayList<Integer> firstPids = new ArrayList<>(5);
         SparseArray<Boolean> lastPids = new SparseArray<>(20);
 
         mApp.getWindowProcessController().appEarlyNotResponding(annotation, () -> {
+            latencyTracker.waitingOnAMSLockStarted();
             synchronized (mService) {
+                latencyTracker.waitingOnAMSLockEnded();
                 // Store annotation here as instance below races with this killLocked.
                 setAnrAnnotation(annotation);
                 mApp.killLocked("anr", ApplicationExitInfo.REASON_ANR, true);
@@ -271,37 +276,48 @@
 
         long anrTime = SystemClock.uptimeMillis();
         if (isMonitorCpuUsage()) {
+            latencyTracker.updateCpuStatsNowCalled();
             mService.updateCpuStatsNow();
+            latencyTracker.updateCpuStatsNowReturned();
         }
 
         final boolean isSilentAnr;
         final int pid = mApp.getPid();
         final UUID errorId;
+        latencyTracker.waitingOnAMSLockStarted();
         synchronized (mService) {
+            latencyTracker.waitingOnAMSLockEnded();
             // Store annotation here as instance above will not be hit on all paths.
             setAnrAnnotation(annotation);
 
             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
             if (mService.mAtmInternal.isShuttingDown()) {
                 Slog.i(TAG, "During shutdown skipping ANR: " + this + " " + annotation);
+                latencyTracker.anrSkippedProcessErrorStateRecordAppNotResponding();
                 return;
             } else if (isNotResponding()) {
                 Slog.i(TAG, "Skipping duplicate ANR: " + this + " " + annotation);
+                latencyTracker.anrSkippedProcessErrorStateRecordAppNotResponding();
                 return;
             } else if (isCrashing()) {
                 Slog.i(TAG, "Crashing app skipping ANR: " + this + " " + annotation);
+                latencyTracker.anrSkippedProcessErrorStateRecordAppNotResponding();
                 return;
             } else if (mApp.isKilledByAm()) {
                 Slog.i(TAG, "App already killed by AM skipping ANR: " + this + " " + annotation);
+                latencyTracker.anrSkippedProcessErrorStateRecordAppNotResponding();
                 return;
             } else if (mApp.isKilled()) {
                 Slog.i(TAG, "Skipping died app ANR: " + this + " " + annotation);
+                latencyTracker.anrSkippedProcessErrorStateRecordAppNotResponding();
                 return;
             }
 
             // In case we come through here for the same app before completing
             // this one, mark as anring now so we will bail out.
+            latencyTracker.waitingOnProcLockStarted();
             synchronized (mProcLock) {
+                latencyTracker.waitingOnProcLockEnded();
                 setNotResponding(true);
             }
 
@@ -361,9 +377,11 @@
         }
 
         // Get critical event log before logging the ANR so that it doesn't occur in the log.
+        latencyTracker.criticalEventLogStarted();
         final String criticalEventLog =
                 CriticalEventLog.getInstance().logLinesForTraceFile(
                         mApp.getProcessClassEnum(), mApp.processName, mApp.uid);
+        latencyTracker.criticalEventLogEnded();
         CriticalEventLog.getInstance().logAnr(annotation, mApp.getProcessClassEnum(),
                 mApp.processName, mApp.uid, mApp.mPid);
 
@@ -405,9 +423,14 @@
         }
 
         StringBuilder report = new StringBuilder();
-        report.append(ResourcePressureUtil.currentPsiState());
+
+        latencyTracker.currentPsiStateCalled();
+        String currentPsiState = ResourcePressureUtil.currentPsiState();
+        latencyTracker.currentPsiStateReturned();
+        report.append(currentPsiState);
         ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
 
+        latencyTracker.nativePidCollectionStarted();
         // don't dump native PIDs for background ANRs unless it is the process of interest
         String[] nativeProcs = null;
         if (isSilentAnr || onlyDumpSelf) {
@@ -430,7 +453,7 @@
                 nativePids.add(i);
             }
         }
-
+        latencyTracker.nativePidCollectionEnded();
         // For background ANRs, don't pass the ProcessCpuTracker to
         // avoid spending 1/2 second collecting stats to rank lastPids.
         StringWriter tracesFileException = new StringWriter();
@@ -438,7 +461,8 @@
         final long[] offsets = new long[2];
         File tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
                 isSilentAnr ? null : processCpuTracker, isSilentAnr ? null : lastPids,
-                nativePids, tracesFileException, offsets, annotation, criticalEventLog);
+                nativePids, tracesFileException, offsets, annotation, criticalEventLog,
+                latencyTracker);
 
         if (isMonitorCpuUsage()) {
             mService.updateCpuStatsNow();
diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
index 0f5aa3a..4aaf1ab 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
@@ -52,6 +52,7 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost.SurfacePackage;
 import android.view.WindowManager;
+import android.window.ScreenCapture;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -843,8 +844,8 @@
         final SurfaceControl overlaySurfaceControl =
                 overlaySurfacePackage != null ? overlaySurfacePackage.getSurfaceControl() : null;
         mBackgroundExecutor.execute(() -> {
-            final SurfaceControl.LayerCaptureArgs.Builder layerCaptureArgsBuilder =
-                    new SurfaceControl.LayerCaptureArgs.Builder(/* layer */ null);
+            final ScreenCapture.LayerCaptureArgs.Builder layerCaptureArgsBuilder =
+                    new ScreenCapture.LayerCaptureArgs.Builder(/* layer */ null);
             if (overlaySurfaceControl != null) {
                 SurfaceControl[] excludeLayers = new SurfaceControl[1];
                 excludeLayers[0] = overlaySurfaceControl;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 8b11c39..af73c2b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -16,9 +16,6 @@
 
 package com.android.server.appop;
 
-import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
-import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
-import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
 import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
 import static android.app.AppOpsManager.ATTRIBUTION_FLAG_TRUSTED;
 import static android.app.AppOpsManager.CALL_BACK_ON_SWITCHED_OP;
@@ -46,6 +43,7 @@
 import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
+import static android.app.AppOpsManager.OP_VIBRATE;
 import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_FAILED;
 import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_RESUMED;
 import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_STARTED;
@@ -56,13 +54,6 @@
 import static android.app.AppOpsManager.SAMPLING_STRATEGY_UNIFORM;
 import static android.app.AppOpsManager.SAMPLING_STRATEGY_UNIFORM_OPS;
 import static android.app.AppOpsManager.SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE;
-import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
-import static android.app.AppOpsManager.UID_STATE_CACHED;
-import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
-import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
-import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
-import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
-import static android.app.AppOpsManager.UID_STATE_TOP;
 import static android.app.AppOpsManager._NUM_OP;
 import static android.app.AppOpsManager.extractFlagsFromKey;
 import static android.app.AppOpsManager.extractUidStateFromKey;
@@ -72,7 +63,6 @@
 import static android.app.AppOpsManager.opRestrictsRead;
 import static android.app.AppOpsManager.opToName;
 import static android.app.AppOpsManager.opToPublicName;
-import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState;
 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
 import static android.content.Intent.EXTRA_REPLACING;
 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
@@ -80,8 +70,6 @@
 
 import static com.android.server.appop.AppOpsService.ModeCallback.ALL_OPS;
 
-import static java.lang.Long.max;
-
 import android.Manifest;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -167,6 +155,7 @@
 import com.android.internal.app.IAppOpsStartedCallback;
 import com.android.internal.app.MessageSamplingConfig;
 import com.android.internal.compat.IPlatformCompat;
+import com.android.internal.os.Clock;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
@@ -236,35 +225,11 @@
     // Constant meaning that any UID should be matched when dispatching callbacks
     private static final int UID_ANY = -2;
 
-    // Map from process states to the uid states we track.
-    private static final int[] PROCESS_STATE_TO_UID_STATE = new int[] {
-        UID_STATE_PERSISTENT,           // ActivityManager.PROCESS_STATE_PERSISTENT
-        UID_STATE_PERSISTENT,           // ActivityManager.PROCESS_STATE_PERSISTENT_UI
-        UID_STATE_TOP,                  // ActivityManager.PROCESS_STATE_TOP
-        UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_BOUND_TOP
-        UID_STATE_FOREGROUND_SERVICE,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
-        UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
-        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
-        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
-        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_BACKUP
-        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_SERVICE
-        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_RECEIVER
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_TOP_SLEEPING
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_HOME
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_RECENT
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_EMPTY
-        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_NONEXISTENT
-    };
-
     private static final int[] OPS_RESTRICTED_ON_SUSPEND = {
             OP_PLAY_AUDIO,
             OP_RECORD_AUDIO,
             OP_CAMERA,
+            OP_VIBRATE,
     };
 
     private static final int MAX_UNFORWARDED_OPS = 10;
@@ -342,8 +307,6 @@
 
     volatile @NonNull HistoricalRegistry mHistoricalRegistry = new HistoricalRegistry(this);
 
-    long mLastRealtime;
-
     /*
      * These are app op restrictions imposed per user from various parties.
      */
@@ -404,6 +367,21 @@
     /** Interface for app-op modes.*/
     @VisibleForTesting AppOpsServiceInterface mAppOpsServiceInterface;
 
+    private AppOpsUidStateTracker mUidStateTracker;
+
+    /** Hands the definition of foreground and uid states */
+    @GuardedBy("this")
+    public AppOpsUidStateTracker getUidStateTracker() {
+        if (mUidStateTracker == null) {
+            mUidStateTracker = new AppOpsUidStateTrackerImpl(
+                    LocalServices.getService(ActivityManagerInternal.class), mHandler,
+                    Clock.SYSTEM_CLOCK, mConstants);
+
+            mUidStateTracker.addUidStateChangedCallback(mHandler, this::onUidStateChanged);
+        }
+        return mUidStateTracker;
+    }
+
     /**
      * An unsynchronized pool of {@link OpEventProxyInfo} objects.
      */
@@ -463,7 +441,6 @@
      * global Settings. Any access to this class or its fields should be done while
      * holding the AppOpsService lock.
      */
-    @VisibleForTesting
     final class Constants extends ContentObserver {
 
         /**
@@ -551,14 +528,6 @@
     final class UidState {
         public final int uid;
 
-        public int state = UID_STATE_CACHED;
-        public int pendingState = UID_STATE_CACHED;
-        public long pendingStateCommitTime;
-        public int capability;
-        public int pendingCapability;
-        public boolean appWidgetVisible;
-        public boolean pendingAppWidgetVisible;
-
         public ArrayMap<String, Ops> pkgOps;
 
         // true indicates there is an interested observer, false there isn't but it has such an op
@@ -592,10 +561,8 @@
                 }
             }
             return (pkgOps == null || pkgOps.isEmpty())
-                    && (state == UID_STATE_CACHED
-                    && (pendingState == UID_STATE_CACHED))
-                    && (mAppOpsServiceInterface.areUidModesDefault(uid)
-                    && areAllPackageModesDefault);
+                    && mAppOpsServiceInterface.areUidModesDefault(uid)
+                    && areAllPackageModesDefault;
         }
 
         // Functions for uid mode access and manipulation.
@@ -611,52 +578,9 @@
             return mAppOpsServiceInterface.setUidMode(uid, op, mode);
         }
 
+        @SuppressWarnings("GuardedBy")
         int evalMode(int op, int mode) {
-            if (mode == MODE_FOREGROUND) {
-                if (appWidgetVisible) {
-                    return MODE_ALLOWED;
-                } else if (mActivityManagerInternal != null
-                        && mActivityManagerInternal.isPendingTopUid(uid)) {
-                    return MODE_ALLOWED;
-                } else if (mActivityManagerInternal != null
-                        && mActivityManagerInternal.isTempAllowlistedForFgsWhileInUse(uid)) {
-                    return MODE_ALLOWED;
-                } else if (state <= UID_STATE_TOP) {
-                    // process is in TOP.
-                    return MODE_ALLOWED;
-                } else if (state <= AppOpsManager.resolveFirstUnrestrictedUidState(op)) {
-                    // process is in foreground, check its capability.
-                    switch (op) {
-                        case AppOpsManager.OP_FINE_LOCATION:
-                        case AppOpsManager.OP_COARSE_LOCATION:
-                        case AppOpsManager.OP_MONITOR_LOCATION:
-                        case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION:
-                            if ((capability & PROCESS_CAPABILITY_FOREGROUND_LOCATION) != 0) {
-                                return MODE_ALLOWED;
-                            } else {
-                                return MODE_IGNORED;
-                            }
-                        case OP_CAMERA:
-                            if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) {
-                                return MODE_ALLOWED;
-                            } else {
-                                return MODE_IGNORED;
-                            }
-                        case OP_RECORD_AUDIO:
-                            if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) {
-                                return MODE_ALLOWED;
-                            } else {
-                                return MODE_IGNORED;
-                            }
-                        default:
-                            return MODE_ALLOWED;
-                    }
-                } else {
-                    // process is not in foreground.
-                    return MODE_IGNORED;
-                }
-            }
-            return mode;
+            return getUidStateTracker().evalMode(uid, op, mode);
         }
 
         public void evalForegroundOps() {
@@ -679,6 +603,16 @@
                 }
             }
         }
+
+        @SuppressWarnings("GuardedBy")
+        public int getState() {
+            return getUidStateTracker().getUidState(uid);
+        }
+
+        @SuppressWarnings("GuardedBy")
+        public void dump(PrintWriter pw, long nowElapsed) {
+            getUidStateTracker().dumpUidState(pw, uid, nowElapsed);
+        }
     }
 
     final static class Ops extends SparseArray<Op> {
@@ -706,7 +640,7 @@
         }
     }
 
-    /** Returned from {@link #verifyAndGetBypass(int, String, String, String, boolean)}. */
+    /** Returned from {@link #verifyAndGetBypass(int, String, String, String)}. */
     private static final class PackageVerificationResult {
 
         final RestrictionBypass bypass;
@@ -1477,10 +1411,6 @@
                     UserHandle.getUserId(this.uid));
         }
 
-        int evalMode() {
-            return uidState.evalMode(op, getMode());
-        }
-
         void removeAttributionsWithNoTime() {
             for (int i = mAttributions.size() - 1; i >= 0; i--) {
                 if (!mAttributions.valueAt(i).hasAnyTime()) {
@@ -2092,79 +2022,88 @@
         }
     }
 
-    /**
-     * Update the pending state for the uid
-     *
-     * @param currentTime The current elapsed real time
-     * @param uid The uid that has a pending state
-     */
-    private void updatePendingState(long currentTime, int uid) {
+    // The callback method from ForegroundPolicyInterface
+    private void onUidStateChanged(int uid, int state, boolean foregroundModeMayChange) {
         synchronized (this) {
-            mLastRealtime = max(currentTime, mLastRealtime);
-            updatePendingStateIfNeededLocked(mUidStates.get(uid));
-        }
-    }
+            UidState uidState = getUidStateLocked(uid, true);
 
-    public void updateUidProcState(int uid, int procState,
-            @ActivityManager.ProcessCapability int capability) {
-        synchronized (this) {
-            final UidState uidState = getUidStateLocked(uid, true);
-            final int newState = PROCESS_STATE_TO_UID_STATE[procState];
-            if (uidState != null && (uidState.pendingState != newState
-                    || uidState.pendingCapability != capability)) {
-                final int oldPendingState = uidState.pendingState;
-                uidState.pendingState = newState;
-                uidState.pendingCapability = capability;
-                if (newState < uidState.state
-                        || (newState <= UID_STATE_MAX_LAST_NON_RESTRICTED
-                                && uidState.state > UID_STATE_MAX_LAST_NON_RESTRICTED)) {
-                    // We are moving to a more important state, or the new state may be in the
-                    // foreground and the old state is in the background, then always do it
-                    // immediately.
-                    commitUidPendingStateLocked(uidState);
-                } else if (newState == uidState.state && capability != uidState.capability) {
-                    // No change on process state, but process capability has changed.
-                    commitUidPendingStateLocked(uidState);
-                } else if (uidState.pendingStateCommitTime == 0) {
-                    // We are moving to a less important state for the first time,
-                    // delay the application for a bit.
-                    final long settleTime;
-                    if (uidState.state <= UID_STATE_TOP) {
-                        settleTime = mConstants.TOP_STATE_SETTLE_TIME;
-                    } else if (uidState.state <= UID_STATE_FOREGROUND_SERVICE) {
-                        settleTime = mConstants.FG_SERVICE_STATE_SETTLE_TIME;
-                    } else {
-                        settleTime = mConstants.BG_STATE_SETTLE_TIME;
+            if (uidState != null && foregroundModeMayChange && uidState.hasForegroundWatchers) {
+                for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) {
+                    if (!uidState.foregroundOps.valueAt(fgi)) {
+                        continue;
                     }
-                    final long commitTime = SystemClock.elapsedRealtime() + settleTime;
-                    uidState.pendingStateCommitTime = commitTime;
+                    final int code = uidState.foregroundOps.keyAt(fgi);
 
-                    mHandler.sendMessageDelayed(
-                            PooledLambda.obtainMessage(AppOpsService::updatePendingState, this,
-                                    commitTime + 1, uid), settleTime + 1);
-                }
-
-                if (uidState.pkgOps != null) {
-                    int numPkgs = uidState.pkgOps.size();
-                    for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
-                        Ops ops = uidState.pkgOps.valueAt(pkgNum);
-
-                        int numOps = ops.size();
-                        for (int opNum = 0; opNum < numOps; opNum++) {
-                            Op op = ops.valueAt(opNum);
-
-                            int numAttributions = op.mAttributions.size();
-                            for (int attributionNum = 0; attributionNum < numAttributions;
-                                    attributionNum++) {
-                                AttributedOp attributedOp = op.mAttributions.valueAt(
-                                        attributionNum);
-
-                                attributedOp.onUidStateChanged(newState);
+                    if (uidState.getUidMode(code) != AppOpsManager.opToDefaultMode(code)
+                            && uidState.getUidMode(code) == AppOpsManager.MODE_FOREGROUND) {
+                        mHandler.sendMessage(PooledLambda.obtainMessage(
+                                AppOpsService::notifyOpChangedForAllPkgsInUid,
+                                this, code, uidState.uid, true, null));
+                    } else if (uidState.pkgOps != null) {
+                        final ArraySet<OnOpModeChangedListener> listenerSet =
+                                mAppOpsServiceInterface.getOpModeChangedListeners(code);
+                        if (listenerSet != null) {
+                            for (int cbi = listenerSet.size() - 1; cbi >= 0; cbi--) {
+                                final OnOpModeChangedListener listener = listenerSet.valueAt(cbi);
+                                if ((listener.getFlags()
+                                        & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0
+                                        || !listener.isWatchingUid(uidState.uid)) {
+                                    continue;
+                                }
+                                for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) {
+                                    final Op op = uidState.pkgOps.valueAt(pkgi).get(code);
+                                    if (op == null) {
+                                        continue;
+                                    }
+                                    if (op.getMode() == AppOpsManager.MODE_FOREGROUND) {
+                                        mHandler.sendMessage(PooledLambda.obtainMessage(
+                                                AppOpsService::notifyOpChanged,
+                                                this, listenerSet.valueAt(cbi), code, uidState.uid,
+                                                uidState.pkgOps.keyAt(pkgi)));
+                                    }
+                                }
                             }
                         }
                     }
                 }
             }
+
+            if (uidState != null && uidState.pkgOps != null) {
+                int numPkgs = uidState.pkgOps.size();
+                for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
+                    Ops ops = uidState.pkgOps.valueAt(pkgNum);
+
+                    int numOps = ops.size();
+                    for (int opNum = 0; opNum < numOps; opNum++) {
+                        Op op = ops.valueAt(opNum);
+
+                        int numAttributions = op.mAttributions.size();
+                        for (int attributionNum = 0; attributionNum < numAttributions;
+                                attributionNum++) {
+                            AttributedOp attributedOp = op.mAttributions.valueAt(
+                                    attributionNum);
+
+                            attributedOp.onUidStateChanged(state);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Notify the proc state or capability has changed for a certain UID.
+     */
+    public void updateUidProcState(int uid, int procState,
+            @ActivityManager.ProcessCapability int capability) {
+        synchronized (this) {
+            getUidStateTracker().updateUidProcState(uid, procState, capability);
+            if (!mUidStates.contains(uid)) {
+                UidState uidState = new UidState(uid);
+                mUidStates.put(uid, uidState);
+                onUidStateChanged(uid,
+                        AppOpsUidStateTracker.processStateToUidState(procState), false);
+            }
         }
     }
 
@@ -3158,7 +3097,7 @@
             if (op == null) {
                 return AppOpsManager.opToDefaultMode(code);
             }
-            return raw ? op.getMode() : op.evalMode();
+            return raw ? op.getMode() : op.uidState.evalMode(op.op, op.getMode());
         }
     }
 
@@ -3376,7 +3315,7 @@
             final int switchCode = AppOpsManager.opToSwitch(code);
             final UidState uidState = ops.uidState;
             if (isOpRestrictedLocked(uid, code, packageName, attributionTag, pvr.bypass, false)) {
-                attributedOp.rejected(uidState.state, flags);
+                attributedOp.rejected(uidState.getState(), flags);
                 scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
                         AppOpsManager.MODE_IGNORED);
                 return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, attributionTag,
@@ -3390,7 +3329,7 @@
                     if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + packageName + " flags: " + AppOpsManager.flagsToString(flags));
-                    attributedOp.rejected(uidState.state, flags);
+                    attributedOp.rejected(uidState.getState(), flags);
                     scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
                             uidMode);
                     return new SyncNotedAppOp(uidMode, code, attributionTag, packageName);
@@ -3398,12 +3337,12 @@
             } else {
                 final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, uid, true)
                         : op;
-                final int mode = switchOp.evalMode();
+                final int mode = switchOp.uidState.evalMode(switchOp.op, switchOp.getMode());
                 if (mode != AppOpsManager.MODE_ALLOWED) {
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + packageName + " flags: " + AppOpsManager.flagsToString(flags));
-                    attributedOp.rejected(uidState.state, flags);
+                    attributedOp.rejected(uidState.getState(), flags);
                     scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
                             mode);
                     return new SyncNotedAppOp(mode, code, attributionTag, packageName);
@@ -3418,7 +3357,8 @@
             }
             scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
                     AppOpsManager.MODE_ALLOWED);
-            attributedOp.accessed(proxyUid, proxyPackageName, proxyAttributionTag, uidState.state,
+            attributedOp.accessed(proxyUid, proxyPackageName, proxyAttributionTag,
+                    uidState.getState(),
                     flags);
 
             if (shouldCollectAsyncNotedOp) {
@@ -3909,7 +3849,7 @@
                                 + packageName + " flags: " + AppOpsManager.flagsToString(flags));
                     }
                     if (!dryRun) {
-                        attributedOp.rejected(uidState.state, flags);
+                        attributedOp.rejected(uidState.getState(), flags);
                         scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
                                 flags, uidMode, startType, attributionFlags, attributionChainId);
                     }
@@ -3918,14 +3858,14 @@
             } else {
                 final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, uid, true)
                         : op;
-                final int mode = switchOp.evalMode();
+                final int mode = switchOp.uidState.evalMode(switchOp.op, switchOp.getMode());
                 if (mode != AppOpsManager.MODE_ALLOWED
                         && (!startIfModeDefault || mode != MODE_DEFAULT)) {
                     if (DEBUG) Slog.d(TAG, "startOperation: reject #" + mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + packageName + " flags: " + AppOpsManager.flagsToString(flags));
                     if (!dryRun) {
-                        attributedOp.rejected(uidState.state, flags);
+                        attributedOp.rejected(uidState.getState(), flags);
                         scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
                                 flags, mode, startType, attributionFlags, attributionChainId);
                     }
@@ -3939,12 +3879,12 @@
                 try {
                     if (isRestricted) {
                         attributedOp.createPaused(clientId, proxyUid, proxyPackageName,
-                                proxyAttributionTag, uidState.state, flags, attributionFlags,
-                                attributionChainId);
+                                proxyAttributionTag, uidState.getState(), flags,
+                                attributionFlags, attributionChainId);
                     } else {
                         attributedOp.started(clientId, proxyUid, proxyPackageName,
-                                proxyAttributionTag, uidState.state, flags, attributionFlags,
-                                attributionChainId);
+                                proxyAttributionTag, uidState.getState(), flags,
+                                attributionFlags, attributionChainId);
                         startType = START_TYPE_STARTED;
                     }
                 } catch (RemoteException e) {
@@ -4358,101 +4298,14 @@
             }
             uidState = new UidState(uid);
             mUidStates.put(uid, uidState);
-        } else {
-            updatePendingStateIfNeededLocked(uidState);
         }
+
         return uidState;
     }
 
-    /**
-     * Check if the pending state should be updated and do so if needed
-     *
-     * @param uidState The uidState that might have a pending state
-     */
-    private void updatePendingStateIfNeededLocked(@NonNull UidState uidState) {
-        if (uidState != null) {
-            if (uidState.pendingStateCommitTime != 0) {
-                if (uidState.pendingStateCommitTime < mLastRealtime) {
-                    commitUidPendingStateLocked(uidState);
-                } else {
-                    mLastRealtime = SystemClock.elapsedRealtime();
-                    if (uidState.pendingStateCommitTime < mLastRealtime) {
-                        commitUidPendingStateLocked(uidState);
-                    }
-                }
-            }
-        }
-    }
-
-    private void commitUidPendingStateLocked(UidState uidState) {
-        if (uidState.hasForegroundWatchers) {
-            for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) {
-                if (!uidState.foregroundOps.valueAt(fgi)) {
-                    continue;
-                }
-                final int code = uidState.foregroundOps.keyAt(fgi);
-                // For location ops we consider fg state only if the fg service
-                // is of location type, for all other ops any fg service will do.
-                final long firstUnrestrictedUidState = resolveFirstUnrestrictedUidState(code);
-                final boolean resolvedLastFg = uidState.state <= firstUnrestrictedUidState;
-                final boolean resolvedNowFg = uidState.pendingState <= firstUnrestrictedUidState;
-                if (resolvedLastFg == resolvedNowFg
-                        && uidState.capability == uidState.pendingCapability
-                        && uidState.appWidgetVisible == uidState.pendingAppWidgetVisible) {
-                    continue;
-                }
-
-                if (uidState.getUidMode(code) != AppOpsManager.opToDefaultMode(code)
-                        && uidState.getUidMode(code) == AppOpsManager.MODE_FOREGROUND) {
-                    mHandler.sendMessage(PooledLambda.obtainMessage(
-                            AppOpsService::notifyOpChangedForAllPkgsInUid,
-                            this, code, uidState.uid, true, null));
-                } else if (uidState.pkgOps != null) {
-                    final ArraySet<OnOpModeChangedListener> listenerSet =
-                            mAppOpsServiceInterface.getOpModeChangedListeners(code);
-                    if (listenerSet != null) {
-                        for (int cbi = listenerSet.size() - 1; cbi >= 0; cbi--) {
-                            final OnOpModeChangedListener listener = listenerSet.valueAt(cbi);
-                            if ((listener.getFlags()
-                                    & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0
-                                    || !listener.isWatchingUid(uidState.uid)) {
-                                continue;
-                            }
-                            for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) {
-                                final Op op = uidState.pkgOps.valueAt(pkgi).get(code);
-                                if (op == null) {
-                                    continue;
-                                }
-                                if (op.getMode() == AppOpsManager.MODE_FOREGROUND) {
-                                    mHandler.sendMessage(PooledLambda.obtainMessage(
-                                            AppOpsService::notifyOpChanged,
-                                            this, listenerSet.valueAt(cbi), code, uidState.uid,
-                                            uidState.pkgOps.keyAt(pkgi)));
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        uidState.state = uidState.pendingState;
-        uidState.capability = uidState.pendingCapability;
-        uidState.appWidgetVisible = uidState.pendingAppWidgetVisible;
-        uidState.pendingStateCommitTime = 0;
-    }
-
     private void updateAppWidgetVisibility(SparseArray<String> uidPackageNames, boolean visible) {
         synchronized (this) {
-            for (int i = uidPackageNames.size() - 1; i >= 0; i--) {
-                final int uid = uidPackageNames.keyAt(i);
-                final UidState uidState = getUidStateLocked(uid, true);
-                if (uidState != null && (uidState.pendingAppWidgetVisible != visible)) {
-                    uidState.pendingAppWidgetVisible = visible;
-                    if (uidState.pendingAppWidgetVisible != uidState.appWidgetVisible) {
-                        commitUidPendingStateLocked(uidState);
-                    }
-                }
-            }
+            getUidStateTracker().updateAppWidgetVisibility(uidPackageNames, visible);
         }
     }
 
@@ -4520,9 +4373,8 @@
                 final PackageManager pm = mContext.getPackageManager();
                 final String supplementalPackageName = pm.getSdkSandboxPackageName();
                 if (Objects.equals(packageName, supplementalPackageName)) {
-                    int supplementalAppId = pm.getPackageUid(supplementalPackageName,
-                            PackageManager.PackageInfoFlags.of(0));
-                    uid = UserHandle.getUid(UserHandle.getUserId(uid), supplementalAppId);
+                    uid = pm.getPackageUidAsUser(supplementalPackageName,
+                            PackageManager.PackageInfoFlags.of(0), UserHandle.getUserId(uid));
                 }
             } catch (PackageManager.NameNotFoundException e) {
                 // Shouldn't happen for the supplemental package
@@ -5881,6 +5733,7 @@
         boolean includeDiscreteOps = false;
         int nDiscreteOps = 10;
         @HistoricalOpsRequestFilter int dumpFilter = 0;
+        boolean dumpAll = false;
 
         if (args != null) {
             for (int i = 0; i < args.length; i++) {
@@ -5890,6 +5743,7 @@
                     return;
                 } else if ("-a".equals(arg)) {
                     // dump all data
+                    dumpAll = true;
                 } else if ("--op".equals(arg)) {
                     i++;
                     if (i >= args.length) {
@@ -6203,31 +6057,7 @@
                 }
 
                 pw.print("  Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":");
-                pw.print("    state=");
-                pw.println(AppOpsManager.getUidStateName(uidState.state));
-                if (uidState.state != uidState.pendingState) {
-                    pw.print("    pendingState=");
-                    pw.println(AppOpsManager.getUidStateName(uidState.pendingState));
-                }
-                pw.print("    capability=");
-                ActivityManager.printCapabilitiesFull(pw, uidState.capability);
-                pw.println();
-                if (uidState.capability != uidState.pendingCapability) {
-                    pw.print("    pendingCapability=");
-                    ActivityManager.printCapabilitiesFull(pw, uidState.pendingCapability);
-                    pw.println();
-                }
-                pw.print("    appWidgetVisible=");
-                pw.println(uidState.appWidgetVisible);
-                if (uidState.appWidgetVisible != uidState.pendingAppWidgetVisible) {
-                    pw.print("    pendingAppWidgetVisible=");
-                    pw.println(uidState.pendingAppWidgetVisible);
-                }
-                if (uidState.pendingStateCommitTime != 0) {
-                    pw.print("    pendingStateCommitTime=");
-                    TimeUtils.formatDuration(uidState.pendingStateCommitTime, nowElapsed, pw);
-                    pw.println();
-                }
+                uidState.dump(pw, nowElapsed);
                 if (uidState.foregroundOps != null && (dumpMode < 0
                         || dumpMode == AppOpsManager.MODE_FOREGROUND)) {
                     pw.println("    foregroundOps:");
@@ -6446,6 +6276,14 @@
             mHistoricalRegistry.dumpDiscreteData(pw, dumpUid, dumpPackage, dumpAttributionTag,
                     dumpFilter, dumpOp, sdf, date, "  ", nDiscreteOps);
         }
+
+        if (dumpAll) {
+            pw.println();
+            pw.println("Uid State Changes Event Log:");
+            if (mUidStateTracker != null) {
+                mUidStateTracker.dumpEvents(pw);
+            }
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTracker.java b/services/core/java/com/android/server/appop/AppOpsUidStateTracker.java
new file mode 100644
index 0000000..3da121b
--- /dev/null
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTracker.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.appop;
+
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
+import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
+import static android.app.ActivityManager.PROCESS_STATE_TOP;
+import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
+import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
+import static android.app.AppOpsManager.UID_STATE_CACHED;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
+import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
+import static android.app.AppOpsManager.UID_STATE_TOP;
+
+import android.os.Handler;
+import android.util.SparseArray;
+
+import java.io.PrintWriter;
+
+interface AppOpsUidStateTracker {
+
+    // Map from process states to the uid states we track.
+    static int processStateToUidState(int procState) {
+        if (procState == PROCESS_STATE_UNKNOWN) {
+            return UID_STATE_CACHED;
+        }
+
+        if (procState <= PROCESS_STATE_PERSISTENT_UI) {
+            return UID_STATE_PERSISTENT;
+        }
+
+        if (procState <= PROCESS_STATE_TOP) {
+            return UID_STATE_TOP;
+        }
+
+        if (procState <= PROCESS_STATE_BOUND_TOP) {
+            return UID_STATE_FOREGROUND;
+        }
+
+        if (procState <= PROCESS_STATE_FOREGROUND_SERVICE) {
+            return UID_STATE_FOREGROUND_SERVICE;
+        }
+
+        if (procState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+            return UID_STATE_FOREGROUND;
+        }
+
+        if (procState <= PROCESS_STATE_RECEIVER) {
+            return UID_STATE_BACKGROUND;
+        }
+
+        return UID_STATE_CACHED;
+    }
+
+    /*
+     * begin data pushed from appopsservice
+     */
+
+    void updateUidProcState(int uid, int procState, int capability);
+
+    void updateAppWidgetVisibility(SparseArray<String> uidPackageNames, boolean visible);
+
+    /*
+     * end data pushed from appopsservice
+     */
+
+    /**
+     * Gets the {@link android.app.AppOpsManager.UidState} that the uid current is in.
+     */
+    int getUidState(int uid);
+
+    /**
+     * Given a uid, code, and mode, resolve any foregroundness to MODE_IGNORED or MODE_ALLOWED
+     */
+    int evalMode(int uid, int code, int mode);
+
+    /**
+     * Listen to changes in {@link android.app.AppOpsManager.UidState}
+     */
+    void addUidStateChangedCallback(Handler handler,
+            UidStateChangedCallback callback);
+
+    /**
+     * Remove a {@link UidStateChangedCallback}
+     */
+    void removeUidStateChangedCallback(UidStateChangedCallback callback);
+
+    interface UidStateChangedCallback {
+        /**
+         * Invoked when a UID's {@link android.app.AppOpsManager.UidState} changes.
+         * @param uid The uid that changed.
+         * @param uidState The state that was changed to.
+         * @param foregroundModeMayChange True if there may be a op in MODE_FOREGROUND whose
+         *                               evaluated result may have changed.
+         */
+        void onUidStateChanged(int uid, int uidState, boolean foregroundModeMayChange);
+    }
+
+    void dumpUidState(PrintWriter pw, int uid, long nowElapsed);
+
+    void dumpEvents(PrintWriter pw);
+}
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
new file mode 100644
index 0000000..ca5bfb3
--- /dev/null
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
@@ -0,0 +1,601 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.appop;
+
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.app.ActivityManager.ProcessCapability;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_IGNORED;
+import static android.app.AppOpsManager.OP_CAMERA;
+import static android.app.AppOpsManager.OP_RECORD_AUDIO;
+import static android.app.AppOpsManager.UID_STATE_CACHED;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
+import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
+import static android.app.AppOpsManager.UID_STATE_TOP;
+
+import static com.android.server.appop.AppOpsUidStateTracker.processStateToUidState;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.AppOpsManager;
+import android.os.Handler;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
+import android.util.SparseLongArray;
+import android.util.TimeUtils;
+
+import com.android.internal.os.Clock;
+import com.android.internal.util.function.pooled.PooledLambda;
+
+import java.io.PrintWriter;
+import java.util.concurrent.CountDownLatch;
+
+class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker {
+
+    private static final String LOG_TAG = AppOpsUidStateTrackerImpl.class.getSimpleName();
+
+    private final Handler mHandler;
+    private final Clock mClock;
+    private ActivityManagerInternal mActivityManagerInternal;
+    private AppOpsService.Constants mConstants;
+
+    private SparseIntArray mUidStates = new SparseIntArray();
+    private SparseIntArray mPendingUidStates = new SparseIntArray();
+    private SparseIntArray mCapability = new SparseIntArray();
+    private SparseIntArray mPendingCapability = new SparseIntArray();
+    private SparseBooleanArray mVisibleAppWidget = new SparseBooleanArray();
+    private SparseBooleanArray mPendingVisibleAppWidget = new SparseBooleanArray();
+    private SparseLongArray mPendingCommitTime = new SparseLongArray();
+    private SparseBooleanArray mPendingGone = new SparseBooleanArray();
+
+    private ArrayMap<UidStateChangedCallback, Handler> mUidStateChangedCallbacks = new ArrayMap<>();
+
+    private final EventLog mEventLog;
+
+    AppOpsUidStateTrackerImpl(ActivityManagerInternal activityManagerInternal,
+            Handler handler, Clock clock, AppOpsService.Constants constants) {
+        mActivityManagerInternal = activityManagerInternal;
+        mHandler = handler;
+        mClock = clock;
+        mConstants = constants;
+
+        mEventLog = new EventLog(handler);
+    }
+
+    @Override
+    public int getUidState(int uid) {
+        return getUidStateLocked(uid);
+    }
+
+    private int getUidStateLocked(int uid) {
+        updateUidPendingStateIfNeeded(uid);
+        return mUidStates.get(uid, UID_STATE_CACHED);
+    }
+
+    @Override
+    public int evalMode(int uid, int code, int mode) {
+        if (mode != AppOpsManager.MODE_FOREGROUND) {
+            return mode;
+        }
+
+        int uidStateValue;
+        int capability;
+        boolean visibleAppWidget;
+        boolean pendingTop;
+        boolean tempAllowlist;
+        uidStateValue = getUidState(uid);
+        capability = getUidCapability(uid);
+        visibleAppWidget = getUidVisibleAppWidget(uid);
+        pendingTop = mActivityManagerInternal.isPendingTopUid(uid);
+        tempAllowlist = mActivityManagerInternal.isTempAllowlistedForFgsWhileInUse(uid);
+
+        int result = evalMode(uidStateValue, code, mode, capability, visibleAppWidget, pendingTop,
+                tempAllowlist);
+        mEventLog.logEvalForegroundMode(uid, uidStateValue, capability, code, result);
+        return result;
+    }
+
+    private static int evalMode(int uidState, int code, int mode, int capability,
+            boolean appWidgetVisible, boolean pendingTop, boolean tempAllowlist) {
+        if (mode != AppOpsManager.MODE_FOREGROUND) {
+            return mode;
+        }
+
+        if (appWidgetVisible || pendingTop || tempAllowlist) {
+            return MODE_ALLOWED;
+        }
+
+        switch (code) {
+            case AppOpsManager.OP_FINE_LOCATION:
+            case AppOpsManager.OP_COARSE_LOCATION:
+            case AppOpsManager.OP_MONITOR_LOCATION:
+            case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION:
+                if ((capability & PROCESS_CAPABILITY_FOREGROUND_LOCATION) == 0) {
+                    return MODE_IGNORED;
+                } else {
+                    return MODE_ALLOWED;
+                }
+            case OP_CAMERA:
+                if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) == 0) {
+                    return MODE_IGNORED;
+                } else {
+                    return MODE_ALLOWED;
+                }
+            case OP_RECORD_AUDIO:
+                if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) == 0) {
+                    return MODE_IGNORED;
+                } else {
+                    return MODE_ALLOWED;
+                }
+        }
+
+        if (uidState > AppOpsManager.resolveFirstUnrestrictedUidState(code)) {
+            return MODE_IGNORED;
+        }
+
+        return MODE_ALLOWED;
+    }
+
+    @Override
+    public void addUidStateChangedCallback(Handler handler, UidStateChangedCallback callback) {
+        if (mUidStateChangedCallbacks.containsKey(callback)) {
+            throw new IllegalStateException("Callback is already registered.");
+        }
+        mUidStateChangedCallbacks.put(callback, handler);
+    }
+
+    @Override
+    public void removeUidStateChangedCallback(UidStateChangedCallback callback) {
+        if (!mUidStateChangedCallbacks.containsKey(callback)) {
+            throw new IllegalStateException("Callback is not registered.");
+        }
+        mUidStateChangedCallbacks.remove(callback);
+    }
+
+    @Override
+    public void updateAppWidgetVisibility(SparseArray<String> uidPackageNames, boolean visible) {
+        int numUids = uidPackageNames.size();
+        for (int i = 0; i < numUids; i++) {
+            int uid = uidPackageNames.keyAt(i);
+            mPendingVisibleAppWidget.put(uid, visible);
+
+            commitUidPendingState(uid);
+        }
+    }
+
+    @Override
+    public void updateUidProcState(int uid, int procState, int capability) {
+        mEventLog.logUpdateUidProcState(uid, procState, capability);
+
+        int uidState = processStateToUidState(procState);
+
+        int prevUidState = mUidStates.get(uid, AppOpsManager.MIN_PRIORITY_UID_STATE);
+        int prevCapability = mCapability.get(uid, PROCESS_CAPABILITY_NONE);
+        long pendingStateCommitTime = mPendingCommitTime.get(uid, 0);
+        if (uidState != prevUidState || capability != prevCapability) {
+            mPendingUidStates.put(uid, uidState);
+            mPendingCapability.put(uid, capability);
+
+            if (procState == PROCESS_STATE_NONEXISTENT) {
+                mPendingGone.put(uid, true);
+                commitUidPendingState(uid);
+            } else if (uidState < prevUidState
+                    || (uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED
+                    && prevUidState > UID_STATE_MAX_LAST_NON_RESTRICTED)) {
+                // We are moving to a more important state, or the new state may be in the
+                // foreground and the old state is in the background, then always do it
+                // immediately.
+                commitUidPendingState(uid);
+            } else if (uidState == prevUidState && capability != prevCapability) {
+                // No change on process state, but process capability has changed.
+                commitUidPendingState(uid);
+            } else if (uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED) {
+                // We are moving to a less important state, but it doesn't cross the restriction
+                // threshold.
+                commitUidPendingState(uid);
+            } else if (pendingStateCommitTime == 0) {
+                // We are moving to a less important state for the first time,
+                // delay the application for a bit.
+                final long settleTime;
+                if (prevUidState <= UID_STATE_TOP) {
+                    settleTime = mConstants.TOP_STATE_SETTLE_TIME;
+                } else if (prevUidState <= UID_STATE_FOREGROUND_SERVICE) {
+                    settleTime = mConstants.FG_SERVICE_STATE_SETTLE_TIME;
+                } else {
+                    settleTime = mConstants.BG_STATE_SETTLE_TIME;
+                }
+                final long commitTime = mClock.elapsedRealtime() + settleTime;
+                mPendingCommitTime.put(uid, commitTime);
+
+                mHandler.sendMessageDelayed(PooledLambda.obtainMessage(
+                                AppOpsUidStateTrackerImpl::updateUidPendingStateIfNeeded, this,
+                                uid), settleTime + 1);
+            }
+        }
+    }
+
+    @Override
+    public void dumpUidState(PrintWriter pw, int uid, long nowElapsed) {
+        int state = mUidStates.get(uid, UID_STATE_CACHED);
+        // if no pendingState set to state to suppress output
+        int pendingState = mPendingUidStates.get(uid, state);
+        pw.print("    state=");
+        pw.println(AppOpsManager.getUidStateName(state));
+        if (state != pendingState) {
+            pw.print("    pendingState=");
+            pw.println(AppOpsManager.getUidStateName(pendingState));
+        }
+        int capability = mCapability.get(uid, PROCESS_CAPABILITY_NONE);
+        // if no pendingCapability set to capability to suppress output
+        int pendingCapability = mPendingCapability.get(uid, capability);
+        pw.print("    capability=");
+        ActivityManager.printCapabilitiesFull(pw, capability);
+        pw.println();
+        if (capability != pendingCapability) {
+            pw.print("    pendingCapability=");
+            ActivityManager.printCapabilitiesFull(pw, pendingCapability);
+            pw.println();
+        }
+        boolean appWidgetVisible = mVisibleAppWidget.get(uid, false);
+        // if no pendingAppWidgetVisible set to appWidgetVisible to suppress output
+        boolean pendingAppWidgetVisible = mPendingVisibleAppWidget.get(uid, appWidgetVisible);
+        pw.print("    appWidgetVisible=");
+        pw.println(appWidgetVisible);
+        if (appWidgetVisible != pendingAppWidgetVisible) {
+            pw.print("    pendingAppWidgetVisible=");
+            pw.println(pendingAppWidgetVisible);
+        }
+        long pendingStateCommitTime = mPendingCommitTime.get(uid, 0);
+        if (pendingStateCommitTime != 0) {
+            pw.print("    pendingStateCommitTime=");
+            TimeUtils.formatDuration(pendingStateCommitTime, nowElapsed, pw);
+            pw.println();
+        }
+    }
+
+    @Override
+    public void dumpEvents(PrintWriter pw) {
+        mEventLog.dumpEvents(pw);
+    }
+
+    private void updateUidPendingStateIfNeeded(int uid) {
+        updateUidPendingStateIfNeededLocked(uid);
+    }
+
+    private void updateUidPendingStateIfNeededLocked(int uid) {
+        long pendingCommitTime = mPendingCommitTime.get(uid, 0);
+        if (pendingCommitTime != 0) {
+            long currentTime = mClock.elapsedRealtime();
+            if (currentTime < mPendingCommitTime.get(uid)) {
+                return;
+            }
+            commitUidPendingState(uid);
+        }
+    }
+
+    private void commitUidPendingState(int uid) {
+        int pendingUidState = mPendingUidStates.get(uid, UID_STATE_CACHED);
+        int pendingCapability = mPendingCapability.get(uid, PROCESS_CAPABILITY_NONE);
+        boolean pendingVisibleAppWidget = mPendingVisibleAppWidget.get(uid, false);
+
+        int uidState = mUidStates.get(uid, UID_STATE_CACHED);
+        int capability = mCapability.get(uid, PROCESS_CAPABILITY_NONE);
+        boolean visibleAppWidget = mVisibleAppWidget.get(uid, false);
+
+        if (uidState != pendingUidState
+                || capability != pendingCapability
+                || visibleAppWidget != pendingVisibleAppWidget) {
+            boolean foregroundChange = uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED
+                    != pendingUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED
+                    || capability != pendingCapability
+                    || visibleAppWidget != pendingVisibleAppWidget;
+
+            if (foregroundChange) {
+                // To save on memory usage, log only interesting changes.
+                mEventLog.logCommitUidState(uid, pendingUidState, pendingCapability,
+                        pendingVisibleAppWidget);
+            }
+
+            for (int i = 0; i < mUidStateChangedCallbacks.size(); i++) {
+                UidStateChangedCallback cb = mUidStateChangedCallbacks.keyAt(i);
+                Handler h = mUidStateChangedCallbacks.valueAt(i);
+
+                h.sendMessage(PooledLambda.obtainMessage(UidStateChangedCallback::onUidStateChanged,
+                        cb, uid, pendingUidState, foregroundChange));
+            }
+        }
+
+        if (mPendingGone.get(uid, false)) {
+            mUidStates.delete(uid);
+            mCapability.delete(uid);
+            mVisibleAppWidget.delete(uid);
+            mPendingGone.delete(uid);
+        } else {
+            mUidStates.put(uid, pendingUidState);
+            mCapability.put(uid, pendingCapability);
+            mVisibleAppWidget.put(uid, pendingVisibleAppWidget);
+        }
+
+        mPendingUidStates.delete(uid);
+        mPendingCapability.delete(uid);
+        mPendingVisibleAppWidget.delete(uid);
+        mPendingCommitTime.delete(uid);
+    }
+
+    private @ProcessCapability int getUidCapability(int uid) {
+        return mCapability.get(uid, ActivityManager.PROCESS_CAPABILITY_NONE);
+    }
+
+    private boolean getUidVisibleAppWidget(int uid) {
+        return mVisibleAppWidget.get(uid, false);
+    }
+
+    private static class EventLog {
+
+        // These seems a bit too verbose and not as useful, turning off for now.
+        // DCE should be able to remove most associated code.
+        // Memory usage: 16 * size bytes
+        private static final int UPDATE_UID_PROC_STATE_LOG_MAX_SIZE = 0;
+        // Memory usage: 20 * size bytes
+        private static final int COMMIT_UID_STATE_LOG_MAX_SIZE = 200;
+        // Memory usage: 24 * size bytes
+        private static final int EVAL_FOREGROUND_MODE_MAX_SIZE = 200;
+
+        private final Handler mHandler;
+
+        private int[][] mUpdateUidProcStateLog = new int[UPDATE_UID_PROC_STATE_LOG_MAX_SIZE][3];
+        private long[] mUpdateUidProcStateLogTimestamps =
+                new long[UPDATE_UID_PROC_STATE_LOG_MAX_SIZE];
+        private int mUpdateUidProcStateLogSize = 0;
+        private int mUpdateUidProcStateLogHead = 0;
+
+        private int[][] mCommitUidStateLog = new int[COMMIT_UID_STATE_LOG_MAX_SIZE][4];
+        private long[] mCommitUidStateLogTimestamps = new long[COMMIT_UID_STATE_LOG_MAX_SIZE];
+        private int mCommitUidStateLogSize = 0;
+        private int mCommitUidStateLogHead = 0;
+
+        private int[][] mEvalForegroundModeLog = new int[EVAL_FOREGROUND_MODE_MAX_SIZE][5];
+        private long[] mEvalForegroundModeLogTimestamps = new long[EVAL_FOREGROUND_MODE_MAX_SIZE];
+        private int mEvalForegroundModeLogSize = 0;
+        private int mEvalForegroundModeLogHead = 0;
+
+        EventLog(Handler handler) {
+            mHandler = handler;
+        }
+
+        void logUpdateUidProcState(int uid, int procState, int capability) {
+            if (UPDATE_UID_PROC_STATE_LOG_MAX_SIZE == 0) {
+                return;
+            }
+            mHandler.sendMessage(PooledLambda.obtainMessage(EventLog::logUpdateUidProcStateAsync,
+                    this, System.currentTimeMillis(), uid, procState, capability));
+        }
+
+        void logUpdateUidProcStateAsync(long timestamp, int uid, int procState, int capability) {
+            int idx = (mUpdateUidProcStateLogHead + mUpdateUidProcStateLogSize)
+                    % UPDATE_UID_PROC_STATE_LOG_MAX_SIZE;
+            if (mUpdateUidProcStateLogSize == UPDATE_UID_PROC_STATE_LOG_MAX_SIZE) {
+                mUpdateUidProcStateLogHead =
+                        (mUpdateUidProcStateLogHead + 1) % UPDATE_UID_PROC_STATE_LOG_MAX_SIZE;
+            } else {
+                mUpdateUidProcStateLogSize++;
+            }
+
+            mUpdateUidProcStateLog[idx][0] = uid;
+            mUpdateUidProcStateLog[idx][1] = procState;
+            mUpdateUidProcStateLog[idx][2] = capability;
+            mUpdateUidProcStateLogTimestamps[idx] = timestamp;
+        }
+
+        void logCommitUidState(int uid, int uidState, int capability, boolean visible) {
+            if (COMMIT_UID_STATE_LOG_MAX_SIZE == 0) {
+                return;
+            }
+            mHandler.sendMessage(PooledLambda.obtainMessage(EventLog::logCommitUidStateAsync,
+                    this, System.currentTimeMillis(), uid, uidState, capability, visible));
+        }
+
+        void logCommitUidStateAsync(long timestamp, int uid, int uidState, int capability,
+                boolean visible) {
+            int idx = (mCommitUidStateLogHead + mCommitUidStateLogSize)
+                    % COMMIT_UID_STATE_LOG_MAX_SIZE;
+            if (mCommitUidStateLogSize == COMMIT_UID_STATE_LOG_MAX_SIZE) {
+                mCommitUidStateLogHead =
+                        (mCommitUidStateLogHead + 1) % COMMIT_UID_STATE_LOG_MAX_SIZE;
+            } else {
+                mCommitUidStateLogSize++;
+            }
+
+            mCommitUidStateLog[idx][0] = uid;
+            mCommitUidStateLog[idx][1] = uidState;
+            mCommitUidStateLog[idx][2] = capability;
+            mCommitUidStateLog[idx][3] = visible ? 1 : 0;
+            mCommitUidStateLogTimestamps[idx] = timestamp;
+        }
+
+        void logEvalForegroundMode(int uid, int uidState, int capability, int code, int result) {
+            if (EVAL_FOREGROUND_MODE_MAX_SIZE == 0) {
+                return;
+            }
+            mHandler.sendMessage(PooledLambda.obtainMessage(EventLog::logEvalForegroundModeAsync,
+                    this, System.currentTimeMillis(), uid, uidState, capability, code, result));
+        }
+
+        void logEvalForegroundModeAsync(long timestamp, int uid, int uidState, int capability,
+                int code, int result) {
+            int idx = (mEvalForegroundModeLogHead + mEvalForegroundModeLogSize)
+                    % EVAL_FOREGROUND_MODE_MAX_SIZE;
+            if (mEvalForegroundModeLogSize == EVAL_FOREGROUND_MODE_MAX_SIZE) {
+                mEvalForegroundModeLogHead =
+                        (mEvalForegroundModeLogHead + 1) % EVAL_FOREGROUND_MODE_MAX_SIZE;
+            } else {
+                mEvalForegroundModeLogSize++;
+            }
+
+            mEvalForegroundModeLog[idx][0] = uid;
+            mEvalForegroundModeLog[idx][1] = uidState;
+            mEvalForegroundModeLog[idx][2] = capability;
+            mEvalForegroundModeLog[idx][3] = code;
+            mEvalForegroundModeLog[idx][4] = result;
+            mEvalForegroundModeLogTimestamps[idx] = timestamp;
+        }
+
+        void dumpEvents(PrintWriter pw) {
+            if (Thread.currentThread() != mHandler.getLooper().getThread()) {
+                // All operations are done on the handler's thread
+                CountDownLatch latch = new CountDownLatch(1);
+                mHandler.post(() -> {
+                    dumpEvents(pw);
+                    latch.countDown();
+                });
+
+                try {
+                    latch.await();
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+                return;
+            }
+
+            int updateIdx = 0;
+            int commitIdx = 0;
+            int evalIdx = 0;
+
+            while (updateIdx < mUpdateUidProcStateLogSize
+                    || commitIdx < mCommitUidStateLogSize
+                    || evalIdx < mEvalForegroundModeLogSize) {
+                int updatePtr = 0;
+                int commitPtr = 0;
+                int evalPtr = 0;
+                if (UPDATE_UID_PROC_STATE_LOG_MAX_SIZE != 0) {
+                    updatePtr = (mUpdateUidProcStateLogHead + updateIdx)
+                            % UPDATE_UID_PROC_STATE_LOG_MAX_SIZE;
+                }
+                if (COMMIT_UID_STATE_LOG_MAX_SIZE != 0) {
+                    commitPtr = (mCommitUidStateLogHead + commitIdx)
+                            % COMMIT_UID_STATE_LOG_MAX_SIZE;
+                }
+                if (EVAL_FOREGROUND_MODE_MAX_SIZE != 0) {
+                    evalPtr = (mEvalForegroundModeLogHead + evalIdx)
+                            % EVAL_FOREGROUND_MODE_MAX_SIZE;
+                }
+
+                long aTimestamp = updateIdx < mUpdateUidProcStateLogSize
+                        ? mUpdateUidProcStateLogTimestamps[updatePtr] : Long.MAX_VALUE;
+                long bTimestamp = commitIdx < mCommitUidStateLogSize
+                        ? mCommitUidStateLogTimestamps[commitPtr] : Long.MAX_VALUE;
+                long cTimestamp = evalIdx < mEvalForegroundModeLogSize
+                        ? mEvalForegroundModeLogTimestamps[evalPtr] : Long.MAX_VALUE;
+
+                if (aTimestamp <= bTimestamp && aTimestamp <= cTimestamp) {
+                    dumpUpdateUidProcState(pw, updatePtr);
+                    updateIdx++;
+                } else if (bTimestamp <= cTimestamp) {
+                    dumpCommitUidState(pw, commitPtr);
+                    commitIdx++;
+                } else {
+                    dumpEvalForegroundMode(pw, evalPtr);
+                    evalIdx++;
+                }
+            }
+        }
+
+        void dumpUpdateUidProcState(PrintWriter pw, int idx) {
+            long timestamp = mUpdateUidProcStateLogTimestamps[idx];
+            int uid = mUpdateUidProcStateLog[idx][0];
+            int procState = mUpdateUidProcStateLog[idx][1];
+            int capability = mUpdateUidProcStateLog[idx][2];
+
+            TimeUtils.dumpTime(pw, timestamp);
+
+            pw.print(" UPDATE_UID_PROC_STATE");
+
+            pw.print(" uid=");
+            pw.print(uid);
+
+            pw.print(" procState=");
+            pw.print(String.format("%-30s", ActivityManager.procStateToString(procState)));
+
+            pw.print(" capability=");
+            pw.print(ActivityManager.getCapabilitiesSummary(capability));
+
+            pw.println();
+        }
+
+        void dumpCommitUidState(PrintWriter pw, int idx) {
+            long timestamp = mCommitUidStateLogTimestamps[idx];
+            int uid = mCommitUidStateLog[idx][0];
+            int uidState = mCommitUidStateLog[idx][1];
+            int capability = mCommitUidStateLog[idx][2];
+            boolean visibleAppWidget = mCommitUidStateLog[idx][3] != 0;
+
+            TimeUtils.dumpTime(pw, timestamp);
+
+            pw.print(" COMMIT_UID_STATE     ");
+
+            pw.print(" uid=");
+            pw.print(uid);
+
+            pw.print(" uidState=");
+            pw.print(String.format("%-30s", AppOpsManager.uidStateToString(uidState)));
+
+            pw.print(" capability=");
+            pw.print(ActivityManager.getCapabilitiesSummary(capability));
+
+            pw.print(" visibleAppWidget=");
+            pw.print(visibleAppWidget);
+
+            pw.println();
+        }
+
+        void dumpEvalForegroundMode(PrintWriter pw, int idx) {
+            long timestamp = mEvalForegroundModeLogTimestamps[idx];
+            int uid = mEvalForegroundModeLog[idx][0];
+            int uidState = mEvalForegroundModeLog[idx][1];
+            int capability = mEvalForegroundModeLog[idx][2];
+            int code = mEvalForegroundModeLog[idx][3];
+            int result = mEvalForegroundModeLog[idx][4];
+
+            TimeUtils.dumpTime(pw, timestamp);
+
+            pw.print(" EVAL_FOREGROUND_MODE ");
+
+            pw.print(" uid=");
+            pw.print(uid);
+
+            pw.print(" uidState=");
+            pw.print(String.format("%-30s", AppOpsManager.uidStateToString(uidState)));
+
+            pw.print(" capability=");
+            pw.print(ActivityManager.getCapabilitiesSummary(capability));
+
+            pw.print(" code=");
+            pw.print(String.format("%-20s", AppOpsManager.opToName(code)));
+
+            pw.print(" result=");
+            pw.print(AppOpsManager.modeToName(result));
+
+            pw.println();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index cb04ddf..372bc8a 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -31,7 +31,6 @@
 import android.opengl.EGLSurface;
 import android.opengl.GLES11Ext;
 import android.opengl.GLES20;
-import android.os.IBinder;
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
@@ -39,6 +38,7 @@
 import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
+import android.window.ScreenCapture;
 
 import com.android.server.LocalServices;
 import com.android.server.policy.WindowManagerPolicy;
@@ -169,19 +169,11 @@
         mDisplayWidth = displayInfo.getNaturalWidth();
         mDisplayHeight = displayInfo.getNaturalHeight();
 
-        final IBinder token = SurfaceControl.getInternalDisplayToken();
-        if (token == null) {
-            Slog.e(TAG,
-                    "Failed to take screenshot because internal display is disconnected");
-            return false;
-        }
-        final boolean isWideColor = SurfaceControl.getDynamicDisplayInfo(token).activeColorMode
-                == Display.COLOR_MODE_DISPLAY_P3;
-
+        final boolean isWideColor = displayInfo.colorMode == Display.COLOR_MODE_DISPLAY_P3;
         // Set mPrepared here so if initialization fails, resources can be cleaned up.
         mPrepared = true;
 
-        final SurfaceControl.ScreenshotHardwareBuffer hardwareBuffer = captureScreen();
+        final ScreenCapture.ScreenshotHardwareBuffer hardwareBuffer = captureScreen();
         if (hardwareBuffer == null) {
             dismiss();
             return false;
@@ -508,7 +500,7 @@
     }
 
     private boolean setScreenshotTextureAndSetViewport(
-            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) {
+            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer) {
         if (!attachEglContext()) {
             return false;
         }
@@ -559,8 +551,8 @@
         }
     }
 
-    private SurfaceControl.ScreenshotHardwareBuffer captureScreen() {
-        SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
+    private ScreenCapture.ScreenshotHardwareBuffer captureScreen() {
+        ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
                 mDisplayManagerInternal.systemScreenshot(mDisplayId);
         if (screenshotBuffer == null) {
             Slog.e(TAG, "Failed to take screenshot. Buffer is null");
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index fd30d7e..9ab78bc 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -35,6 +35,7 @@
 import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
 import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
 import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
+import static android.os.Process.ROOT_UID;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -118,6 +119,7 @@
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.window.DisplayWindowPolicyController;
+import android.window.ScreenCapture;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -1171,6 +1173,10 @@
     }
 
     private boolean validatePackageName(int uid, String packageName) {
+        // Root doesn't have a package name.
+        if (uid == ROOT_UID) {
+            return true;
+        }
         if (packageName != null) {
             String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
             if (packageNames != null) {
@@ -2051,8 +2057,8 @@
         return null;
     }
 
-    private SurfaceControl.ScreenshotHardwareBuffer systemScreenshotInternal(int displayId) {
-        final SurfaceControl.DisplayCaptureArgs captureArgs;
+    private ScreenCapture.ScreenshotHardwareBuffer systemScreenshotInternal(int displayId) {
+        final ScreenCapture.DisplayCaptureArgs captureArgs;
         synchronized (mSyncRoot) {
             final IBinder token = getDisplayToken(displayId);
             if (token == null) {
@@ -2064,27 +2070,27 @@
             }
 
             final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
-            captureArgs = new SurfaceControl.DisplayCaptureArgs.Builder(token)
+            captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(token)
                     .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight())
                     .setUseIdentityTransform(true)
                     .setCaptureSecureLayers(true)
                     .setAllowProtected(true)
                     .build();
         }
-        return SurfaceControl.captureDisplay(captureArgs);
+        return ScreenCapture.captureDisplay(captureArgs);
     }
 
-    private SurfaceControl.ScreenshotHardwareBuffer userScreenshotInternal(int displayId) {
+    private ScreenCapture.ScreenshotHardwareBuffer userScreenshotInternal(int displayId) {
         synchronized (mSyncRoot) {
             final IBinder token = getDisplayToken(displayId);
             if (token == null) {
                 return null;
             }
 
-            final SurfaceControl.DisplayCaptureArgs captureArgs =
-                    new SurfaceControl.DisplayCaptureArgs.Builder(token)
+            final ScreenCapture.DisplayCaptureArgs captureArgs =
+                    new ScreenCapture.DisplayCaptureArgs.Builder(token)
                             .build();
-            return SurfaceControl.captureDisplay(captureArgs);
+            return ScreenCapture.captureDisplay(captureArgs);
         }
     }
 
@@ -3487,6 +3493,17 @@
                 Binder.restoreCallingIdentity(token);
             }
         }
+
+        @Override
+        public void setDisplayIdToMirror(IBinder token, int displayId) {
+            synchronized (mSyncRoot) {
+                final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+                if (mVirtualDisplayAdapter != null) {
+                    mVirtualDisplayAdapter.setDisplayIdToMirror(token,
+                            display == null ? Display.INVALID_DISPLAY : displayId);
+                }
+            }
+        }
     }
 
     private static boolean isValidBrightness(float brightness) {
@@ -3575,12 +3592,12 @@
         }
 
         @Override
-        public SurfaceControl.ScreenshotHardwareBuffer systemScreenshot(int displayId) {
+        public ScreenCapture.ScreenshotHardwareBuffer systemScreenshot(int displayId) {
             return systemScreenshotInternal(displayId);
         }
 
         @Override
-        public SurfaceControl.ScreenshotHardwareBuffer userScreenshot(int displayId) {
+        public ScreenCapture.ScreenshotHardwareBuffer userScreenshot(int displayId) {
             return userScreenshotInternal(displayId);
         }
 
@@ -3867,6 +3884,19 @@
                 return displayIdToMirror;
             }
         }
+
+        @Override
+        public SurfaceControl.DisplayPrimaries getDisplayNativePrimaries(int displayId) {
+            IBinder displayToken;
+            synchronized (mSyncRoot) {
+                displayToken = getDisplayToken(displayId);
+                if (displayToken == null) {
+                    throw new IllegalArgumentException("Invalid displayId=" + displayId);
+                }
+            }
+
+            return SurfaceControl.getDisplayNativePrimaries(displayToken);
+        }
     }
 
     class DesiredDisplayModeSpecsObserver
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 38728ce..20b82c3 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -161,6 +161,13 @@
         }
     }
 
+    void setDisplayIdToMirror(IBinder appToken, int displayId) {
+        VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
+        if (device != null) {
+            device.setDisplayIdToMirror(displayId);
+        }
+    }
+
     public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
         VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
         if (device != null) {
@@ -313,6 +320,15 @@
             return mDisplayIdToMirror;
         }
 
+        void setDisplayIdToMirror(int displayIdToMirror) {
+            if (mDisplayIdToMirror != displayIdToMirror) {
+                mDisplayIdToMirror = displayIdToMirror;
+                mInfo = null;
+                sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
+                sendTraversalRequestLocked();
+            }
+        }
+
         @Override
         public boolean isWindowManagerMirroringLocked() {
             return mIsWindowManagerMirroring;
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index b51f3f5..21a8518 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -50,6 +50,7 @@
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.ColorDisplayManager.AutoMode;
 import android.hardware.display.ColorDisplayManager.ColorMode;
+import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.IColorDisplayManager;
 import android.hardware.display.Time;
 import android.net.Uri;
@@ -154,7 +155,8 @@
 
     @VisibleForTesting
     final DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController =
-            new DisplayWhiteBalanceTintController();
+            new DisplayWhiteBalanceTintController(
+                    LocalServices.getService(DisplayManagerInternal.class));
     private final NightDisplayTintController mNightDisplayTintController =
             new NightDisplayTintController();
     private final TintController mGlobalSaturationTintController =
diff --git a/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
index 93a78c1..c5dd6ac 100644
--- a/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
+++ b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
@@ -16,6 +16,8 @@
 
 package com.android.server.display.color;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
 
 import android.annotation.NonNull;
@@ -24,10 +26,9 @@
 import android.content.res.Resources;
 import android.graphics.ColorSpace;
 import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.DisplayManagerInternal;
 import android.opengl.Matrix;
-import android.os.IBinder;
 import android.util.Slog;
-import android.view.SurfaceControl;
 import android.view.SurfaceControl.DisplayPrimaries;
 
 import com.android.internal.R;
@@ -64,6 +65,12 @@
     // This feature becomes disallowed if the device is in an unsupported strong/light state.
     private boolean mIsAllowed = true;
 
+    private final DisplayManagerInternal mDisplayManagerInternal;
+
+    DisplayWhiteBalanceTintController(DisplayManagerInternal dm) {
+        mDisplayManagerInternal = dm;
+    }
+
     @Override
     public void setUp(Context context, boolean needsLinear) {
         mSetUp = false;
@@ -287,12 +294,8 @@
     }
 
     private ColorSpace.Rgb getDisplayColorSpaceFromSurfaceControl() {
-        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
-        if (displayToken == null) {
-            return null;
-        }
-
-        DisplayPrimaries primaries = SurfaceControl.getDisplayNativePrimaries(displayToken);
+        DisplayPrimaries primaries =
+                mDisplayManagerInternal.getDisplayNativePrimaries(DEFAULT_DISPLAY);
         if (primaries == null || primaries.red == null || primaries.green == null
                 || primaries.blue == null || primaries.white == null) {
             return null;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 99bbc3f..32ff5e22 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -71,6 +71,9 @@
     private static final String TAG = "HdmiCecLocalDeviceAudioSystem";
 
     private static final boolean WAKE_ON_HOTPLUG = false;
+    private static final int MAX_CHANNELS = 8;
+    private static final HashMap<Integer, List<Integer>> AUDIO_CODECS_MAP =
+            mapAudioCodecWithAudioFormat();
 
     // Whether the System Audio Control feature is enabled or not. True by default.
     @GuardedBy("mLock")
@@ -485,17 +488,17 @@
             }
         }
 
-        @AudioCodec int[] audioFormatCodes = parseAudioFormatCodes(message.getParams());
+        @AudioCodec int[] audioCodecs = parseAudioCodecs(message.getParams());
         byte[] sadBytes;
         if (config != null && config.size() > 0) {
-            sadBytes = getSupportedShortAudioDescriptorsFromConfig(config, audioFormatCodes);
+            sadBytes = getSupportedShortAudioDescriptorsFromConfig(config, audioCodecs);
         } else {
             AudioDeviceInfo deviceInfo = getSystemAudioDeviceInfo();
             if (deviceInfo == null) {
                 return Constants.ABORT_UNABLE_TO_DETERMINE;
             }
 
-            sadBytes = getSupportedShortAudioDescriptors(deviceInfo, audioFormatCodes);
+            sadBytes = getSupportedShortAudioDescriptors(deviceInfo, audioCodecs);
         }
 
         if (sadBytes.length == 0) {
@@ -508,11 +511,12 @@
         }
     }
 
-    private byte[] getSupportedShortAudioDescriptors(
-            AudioDeviceInfo deviceInfo, @AudioCodec int[] audioFormatCodes) {
-        ArrayList<byte[]> sads = new ArrayList<>(audioFormatCodes.length);
-        for (@AudioCodec int audioFormatCode : audioFormatCodes) {
-            byte[] sad = getSupportedShortAudioDescriptor(deviceInfo, audioFormatCode);
+    @VisibleForTesting
+    byte[] getSupportedShortAudioDescriptors(
+            AudioDeviceInfo deviceInfo, @AudioCodec int[] audioCodecs) {
+        ArrayList<byte[]> sads = new ArrayList<>(audioCodecs.length);
+        for (@AudioCodec int audioCodec : audioCodecs) {
+            byte[] sad = getSupportedShortAudioDescriptor(deviceInfo, audioCodec);
             if (sad != null) {
                 if (sad.length == 3) {
 
@@ -520,7 +524,7 @@
                 } else {
                     HdmiLogger.warning(
                             "Dropping Short Audio Descriptor with length %d for requested codec %x",
-                            sad.length, audioFormatCode);
+                            sad.length, audioCodec);
                 }
             }
         }
@@ -528,7 +532,7 @@
     }
 
     private byte[] getSupportedShortAudioDescriptorsFromConfig(
-            List<DeviceConfig> deviceConfig, @AudioCodec int[] audioFormatCodes) {
+            List<DeviceConfig> deviceConfig, @AudioCodec int[] audioCodecs) {
         DeviceConfig deviceConfigToUse = null;
         String audioDeviceName = SystemProperties.get(
                 Constants.PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT,
@@ -544,13 +548,13 @@
             return new byte[0];
         }
         HashMap<Integer, byte[]> map = new HashMap<>();
-        ArrayList<byte[]> sads = new ArrayList<>(audioFormatCodes.length);
+        ArrayList<byte[]> sads = new ArrayList<>(audioCodecs.length);
         for (CodecSad codecSad : deviceConfigToUse.supportedCodecs) {
             map.put(codecSad.audioCodec, codecSad.sad);
         }
-        for (int i = 0; i < audioFormatCodes.length; i++) {
-            if (map.containsKey(audioFormatCodes[i])) {
-                byte[] sad = map.get(audioFormatCodes[i]);
+        for (int i = 0; i < audioCodecs.length; i++) {
+            if (map.containsKey(audioCodecs[i])) {
+                byte[] sad = map.get(audioCodecs[i]);
                 if (sad != null && sad.length == 3) {
                     sads.add(sad);
                 }
@@ -572,42 +576,171 @@
 
     /**
      * Returns a 3 byte short audio descriptor as described in CEC 1.4 table 29 or null if the
-     * audioFormatCode is not supported.
+     * audioCodec is not supported.
      */
     @Nullable
-    private byte[] getSupportedShortAudioDescriptor(
-            AudioDeviceInfo deviceInfo, @AudioCodec int audioFormatCode) {
-        switch (audioFormatCode) {
-            case Constants.AUDIO_CODEC_NONE: {
-                return null;
-            }
-            case Constants.AUDIO_CODEC_LPCM: {
-                return getLpcmShortAudioDescriptor(deviceInfo);
-            }
-            // TODO(b/80297701): implement the rest of the codecs
-            case Constants.AUDIO_CODEC_DD:
-            case Constants.AUDIO_CODEC_MPEG1:
-            case Constants.AUDIO_CODEC_MP3:
-            case Constants.AUDIO_CODEC_MPEG2:
-            case Constants.AUDIO_CODEC_AAC:
-            case Constants.AUDIO_CODEC_DTS:
-            case Constants.AUDIO_CODEC_ATRAC:
-            case Constants.AUDIO_CODEC_ONEBITAUDIO:
-            case Constants.AUDIO_CODEC_DDP:
-            case Constants.AUDIO_CODEC_DTSHD:
-            case Constants.AUDIO_CODEC_TRUEHD:
-            case Constants.AUDIO_CODEC_DST:
-            case Constants.AUDIO_CODEC_WMAPRO:
-            default: {
-                return null;
+    @VisibleForTesting
+    byte[] getSupportedShortAudioDescriptor(
+            AudioDeviceInfo deviceInfo, @AudioCodec int audioCodec) {
+        byte[] shortAudioDescriptor = new byte[3];
+
+        int[] deviceSupportedAudioFormats = deviceInfo.getEncodings();
+        // Return null when audioCodec or device does not support any audio formats.
+        if (!AUDIO_CODECS_MAP.containsKey(audioCodec) || deviceSupportedAudioFormats.length == 0) {
+            return null;
+        }
+        List<Integer> audioCodecSupportedAudioFormats = AUDIO_CODECS_MAP.get(audioCodec);
+
+        for (int supportedAudioFormat : deviceSupportedAudioFormats) {
+            if (audioCodecSupportedAudioFormats.contains(supportedAudioFormat)) {
+                // Initialise the first two bytes of short audio descriptor.
+                shortAudioDescriptor[0] = getFirstByteOfSAD(deviceInfo, audioCodec);
+                shortAudioDescriptor[1] = getSecondByteOfSAD(deviceInfo);
+                switch (audioCodec) {
+                    case Constants.AUDIO_CODEC_NONE: {
+                        return null;
+                    }
+                    case Constants.AUDIO_CODEC_LPCM: {
+                        if (supportedAudioFormat == AudioFormat.ENCODING_PCM_16BIT) {
+                            shortAudioDescriptor[2] = (byte) 0x01;
+                        } else if (supportedAudioFormat
+                                == AudioFormat.ENCODING_PCM_24BIT_PACKED) {
+                            shortAudioDescriptor[2] = (byte) 0x04;
+                        } else {
+                            // Since no bit is reserved for these audio formats in LPCM codec.
+                            shortAudioDescriptor[2] = (byte) 0x00;
+                        }
+                        return shortAudioDescriptor;
+                    }
+                    case Constants.AUDIO_CODEC_DD:
+                    case Constants.AUDIO_CODEC_MPEG1:
+                    case Constants.AUDIO_CODEC_MP3:
+                    case Constants.AUDIO_CODEC_MPEG2:
+                    case Constants.AUDIO_CODEC_AAC:
+                    case Constants.AUDIO_CODEC_DTS: {
+                        shortAudioDescriptor[2] = getThirdSadByteForCodecs2Through8(deviceInfo);
+                        return shortAudioDescriptor;
+                    }
+                    case Constants.AUDIO_CODEC_DDP:
+                    case Constants.AUDIO_CODEC_DTSHD:
+                    case Constants.AUDIO_CODEC_TRUEHD: {
+                        // Default value is 0x0 unless defined by Audio Codec Vendor.
+                        shortAudioDescriptor[2] = (byte) 0x00;
+                        return shortAudioDescriptor;
+                    }
+                    case Constants.AUDIO_CODEC_ATRAC:
+                    case Constants.AUDIO_CODEC_ONEBITAUDIO:
+                    case Constants.AUDIO_CODEC_DST:
+                    case Constants.AUDIO_CODEC_WMAPRO:
+                        // Not supported.
+                    default: {
+                        return null;
+                    }
+                }
             }
         }
+        return null;
     }
 
-    @Nullable
-    private byte[] getLpcmShortAudioDescriptor(AudioDeviceInfo deviceInfo) {
-        // TODO(b/80297701): implement
-        return null;
+    private static HashMap<Integer, List<Integer>> mapAudioCodecWithAudioFormat() {
+        // Mapping the values of @AudioCodec audio codecs with @AudioFormat audio formats.
+        HashMap<Integer, List<Integer>> audioCodecsMap = new HashMap<Integer, List<Integer>>();
+
+        audioCodecsMap.put(Constants.AUDIO_CODEC_NONE, List.of(AudioFormat.ENCODING_DEFAULT));
+        audioCodecsMap.put(
+                Constants.AUDIO_CODEC_LPCM,
+                List.of(
+                        AudioFormat.ENCODING_PCM_8BIT,
+                        AudioFormat.ENCODING_PCM_16BIT,
+                        AudioFormat.ENCODING_PCM_FLOAT,
+                        AudioFormat.ENCODING_PCM_24BIT_PACKED,
+                        AudioFormat.ENCODING_PCM_32BIT));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_DD, List.of(AudioFormat.ENCODING_AC3));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_MPEG1, List.of(AudioFormat.ENCODING_AAC_HE_V1));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_MPEG2, List.of(AudioFormat.ENCODING_AAC_HE_V2));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_MP3, List.of(AudioFormat.ENCODING_MP3));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_AAC, List.of(AudioFormat.ENCODING_AAC_LC));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_DTS, List.of(AudioFormat.ENCODING_DTS));
+        audioCodecsMap.put(
+                Constants.AUDIO_CODEC_DDP,
+                List.of(AudioFormat.ENCODING_E_AC3, AudioFormat.ENCODING_E_AC3_JOC));
+        audioCodecsMap.put(Constants.AUDIO_CODEC_DTSHD, List.of(AudioFormat.ENCODING_DTS_HD));
+        audioCodecsMap.put(
+                Constants.AUDIO_CODEC_TRUEHD,
+                List.of(AudioFormat.ENCODING_DOLBY_TRUEHD, AudioFormat.ENCODING_DOLBY_MAT));
+
+        return audioCodecsMap;
+    }
+
+    private byte getFirstByteOfSAD(AudioDeviceInfo deviceInfo, @AudioCodec int audioCodec) {
+        byte firstByte = 0;
+        int maxNumberOfChannels = getMaxNumberOfChannels(deviceInfo);
+
+        // Fill bits 0-2 of the first byte.
+        firstByte |= (maxNumberOfChannels - 1);
+
+        // Fill bits 3-6 of the first byte.
+        firstByte |= (audioCodec << 3);
+
+        return firstByte;
+    }
+
+    private byte getSecondByteOfSAD(AudioDeviceInfo deviceInfo) {
+        ArrayList<Integer> samplingRates =
+                new ArrayList<Integer>(Arrays.asList(32, 44, 48, 88, 96, 176, 192));
+
+        // samplingRatesdevicesupports is guaranteed to be not null
+        int[] samplingRatesDeviceSupports = deviceInfo.getSampleRates();
+        if (samplingRatesDeviceSupports.length == 0) {
+            Slog.e(TAG, "Device supports arbitrary rates");
+            // Since device supports arbitrary rates, we will return 0x7f since bit 7 is reserved.
+            return (byte) 0x7f;
+        }
+        byte secondByte = 0;
+        for (int supportedSampleRate : samplingRatesDeviceSupports) {
+            if (samplingRates.contains(supportedSampleRate)) {
+                int index = samplingRates.indexOf(supportedSampleRate);
+                // Setting the bit of a sample rate which is being supported.
+                secondByte |= (1 << index);
+            }
+        }
+
+        return secondByte;
+    }
+
+    /**
+     * Empty array from deviceInfo.getChannelCounts() implies device supports arbitrary channel
+     * counts and hence we assume max channels are supported by the device.
+     */
+    private int getMaxNumberOfChannels(AudioDeviceInfo deviceInfo) {
+        int maxNumberOfChannels = MAX_CHANNELS;
+        int[] channelCounts = deviceInfo.getChannelCounts();
+        if (channelCounts.length != 0) {
+            maxNumberOfChannels = channelCounts[channelCounts.length - 1];
+            maxNumberOfChannels =
+                    (maxNumberOfChannels > MAX_CHANNELS ? MAX_CHANNELS : maxNumberOfChannels);
+        }
+        return maxNumberOfChannels;
+    }
+
+    private byte getThirdSadByteForCodecs2Through8(AudioDeviceInfo deviceInfo) {
+        /*
+         * Here, we are assuming that max bit rate is closely equals to the max sampling rate the
+         * device supports.
+         */
+        int maxSamplingRate = 0;
+        int[] samplingRatesDeviceSupports = deviceInfo.getSampleRates();
+        if (samplingRatesDeviceSupports.length == 0) {
+            maxSamplingRate = 192;
+        } else {
+            for (int sampleRate : samplingRatesDeviceSupports) {
+                if (maxSamplingRate < sampleRate) {
+                    maxSamplingRate = sampleRate;
+                }
+            }
+        }
+
+        return (byte) (maxSamplingRate / 8);
     }
 
     @Nullable
@@ -634,14 +767,14 @@
     }
 
     @AudioCodec
-    private int[] parseAudioFormatCodes(byte[] params) {
-        @AudioCodec int[] audioFormatCodes = new int[params.length];
+    private int[] parseAudioCodecs(byte[] params) {
+        @AudioCodec int[] audioCodecs = new int[params.length];
         for (int i = 0; i < params.length; i++) {
             byte val = params[i];
-            audioFormatCodes[i] =
-                val >= 1 && val <= Constants.AUDIO_CODEC_MAX ? val : Constants.AUDIO_CODEC_NONE;
+            audioCodecs[i] =
+                    val >= 1 && val <= Constants.AUDIO_CODEC_MAX ? val : Constants.AUDIO_CODEC_NONE;
         }
-        return audioFormatCodes;
+        return audioCodecs;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/input/BatteryController.java b/services/core/java/com/android/server/input/BatteryController.java
index c57d7e7..86732a1 100644
--- a/services/core/java/com/android/server/input/BatteryController.java
+++ b/services/core/java/com/android/server/input/BatteryController.java
@@ -18,12 +18,17 @@
 
 import android.annotation.BinderThread;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
+import android.hardware.BatteryState;
 import android.hardware.input.IInputDeviceBatteryListener;
 import android.hardware.input.InputManager;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.UEventObserver;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
@@ -31,6 +36,8 @@
 import android.view.InputDevice;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.input.BatteryController.UEventManager.UEventListener;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -41,7 +48,7 @@
  * A thread-safe component of {@link InputManagerService} responsible for managing the battery state
  * of input devices.
  */
-final class BatteryController {
+final class BatteryController implements InputManager.InputDeviceListener {
     private static final String TAG = BatteryController.class.getSimpleName();
 
     // To enable these logs, run:
@@ -51,15 +58,35 @@
     private final Object mLock = new Object();
     private final Context mContext;
     private final NativeInputManagerService mNative;
+    private final Handler mHandler;
+    private final UEventManager mUEventManager;
 
     // Maps a pid to the registered listener record for that process. There can only be one battery
     // listener per process.
     @GuardedBy("mLock")
     private final ArrayMap<Integer, ListenerRecord> mListenerRecords = new ArrayMap<>();
 
-    BatteryController(Context context, NativeInputManagerService nativeService) {
+    // Maps a deviceId that is being monitored to the battery state for the device.
+    // This must be kept in sync with {@link #mListenerRecords}.
+    @GuardedBy("mLock")
+    private final ArrayMap<Integer, MonitoredDeviceState> mMonitoredDeviceStates = new ArrayMap<>();
+
+    BatteryController(Context context, NativeInputManagerService nativeService, Looper looper) {
+        this(context, nativeService, looper, new UEventManager() {});
+    }
+
+    @VisibleForTesting
+    BatteryController(Context context, NativeInputManagerService nativeService, Looper looper,
+            UEventManager uEventManager) {
         mContext = context;
         mNative = nativeService;
+        mHandler = new Handler(looper);
+        mUEventManager = uEventManager;
+    }
+
+    void systemRunning() {
+        Objects.requireNonNull(mContext.getSystemService(InputManager.class))
+                .registerInputDeviceListener(this, mHandler);
     }
 
     /**
@@ -96,29 +123,45 @@
                                 + " is already monitoring deviceId " + deviceId);
             }
 
+            MonitoredDeviceState deviceState = mMonitoredDeviceStates.get(deviceId);
+            if (deviceState == null) {
+                // This is the first listener that is monitoring this device.
+                deviceState = new MonitoredDeviceState(deviceId);
+                mMonitoredDeviceStates.put(deviceId, deviceState);
+            }
+
             if (DEBUG) {
                 Slog.d(TAG, "Battery listener for pid " + pid
                         + " is monitoring deviceId " + deviceId);
             }
 
-            notifyBatteryListener(deviceId, listenerRecord);
+            notifyBatteryListener(listenerRecord, deviceState);
         }
     }
 
-    private void notifyBatteryListener(int deviceId, ListenerRecord record) {
-        final long eventTime = SystemClock.uptimeMillis();
+    private static void notifyBatteryListener(ListenerRecord listenerRecord,
+            MonitoredDeviceState deviceState) {
         try {
-            record.mListener.onBatteryStateChanged(
-                    deviceId,
-                    hasBattery(deviceId),
-                    mNative.getBatteryStatus(deviceId),
-                    mNative.getBatteryCapacity(deviceId) / 100.f,
-                    eventTime);
+            listenerRecord.mListener.onBatteryStateChanged(
+                    deviceState.mDeviceId,
+                    deviceState.mHasBattery,
+                    deviceState.mBatteryStatus,
+                    deviceState.mBatteryCapacity,
+                    deviceState.mLastUpdateTime);
         } catch (RemoteException e) {
             Slog.e(TAG, "Failed to notify listener", e);
         }
     }
 
+    @GuardedBy("mLock")
+    private void notifyAllListenersForDeviceLocked(MonitoredDeviceState deviceState) {
+        mListenerRecords.forEach((pid, listenerRecord) -> {
+            if (listenerRecord.mMonitoredDevices.contains(deviceState.mDeviceId)) {
+                notifyBatteryListener(listenerRecord, deviceState);
+            }
+        });
+    }
+
     private boolean hasBattery(int deviceId) {
         final InputDevice device =
                 Objects.requireNonNull(mContext.getSystemService(InputManager.class))
@@ -126,6 +169,12 @@
         return device != null && device.hasBattery();
     }
 
+    @GuardedBy("mLock")
+    private MonitoredDeviceState getDeviceStateOrThrowLocked(int deviceId) {
+        return Objects.requireNonNull(mMonitoredDeviceStates.get(deviceId),
+                "Maps are out of sync: Cannot find device state for deviceId " + deviceId);
+    }
+
     /**
      * Unregister the battery listener for the given input device and stop monitoring its battery
      * state. If there are no other input devices that this listener is monitoring, the listener is
@@ -170,6 +219,13 @@
                     + pid);
         }
 
+        if (!hasRegisteredListenerForDeviceLocked(deviceId)) {
+            // There are no more listeners monitoring this device.
+            final MonitoredDeviceState deviceState = getDeviceStateOrThrowLocked(deviceId);
+            deviceState.stopMonitoring();
+            mMonitoredDeviceStates.remove(deviceId);
+        }
+
         if (listenerRecord.mMonitoredDevices.isEmpty()) {
             // There are no more devices being monitored by this listener.
             listenerRecord.mListener.asBinder().unlinkToDeath(listenerRecord.mDeathRecipient, 0);
@@ -178,6 +234,16 @@
         }
     }
 
+    @GuardedBy("mLock")
+    private boolean hasRegisteredListenerForDeviceLocked(int deviceId) {
+        for (int i = 0; i < mListenerRecords.size(); i++) {
+            if (mListenerRecords.valueAt(i).mMonitoredDevices.contains(deviceId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void handleListeningProcessDied(int pid) {
         synchronized (mLock) {
             final ListenerRecord listenerRecord = mListenerRecords.get(pid);
@@ -194,6 +260,19 @@
         }
     }
 
+    // Query the battery state for the device and notify all listeners if there is a change.
+    private void handleBatteryChangeNotification(int deviceId, long eventTime) {
+        synchronized (mLock) {
+            final MonitoredDeviceState deviceState = mMonitoredDeviceStates.get(deviceId);
+            if (deviceState == null) {
+                return;
+            }
+            if (deviceState.updateBatteryState(eventTime)) {
+                notifyAllListenersForDeviceLocked(deviceState);
+            }
+        }
+    }
+
     void dump(PrintWriter pw, String prefix) {
         synchronized (mLock) {
             pw.println(prefix + TAG + ": " + mListenerRecords.size()
@@ -211,6 +290,29 @@
         }
     }
 
+    @VisibleForTesting
+    @Override
+    public void onInputDeviceAdded(int deviceId) {}
+
+    @VisibleForTesting
+    @Override
+    public void onInputDeviceRemoved(int deviceId) {}
+
+    @VisibleForTesting
+    @Override
+    public void onInputDeviceChanged(int deviceId) {
+        synchronized (mLock) {
+            final MonitoredDeviceState deviceState = mMonitoredDeviceStates.get(deviceId);
+            if (deviceState == null) {
+                return;
+            }
+            final long eventTime = SystemClock.uptimeMillis();
+            if (deviceState.updateBatteryState(eventTime)) {
+                notifyAllListenersForDeviceLocked(deviceState);
+            }
+        }
+    }
+
     // A record of a registered battery listener from one process.
     private class ListenerRecord {
         final int mPid;
@@ -232,4 +334,109 @@
                     + ", monitored devices=" + Arrays.toString(mMonitoredDevices.toArray());
         }
     }
+
+    // Holds the state of an InputDevice for which battery changes are currently being monitored.
+    private class MonitoredDeviceState {
+        private final int mDeviceId;
+
+        private long mLastUpdateTime = 0;
+        private boolean mHasBattery = false;
+        @BatteryState.BatteryStatus
+        private int mBatteryStatus = BatteryState.STATUS_UNKNOWN;
+        private float mBatteryCapacity = Float.NaN;
+
+        @Nullable
+        private UEventListener mUEventListener;
+
+        MonitoredDeviceState(int deviceId) {
+            mDeviceId = deviceId;
+
+            // Load the initial battery state and start monitoring.
+            final long eventTime = SystemClock.uptimeMillis();
+            updateBatteryState(eventTime);
+        }
+
+        // Returns true if the battery state changed since the last time it was updated.
+        boolean updateBatteryState(long eventTime) {
+            mLastUpdateTime = eventTime;
+
+            final boolean batteryPresenceChanged = mHasBattery != hasBattery(mDeviceId);
+            if (batteryPresenceChanged) {
+                mHasBattery = !mHasBattery;
+                if (mHasBattery) {
+                    startMonitoring();
+                } else {
+                    stopMonitoring();
+                }
+            }
+
+            final int oldStatus = mBatteryStatus;
+            final float oldCapacity = mBatteryCapacity;
+
+            if (mHasBattery) {
+                mBatteryStatus = mNative.getBatteryStatus(mDeviceId);
+                mBatteryCapacity = mNative.getBatteryCapacity(mDeviceId) / 100.f;
+            } else {
+                mBatteryStatus = BatteryState.STATUS_UNKNOWN;
+                mBatteryCapacity = Float.NaN;
+            }
+
+            return batteryPresenceChanged
+                    || mBatteryStatus != oldStatus
+                    || mBatteryCapacity != oldCapacity;
+        }
+
+        private void startMonitoring() {
+            final String batteryPath = mNative.getBatteryDevicePath(mDeviceId);
+            if (batteryPath == null) {
+                return;
+            }
+            mUEventListener = new UEventListener() {
+                @Override
+                void onUEvent(long eventTime) {
+                    handleBatteryChangeNotification(mDeviceId, eventTime);
+                }
+            };
+            mUEventManager.addListener(mUEventListener, "DEVPATH=" + batteryPath);
+        }
+
+        // This must be called when the device is no longer being monitored.
+        void stopMonitoring() {
+            if (mUEventListener != null) {
+                mUEventManager.removeListener(mUEventListener);
+                mUEventListener = null;
+            }
+        }
+    }
+
+    // An interface used to change the API of UEventObserver to a more test-friendly format.
+    @VisibleForTesting
+    interface UEventManager {
+
+        @VisibleForTesting
+        abstract class UEventListener {
+            private final UEventObserver mObserver = new UEventObserver() {
+                @Override
+                public void onUEvent(UEvent event) {
+                    final long eventTime = SystemClock.uptimeMillis();
+                    if (DEBUG) {
+                        Slog.d(TAG,
+                                "UEventListener: Received UEvent: "
+                                        + event + " eventTime: " + eventTime);
+                    }
+                    UEventListener.this.onUEvent(eventTime);
+                }
+            };
+
+            abstract void onUEvent(long eventTime);
+        }
+
+        default void addListener(UEventListener listener, String match) {
+            listener.mObserver.startObserving(match);
+        }
+
+        default void removeListener(UEventListener listener) {
+            listener.mObserver.stopObserving();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 3def714..4da0c0d 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -421,7 +421,7 @@
         mContext = injector.getContext();
         mHandler = new InputManagerHandler(injector.getLooper());
         mNative = injector.getNativeService(this);
-        mBatteryController = new BatteryController(mContext, mNative);
+        mBatteryController = new BatteryController(mContext, mNative, injector.getLooper());
 
         mUseDevInputEventForAudioJack =
                 mContext.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
@@ -561,6 +561,8 @@
         if (mWiredAccessoryCallbacks != null) {
             mWiredAccessoryCallbacks.systemReady();
         }
+
+        mBatteryController.systemRunning();
     }
 
     private void reloadKeyboardLayouts() {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 729de41..ed17b9ca 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2963,9 +2963,12 @@
                     try {
                         // Use PackageManager to load label
                         final PackageManager packageManager = mContext.getPackageManager();
-                        contentDescription = packageManager.getApplicationLabel(
-                                mIPackageManager.getApplicationInfo(packageName, 0,
-                                        mSettings.getCurrentUserId()));
+                        final ApplicationInfo applicationInfo = mIPackageManager
+                                .getApplicationInfo(packageName, 0, mSettings.getCurrentUserId());
+                        if (applicationInfo != null) {
+                            contentDescription = packageManager
+                                    .getApplicationLabel(applicationInfo);
+                        }
                     } catch (RemoteException e) {
                         /* ignore */
                     }
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java b/services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java
index 15b2093..058c1c8 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEventLogger.java
@@ -325,12 +325,8 @@
         }
     }
 
-    /**
-     * Creates a string representation of the logged events
-     *
-     * @return the dumped events
-     */
-    public synchronized String dump() {
+    @Override
+    public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("Nanoapp Loads:");
         sb.append(System.lineSeparator());
@@ -368,9 +364,4 @@
         }
         return sb.toString();
     }
-
-    @Override
-    public String toString() {
-        return dump();
-    }
 }
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 4ca0ea6..7ce1017 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -1054,7 +1054,7 @@
 
         pw.println("");
         pw.println("=================== EVENTS ====================");
-        pw.println(ContextHubEventLogger.getInstance().dump());
+        pw.println(ContextHubEventLogger.getInstance());
 
         // dump eventLog
     }
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 0fac808..4d55d4e 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -1786,8 +1786,8 @@
          * from receiving events from the profile.
          */
         public boolean isPermittedForProfile(int userId) {
-            if (!mUserProfiles.canProfileUseBoundServices(userId)) {
-                return false;
+            if (!mUserProfiles.isProfileUser(userId)) {
+                return true;
             }
             DevicePolicyManager dpm =
                     (DevicePolicyManager) mContext.getSystemService(DEVICE_POLICY_SERVICE);
@@ -1862,16 +1862,16 @@
             }
         }
 
-        public boolean canProfileUseBoundServices(int userId) {
+        public boolean isProfileUser(int userId) {
             synchronized (mCurrentProfiles) {
                 UserInfo user = mCurrentProfiles.get(userId);
                 if (user == null) {
                     return false;
                 }
                 if (user.isManagedProfile() || user.isCloneProfile()) {
-                    return false;
+                    return true;
                 }
-                return true;
+                return false;
             }
         }
     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0b4f736..4b18add 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1829,7 +1829,7 @@
             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 mUserProfiles.updateCache(context);
-                if (mUserProfiles.canProfileUseBoundServices(userId)) {
+                if (!mUserProfiles.isProfileUser(userId)) {
                     // reload per-user settings
                     mSettingsObserver.update(null);
                     // Refresh managed services
@@ -1843,7 +1843,7 @@
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 if (userId != USER_NULL) {
                     mUserProfiles.updateCache(context);
-                    if (mUserProfiles.canProfileUseBoundServices(userId)) {
+                    if (!mUserProfiles.isProfileUser(userId)) {
                         allowDefaultApprovedServices(userId);
                     }
                 }
@@ -1861,7 +1861,7 @@
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 mUserProfiles.updateCache(context);
                 mAssistants.onUserUnlocked(userId);
-                if (mUserProfiles.canProfileUseBoundServices(userId)) {
+                if (!mUserProfiles.isProfileUser(userId)) {
                     mConditionProviders.onUserUnlocked(userId);
                     mListeners.onUserUnlocked(userId);
                     mZenModeHelper.onUserUnlocked(userId);
@@ -1978,34 +1978,39 @@
             return (haystack & needle) != 0;
         }
 
-        public boolean isInLockDownMode() {
-            return mIsInLockDownMode;
+        // Return whether the user is in lockdown mode.
+        // If the flag is not set, we assume the user is not in lockdown.
+        public boolean isInLockDownMode(int userId) {
+            return mUserInLockDownMode.get(userId, false);
         }
 
         @Override
         public synchronized void onStrongAuthRequiredChanged(int userId) {
             boolean userInLockDownModeNext = containsFlag(getStrongAuthForUser(userId),
                     STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
-            mUserInLockDownMode.put(userId, userInLockDownModeNext);
-            boolean isInLockDownModeNext = mUserInLockDownMode.indexOfValue(true) != -1;
 
-            if (mIsInLockDownMode == isInLockDownModeNext) {
+            // Nothing happens if the lockdown mode of userId keeps the same.
+            if (userInLockDownModeNext == isInLockDownMode(userId)) {
                 return;
             }
 
-            if (isInLockDownModeNext) {
-                cancelNotificationsWhenEnterLockDownMode();
+            // When the lockdown mode is changed, we perform the following steps.
+            // If the userInLockDownModeNext is true, all the function calls to
+            // notifyPostedLocked and notifyRemovedLocked will not be executed.
+            // The cancelNotificationsWhenEnterLockDownMode calls notifyRemovedLocked
+            // and postNotificationsWhenExitLockDownMode calls notifyPostedLocked.
+            // So we shall call cancelNotificationsWhenEnterLockDownMode before
+            // we set mUserInLockDownMode as true.
+            // On the other hand, if the userInLockDownModeNext is false, we shall call
+            // postNotificationsWhenExitLockDownMode after we put false into mUserInLockDownMode
+            if (userInLockDownModeNext) {
+                cancelNotificationsWhenEnterLockDownMode(userId);
             }
 
-            // When the mIsInLockDownMode is true, both notifyPostedLocked and
-            // notifyRemovedLocked will be dismissed. So we shall call
-            // cancelNotificationsWhenEnterLockDownMode before we set mIsInLockDownMode
-            // as true and call postNotificationsWhenExitLockDownMode after we set
-            // mIsInLockDownMode as false.
-            mIsInLockDownMode = isInLockDownModeNext;
+            mUserInLockDownMode.put(userId, userInLockDownModeNext);
 
-            if (!isInLockDownModeNext) {
-                postNotificationsWhenExitLockDownMode();
+            if (!userInLockDownModeNext) {
+                postNotificationsWhenExitLockDownMode(userId);
             }
         }
     }
@@ -9712,11 +9717,14 @@
         }
     }
 
-    private void cancelNotificationsWhenEnterLockDownMode() {
+    private void cancelNotificationsWhenEnterLockDownMode(int userId) {
         synchronized (mNotificationLock) {
             int numNotifications = mNotificationList.size();
             for (int i = 0; i < numNotifications; i++) {
                 NotificationRecord rec = mNotificationList.get(i);
+                if (rec.getUser().getIdentifier() != userId) {
+                    continue;
+                }
                 mListeners.notifyRemovedLocked(rec, REASON_LOCKDOWN,
                         rec.getStats());
             }
@@ -9724,14 +9732,23 @@
         }
     }
 
-    private void postNotificationsWhenExitLockDownMode() {
+    private void postNotificationsWhenExitLockDownMode(int userId) {
         synchronized (mNotificationLock) {
             int numNotifications = mNotificationList.size();
+            // Set the delay to spread out the burst of notifications.
+            long delay = 0;
             for (int i = 0; i < numNotifications; i++) {
                 NotificationRecord rec = mNotificationList.get(i);
-                mListeners.notifyPostedLocked(rec, rec);
+                if (rec.getUser().getIdentifier() != userId) {
+                    continue;
+                }
+                mHandler.postDelayed(() -> {
+                    synchronized (mNotificationLock) {
+                        mListeners.notifyPostedLocked(rec, rec);
+                    }
+                }, delay);
+                delay += 20;
             }
-
         }
     }
 
@@ -9910,6 +9927,9 @@
 
         for (int i = 0; i < N; i++) {
             NotificationRecord record = mNotificationList.get(i);
+            if (isInLockDownMode(record.getUser().getIdentifier())) {
+                continue;
+            }
             if (!isVisibleToListener(record.getSbn(), record.getNotificationType(), info)) {
                 continue;
             }
@@ -9951,8 +9971,8 @@
                 rankings.toArray(new NotificationListenerService.Ranking[0]));
     }
 
-    boolean isInLockDownMode() {
-        return mStrongAuthTracker.isInLockDownMode();
+    boolean isInLockDownMode(int userId) {
+        return mStrongAuthTracker.isInLockDownMode(userId);
     }
 
     boolean hasCompanionDevice(ManagedServiceInfo info) {
@@ -11014,7 +11034,7 @@
         @GuardedBy("mNotificationLock")
         void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
                 boolean notifyAllListeners) {
-            if (isInLockDownMode()) {
+            if (isInLockDownMode(r.getUser().getIdentifier())) {
                 return;
             }
 
@@ -11120,7 +11140,7 @@
         @GuardedBy("mNotificationLock")
         public void notifyRemovedLocked(NotificationRecord r, int reason,
                 NotificationStats notificationStats) {
-            if (isInLockDownMode()) {
+            if (isInLockDownMode(r.getUser().getIdentifier())) {
                 return;
             }
 
@@ -11169,10 +11189,6 @@
          */
         @GuardedBy("mNotificationLock")
         public void notifyRankingUpdateLocked(List<NotificationRecord> changedHiddenNotifications) {
-            if (isInLockDownMode()) {
-                return;
-            }
-
             boolean isHiddenRankingUpdate = changedHiddenNotifications != null
                     && changedHiddenNotifications.size() > 0;
             // TODO (b/73052211): if the ranking update changed the notification type,
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index ba71438..baa471c 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -23,7 +23,9 @@
 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
 import static android.content.Intent.ACTION_USER_ADDED;
 import static android.content.Intent.ACTION_USER_REMOVED;
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
 import static android.content.Intent.EXTRA_REASON;
+import static android.content.Intent.EXTRA_USER_ID;
 import static android.content.om.OverlayManagerTransaction.Request.TYPE_REGISTER_FABRICATED;
 import static android.content.om.OverlayManagerTransaction.Request.TYPE_SET_DISABLED;
 import static android.content.om.OverlayManagerTransaction.Request.TYPE_SET_ENABLED;
@@ -39,6 +41,7 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
 import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -56,6 +59,7 @@
 import android.content.res.ApkAssets;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Environment;
 import android.os.FabricatedOverlayInternal;
 import android.os.HandlerThread;
@@ -1009,7 +1013,9 @@
                 }
                 opti++;
 
-                if ("-h".equals(opt)) {
+                if ("-a".equals(opt)) {
+                    // dumpsys will pass in -a; silently ignore it
+                } else if ("-h".equals(opt)) {
                     pw.println("dump [-h] [--verbose] [--user USER_ID] [[FIELD] PACKAGE]");
                     pw.println("  Print debugging information about the overlay manager.");
                     pw.println("  With optional parameter PACKAGE, limit output to the specified");
@@ -1098,6 +1104,7 @@
         private void enforceActor(@NonNull OverlayIdentifier overlay, @NonNull String methodName,
                 int realUserId) throws SecurityException {
             OverlayInfo overlayInfo = mImpl.getOverlayInfo(overlay, realUserId);
+
             if (overlayInfo == null) {
                 throw new IllegalArgumentException("Unable to retrieve overlay information for "
                         + overlay);
@@ -1416,20 +1423,41 @@
 
     private static void broadcastActionOverlayChanged(@NonNull final Set<String> targetPackages,
             final int userId) {
+        final ActivityManagerInternal amInternal =
+                LocalServices.getService(ActivityManagerInternal.class);
         CollectionUtils.forEach(targetPackages, target -> {
             final Intent intent = new Intent(ACTION_OVERLAY_CHANGED,
                     Uri.fromParts("package", target, null));
             intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            try {
-                ActivityManager.getService().broadcastIntent(null, intent, null, null, 0, null,
-                        null, null, android.app.AppOpsManager.OP_NONE, null, false, false, userId);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "broadcastActionOverlayChanged remote exception", e);
-            }
+            intent.putExtra(EXTRA_PACKAGE_NAME, target);
+            intent.putExtra(EXTRA_USER_ID, userId);
+            amInternal.broadcastIntent(intent, null /* resultTo */, null /* requiredPermissions */,
+                    false /* serialized */, userId, null /* appIdAllowList */,
+                    OverlayManagerService::filterReceiverAccess, null /* bOptions */);
         });
     }
 
     /**
+     * A callback from the broadcast queue to determine whether the intent
+     * {@link Intent#ACTION_OVERLAY_CHANGED} is visible to the receiver.
+     *
+     * @param callingUid The receiver's uid.
+     * @param extras The extras of intent that contains {@link Intent#EXTRA_PACKAGE_NAME} and
+     * {@link Intent#EXTRA_USER_ID} to check.
+     * @return {@code null} if the intent is not visible to the receiver.
+     */
+    @Nullable
+    private static Bundle filterReceiverAccess(int callingUid, @NonNull Bundle extras) {
+        final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
+        final int userId = extras.getInt(EXTRA_USER_ID);
+        if (LocalServices.getService(PackageManagerInternal.class).filterAppAccess(
+                packageName, callingUid, userId, false /* filterUninstalled */)) {
+            return null;
+        }
+        return extras;
+    }
+
+    /**
      * Tell the activity manager to tell a set of packages to reload their
      * resources.
      */
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index ae305ca..8e672c3 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -519,6 +519,7 @@
             throws OperationFailedException {
         final OverlayIdentifier overlayIdentifier = new OverlayIdentifier(
                 info.packageName, info.overlayName);
+
         final Set<PackageAndUser> updatedTargets = new ArraySet<>();
         OverlayInfo oi = mSettings.getNullableOverlayInfo(overlayIdentifier, userId);
         if (oi != null) {
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 9f6aa63..7242a56 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -271,7 +271,8 @@
         // other processes clean up before deleting resources.
         synchronized (mPm.mInstallLock) {
             if (info.mArgs != null) {
-                mRemovePackageHelper.cleanUpResources(info.mArgs);
+                mRemovePackageHelper.cleanUpResources(info.mArgs.mCodeFile,
+                        info.mArgs.mInstructionSets);
             }
 
             boolean reEnableStub = false;
diff --git a/services/core/java/com/android/server/pm/InstallArgs.java b/services/core/java/com/android/server/pm/InstallArgs.java
index 65c2378..a94a4e2 100644
--- a/services/core/java/com/android/server/pm/InstallArgs.java
+++ b/services/core/java/com/android/server/pm/InstallArgs.java
@@ -70,10 +70,9 @@
             UserHandle user, String[] instructionSets,
             String abiOverride, String[] installGrantPermissions,
             List<String> allowlistedRestrictedPermissions,
-            int autoRevokePermissionsMode,
-            String traceMethod, int traceCookie, SigningDetails signingDetails,
-            int installReason, int installScenario, boolean forceQueryableOverride,
-            int dataLoaderType, int packageSource) {
+            int autoRevokePermissionsMode, String traceMethod, int traceCookie,
+            SigningDetails signingDetails, int installReason, int installScenario,
+            boolean forceQueryableOverride, int dataLoaderType, int packageSource) {
         mOriginInfo = originInfo;
         mMoveInfo = moveInfo;
         mInstallFlags = installFlags;
@@ -96,18 +95,6 @@
         mPackageSource = packageSource;
     }
 
-    /** New install */
-    InstallArgs(InstallingSession params) {
-        this(params.mOriginInfo, params.mMoveInfo, params.mObserver, params.mInstallFlags,
-                params.mInstallSource, params.mVolumeUuid,
-                params.getUser(), null /*instructionSets*/, params.mPackageAbiOverride,
-                params.mGrantedRuntimePermissions, params.mAllowlistedRestrictedPermissions,
-                params.mAutoRevokePermissionsMode,
-                params.mTraceMethod, params.mTraceCookie, params.mSigningDetails,
-                params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride,
-                params.mDataLoaderType, params.mPackageSource);
-    }
-
     /**
      * Create args that describe an existing installed package. Typically used
      * when cleaning up old installs, or used as a move source.
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index d201710..a25ee5e 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -105,7 +105,6 @@
 import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.DataLoaderType;
-import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInfoLite;
 import android.content.pm.PackageInstaller;
@@ -147,6 +146,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.F2fsUtils;
@@ -275,9 +275,9 @@
                 // Prune unused SharedUserSetting
                 if (mPm.mSettings.checkAndPruneSharedUserLPw(requestSharedUserSetting, false)) {
                     // Set the app ID in removed info for UID_REMOVED broadcasts
-                    if (reconciledPkg.mInstallResult != null
-                            && reconciledPkg.mInstallResult.mRemovedInfo != null) {
-                        reconciledPkg.mInstallResult.mRemovedInfo.mRemovedAppId =
+                    if (reconciledPkg.mInstallRequest != null
+                            && reconciledPkg.mInstallRequest.getRemovedInfo() != null) {
+                        reconciledPkg.mInstallRequest.getRemovedInfo().mRemovedAppId =
                                 requestSharedUserSetting.mAppId;
                     }
                 }
@@ -307,24 +307,26 @@
                 mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting);
             }
         }
-        if (reconciledPkg.mInstallArgs != null
-                && reconciledPkg.mInstallArgs.mForceQueryableOverride) {
+        if (reconciledPkg.mInstallRequest != null
+                && reconciledPkg.mInstallRequest.isForceQueryableOverride()) {
             pkgSetting.setForceQueryableOverride(true);
         }
 
         // If this is part of a standard install, set the initiating package name, else rely on
         // previous device state.
-        if (reconciledPkg.mInstallArgs != null) {
-            InstallSource installSource = reconciledPkg.mInstallArgs.mInstallSource;
-            if (installSource.initiatingPackageName != null) {
-                final PackageSetting ips = mPm.mSettings.getPackageLPr(
-                        installSource.initiatingPackageName);
-                if (ips != null) {
-                    installSource = installSource.setInitiatingPackageSignatures(
-                            ips.getSignatures());
+        if (reconciledPkg.mInstallRequest != null) {
+            InstallSource installSource = reconciledPkg.mInstallRequest.getInstallSource();
+            if (installSource != null) {
+                if (installSource.initiatingPackageName != null) {
+                    final PackageSetting ips = mPm.mSettings.getPackageLPr(
+                            installSource.initiatingPackageName);
+                    if (ips != null) {
+                        installSource = installSource.setInitiatingPackageSignatures(
+                                ips.getSignatures());
+                    }
                 }
+                pkgSetting.setInstallSource(installSource);
             }
-            pkgSetting.setInstallSource(installSource);
         }
 
         if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
@@ -418,8 +420,8 @@
                         reconciledPkg.mAllowedSharedLibraryInfos,
                         reconciledPkg.getCombinedAvailablePackages(), scanFlags);
 
-        if (reconciledPkg.mInstallResult != null) {
-            reconciledPkg.mInstallResult.mLibraryConsumers = clientLibPkgs;
+        if (reconciledPkg.mInstallRequest != null) {
+            reconciledPkg.mInstallRequest.setLibraryConsumers(clientLibPkgs);
         }
 
         if ((scanFlags & SCAN_BOOTING) != 0) {
@@ -615,20 +617,18 @@
                     mPm.updateSequenceNumberLP(pkgSetting, new int[]{ userId });
                 }
                 // start async restore with no post-install since we finish install here
-                PackageInstalledInfo res = new PackageInstalledInfo(
-                        PackageManager.INSTALL_SUCCEEDED);
-                res.mPkg = pkgSetting.getPkg();
-                res.mNewUsers = new int[]{ userId };
 
-                PostInstallData postInstallData =
-                        new PostInstallData(null, res, () -> {
+                InstallRequest request = new InstallRequest(userId,
+                        PackageManager.INSTALL_SUCCEEDED, pkgSetting.getPkg(), new int[]{ userId },
+                        () -> {
                             mPm.restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
                                     userId);
                             if (intentSender != null) {
-                                onRestoreComplete(res.mReturnCode, mContext, intentSender);
+                                onRestoreComplete(PackageManager.INSTALL_SUCCEEDED, mContext,
+                                        intentSender);
                             }
                         });
-                restoreAndPostInstall(userId, res, postInstallData);
+                restoreAndPostInstall(request);
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -647,18 +647,17 @@
         }
     }
 
-    /** @param data Post-install is performed only if this is non-null. */
-    public void restoreAndPostInstall(
-            int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
+    public void restoreAndPostInstall(InstallRequest request) {
+        final int userId = request.getUserId();
         if (DEBUG_INSTALL) {
-            Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.mPkg);
+            Log.v(TAG,
+                    "restoreAndPostInstall userId=" + userId + " package=" + request.getPkg());
         }
 
         // A restore should be requested at this point if (a) the install
         // succeeded, (b) the operation is not an update.
-        final boolean update = res.mRemovedInfo != null
-                && res.mRemovedInfo.mRemovedPackage != null;
-        boolean doRestore = !update && res.mPkg != null;
+        final boolean update = request.isUpdate();
+        boolean doRestore = !update && request.getPkg() != null;
 
         // Set up the post-install work request bookkeeping.  This will be used
         // and cleaned up by the post-install event handling regardless of whether
@@ -666,23 +665,17 @@
         int token;
         if (mPm.mNextInstallToken < 0) mPm.mNextInstallToken = 1;
         token = mPm.mNextInstallToken++;
-        if (data != null) {
-            mPm.mRunningInstalls.put(token, data);
-        } else if (DEBUG_INSTALL) {
-            Log.v(TAG, "No post-install required for " + token);
-        }
+        mPm.mRunningInstalls.put(token, request);
 
         if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
 
-        if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
+        if (request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED && doRestore) {
             // Pass responsibility to the Backup Manager.  It will perform a
             // restore if appropriate, then pass responsibility back to the
             // Package Manager to run the post-install observer callbacks
             // and broadcasts.
-            if (res.mFreezer != null) {
-                res.mFreezer.close();
-            }
-            doRestore = performBackupManagerRestore(userId, token, res);
+            request.closeFreezer();
+            doRestore = performBackupManagerRestore(userId, token, request);
         }
 
         // If this is an update to a package that might be potentially downgraded, then we
@@ -690,8 +683,8 @@
         // need to be snapshotted or restored for the package.
         //
         // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
-        if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
-            doRestore = performRollbackManagerRestore(userId, token, res, data);
+        if (request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
+            doRestore = performRollbackManagerRestore(userId, token, request);
         }
 
         if (!doRestore) {
@@ -707,10 +700,10 @@
     }
 
     /**
-     * Perform Backup Manager restore for a given {@link PackageInstalledInfo}.
+     * Perform Backup Manager restore for a given {@link InstallRequest}.
      * Returns whether the restore successfully completed.
      */
-    private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
+    private boolean performBackupManagerRestore(int userId, int token, InstallRequest request) {
         IBackupManager iBackupManager = mInjector.getIBackupManager();
         if (iBackupManager != null) {
             // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
@@ -725,7 +718,7 @@
             try {
                 if (iBackupManager.isUserReadyForBackup(userId)) {
                     iBackupManager.restoreAtInstallForUser(
-                            userId, res.mPkg.getPackageName(), token);
+                            userId, request.getPkg().getPackageName(), token);
                 } else {
                     Slog.w(TAG, "User " + userId + " is not ready. Restore at install "
                             + "didn't take place.");
@@ -745,12 +738,11 @@
     }
 
     /**
-     * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}.
+     * Perform Rollback Manager restore for a given {@link InstallRequest}.
      * Returns whether the restore successfully completed.
      */
-    private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
-            PostInstallData data) {
-        final String packageName = res.mPkg.getPackageName();
+    private boolean performRollbackManagerRestore(int userId, int token, InstallRequest request) {
+        final String packageName = request.getPkg().getPackageName();
         final int[] allUsers = mPm.mUserManager.getUserIds();
         final int[] installedUsers;
 
@@ -762,19 +754,20 @@
             if (ps != null) {
                 appId = ps.getAppId();
                 ceDataInode = ps.getCeDataInode(userId);
+                // NOTE: We ignore the user specified in the InstallParam because we know this is
+                // an update, and hence need to restore data for all installed users.
+                installedUsers = ps.queryInstalledUsers(allUsers, true);
+            } else {
+                installedUsers = new int[0];
             }
-
-            // NOTE: We ignore the user specified in the InstallParam because we know this is
-            // an update, and hence need to restore data for all installed users.
-            installedUsers = ps.queryInstalledUsers(allUsers, true);
         }
 
-        boolean doSnapshotOrRestore = data != null && data.args != null
-                && ((data.args.mInstallFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
-                || (data.args.mInstallFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);
+        final int installFlags = request.getInstallFlags();
+        boolean doSnapshotOrRestore = ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
+                || (installFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);
 
         if (ps != null && doSnapshotOrRestore) {
-            final String seInfo = AndroidPackageUtils.getSeInfo(res.mPkg, ps);
+            final String seInfo = AndroidPackageUtils.getSeInfo(request.getPkg(), ps);
             final RollbackManagerInternal rollbackManager =
                     mInjector.getLocalService(RollbackManagerInternal.class);
             rollbackManager.snapshotAndRestoreUserData(packageName,
@@ -817,9 +810,8 @@
     @GuardedBy("mPm.mInstallLock")
     private void installPackagesLI(List<InstallRequest> requests) {
         final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
-        final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
-        final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
         final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
+        final Map<String, InstallRequest> installRequests = new ArrayMap<>(requests.size());
         final Map<String, Settings.VersionInfo> versionInfos = new ArrayMap<>(requests.size());
         final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
         boolean success = false;
@@ -832,32 +824,30 @@
                 try {
                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
                     prepareResult =
-                            preparePackageLI(request.mArgs, request.mInstallResult);
+                            preparePackageLI(request);
                 } catch (PrepareFailure prepareFailure) {
-                    request.mInstallResult.setError(prepareFailure.error,
+                    request.setError(prepareFailure.error,
                             prepareFailure.getMessage());
-                    request.mInstallResult.mOrigPackage = prepareFailure.mConflictingPackage;
-                    request.mInstallResult.mOrigPermission = prepareFailure.mConflictingPermission;
+                    request.setOriginPackage(prepareFailure.mConflictingPackage);
+                    request.setOriginPermission(prepareFailure.mConflictingPermission);
                     return;
                 } finally {
                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                 }
-                request.mInstallResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
-                request.mInstallResult.mInstallerPackageName =
-                        request.mArgs.mInstallSource.installerPackageName;
+                request.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
+                request.setInstallerPackageName(request.getSourceInstallerPackageName());
 
                 final String packageName = prepareResult.mPackageToScan.getPackageName();
                 prepareResults.put(packageName, prepareResult);
-                installResults.put(packageName, request.mInstallResult);
-                installArgs.put(packageName, request.mArgs);
+                installRequests.put(packageName, request);
                 try {
                     final ScanResult result = scanPackageTracedLI(
                             prepareResult.mPackageToScan, prepareResult.mParseFlags,
                             prepareResult.mScanFlags, System.currentTimeMillis(),
-                            request.mArgs.mUser, request.mArgs.mAbiOverride);
+                            request.getUser(), request.getAbiOverride());
                     if (null != preparedScans.put(result.mPkgSetting.getPkg().getPackageName(),
                             result)) {
-                        request.mInstallResult.setError(
+                        request.setError(
                                 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
                                 "Duplicate package "
                                         + result.mPkgSetting.getPkg().getPackageName()
@@ -868,7 +858,7 @@
                             result.mRequest.mOldPkg, result.mPkgSetting.getPkg())) {
                         // TODO: INSTALL_FAILED_UPDATE_INCOMPATIBLE is about incomptabible
                         //  signatures. Is there a better error code?
-                        request.mInstallResult.setError(
+                        request.setError(
                                 INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                                 "Update attempted to change value of "
                                         + PackageManager.PROPERTY_NO_APP_DATA_STORAGE);
@@ -883,15 +873,15 @@
                     versionInfos.put(result.mPkgSetting.getPkg().getPackageName(),
                             mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg()));
                 } catch (PackageManagerException e) {
-                    request.mInstallResult.setError("Scanning Failed.", e);
+                    request.setError("Scanning Failed.", e);
                     return;
                 }
             }
 
             CommitRequest commitRequest;
             synchronized (mPm.mLock) {
-                ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
-                        installResults, prepareResults,
+                ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans,
+                        installRequests, prepareResults,
                         Collections.unmodifiableMap(mPm.mPackages), versionInfos);
                 Map<String, ReconciledPackage> reconciledPackages;
                 try {
@@ -901,7 +891,7 @@
                             mPm.mSettings.getKeySetManagerService(), mPm.mSettings);
                 } catch (ReconcileFailure e) {
                     for (InstallRequest request : requests) {
-                        request.mInstallResult.setError("Reconciliation failed...", e);
+                        request.setError("Reconciliation failed...", e);
                     }
                     return;
                 } finally {
@@ -921,25 +911,24 @@
         } finally {
             if (success) {
                 for (InstallRequest request : requests) {
-                    final InstallArgs args = request.mArgs;
-                    if (args.mDataLoaderType != DataLoaderType.INCREMENTAL) {
+                    if (request.getDataLoaderType() != DataLoaderType.INCREMENTAL) {
                         continue;
                     }
-                    if (args.mSigningDetails.getSignatureSchemeVersion() != SIGNING_BLOCK_V4) {
+                    if (request.getSignatureSchemeVersion() != SIGNING_BLOCK_V4) {
                         continue;
                     }
                     // For incremental installs, we bypass the verifier prior to install. Now
                     // that we know the package is valid, send a notice to the verifier with
                     // the root hash of the base.apk.
-                    final String baseCodePath = request.mInstallResult.mPkg.getBaseApkPath();
-                    final String[] splitCodePaths = request.mInstallResult.mPkg.getSplitCodePaths();
-                    final Uri originUri = Uri.fromFile(args.mOriginInfo.mResolvedFile);
+                    final String baseCodePath = request.getPkg().getBaseApkPath();
+                    final String[] splitCodePaths = request.getPkg().getSplitCodePaths();
+                    final Uri originUri = request.getOriginUri();
                     final int verificationId = mPm.mPendingVerificationToken++;
                     final String rootHashString = PackageManagerServiceUtils
                             .buildVerificationRootHashString(baseCodePath, splitCodePaths);
                     VerificationUtils.broadcastPackageVerified(verificationId, originUri,
                             PackageManager.VERIFICATION_ALLOW, rootHashString,
-                            args.mDataLoaderType, args.mUser, mContext);
+                            request.getDataLoaderType(), request.getUser(), mContext);
                 }
             } else {
                 for (ScanResult result : preparedScans.values()) {
@@ -951,11 +940,9 @@
                 // TODO(b/194319951): create a more descriptive reason than unknown
                 // mark all non-failure installs as UNKNOWN so we do not treat them as success
                 for (InstallRequest request : requests) {
-                    if (request.mInstallResult.mFreezer != null) {
-                        request.mInstallResult.mFreezer.close();
-                    }
-                    if (request.mInstallResult.mReturnCode == PackageManager.INSTALL_SUCCEEDED) {
-                        request.mInstallResult.mReturnCode = PackageManager.INSTALL_UNKNOWN;
+                    request.closeFreezer();
+                    if (request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) {
+                        request.setReturnCode(PackageManager.INSTALL_UNKNOWN);
                     }
                 }
             }
@@ -980,18 +967,19 @@
     }
 
     @GuardedBy("mPm.mInstallLock")
-    private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
+    private PrepareResult preparePackageLI(InstallRequest request)
             throws PrepareFailure {
-        final int installFlags = args.mInstallFlags;
-        final boolean onExternal = args.mVolumeUuid != null;
+        final int installFlags = request.getInstallFlags();
+        final boolean onExternal = request.getVolumeUuid() != null;
         final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
         final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
         final boolean virtualPreload =
                 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
         final boolean isApex = ((installFlags & PackageManager.INSTALL_APEX) != 0);
-        final boolean isRollback = args.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
+        final boolean isRollback =
+                request.getInstallReason() == PackageManager.INSTALL_REASON_ROLLBACK;
         @PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
-        if (args.mMoveInfo != null) {
+        if (request.isMoveInstall()) {
             // moving a complete application; perform an initial scan on the new install location
             scanFlags |= SCAN_INITIAL;
         }
@@ -1012,7 +1000,7 @@
         }
 
         final File tmpPackageFile = new File(
-                isApex ? res.mApexInfo.modulePath : args.getCodePath());
+                isApex ? request.getApexInfo().modulePath : request.getCodePath());
         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
 
         // Validity check
@@ -1066,7 +1054,8 @@
             }
         }
 
-        String pkgName = res.mName = parsedPackage.getPackageName();
+        String pkgName = parsedPackage.getPackageName();
+        request.setName(pkgName);
         if (parsedPackage.isTestOnly()) {
             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
                 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
@@ -1074,8 +1063,8 @@
         }
 
         // either use what we've been given or parse directly from the APK
-        if (args.mSigningDetails != SigningDetails.UNKNOWN) {
-            parsedPackage.setSigningDetails(args.mSigningDetails);
+        if (request.getSigningDetails() != SigningDetails.UNKNOWN) {
+            parsedPackage.setSigningDetails(request.getSigningDetails());
         } else {
             final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
             final ParseResult<SigningDetails> result = ParsingPackageUtils.getSigningDetails(
@@ -1223,7 +1212,8 @@
                 if (ps.getPkg() != null) {
                     systemApp = ps.getPkg().isSystem();
                 }
-                res.mOrigUsers = ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true);
+                request.setOriginUsers(
+                        ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true));
             }
 
             final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups());
@@ -1299,7 +1289,7 @@
                         // it as dangerous leading to the group auto-grant.
                         if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE)
                                 == PermissionInfo.PROTECTION_DANGEROUS) {
-                            if (bp != null && !bp.isRuntime()) {
+                            if (!bp.isRuntime()) {
                                 Slog.w(TAG, "Package " + parsedPackage.getPackageName()
                                         + " trying to change a non-runtime permission "
                                         + perm.getName()
@@ -1372,7 +1362,7 @@
             }
         }
 
-        if (args.mMoveInfo != null) {
+        if (request.isMoveInstall()) {
             // We did an in-place move, so dex is ready to roll
             scanFlags |= SCAN_NO_DEX;
             scanFlags |= SCAN_MOVE;
@@ -1380,7 +1370,7 @@
             synchronized (mPm.mLock) {
                 final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
                 if (ps == null) {
-                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
+                    request.setError(INSTALL_FAILED_INTERNAL_ERROR,
                             "Missing settings for moved package " + pkgName);
                 }
 
@@ -1403,7 +1393,7 @@
                 }
                 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
                         && pkgSetting.getPkgState().isUpdatedSystemApp();
-                final String abiOverride = deriveAbiOverride(args.mAbiOverride);
+                final String abiOverride = deriveAbiOverride(request.getAbiOverride());
                 boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem();
                 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
                         derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage,
@@ -1419,7 +1409,7 @@
         }
 
         if (!isApex) {
-            doRenameLI(args, res.mReturnCode, res.mReturnMsg, parsedPackage);
+            doRenameLI(request, parsedPackage);
 
             try {
                 setUpFsVerityIfPossible(parsedPackage);
@@ -1430,8 +1420,8 @@
             }
         } else {
             // Use the path returned by apexd
-            parsedPackage.setPath(res.mApexInfo.modulePath);
-            parsedPackage.setBaseApkPath(res.mApexInfo.modulePath);
+            parsedPackage.setPath(request.getApexInfo().modulePath);
+            parsedPackage.setBaseApkPath(request.getApexInfo().modulePath);
         }
 
         final PackageFreezer freezer =
@@ -1559,8 +1549,8 @@
 
                     // don't allow an upgrade from full to ephemeral
                     if (isInstantApp) {
-                        if (args.mUser == null
-                                || args.mUser.getIdentifier() == UserHandle.USER_ALL) {
+                        if (request.getUser() == null
+                                || request.getUserId() == UserHandle.USER_ALL) {
                             for (int currentUser : allUsers) {
                                 if (!ps.getInstantApp(currentUser)) {
                                     // can't downgrade from full to instant
@@ -1571,10 +1561,10 @@
                                             PackageManager.INSTALL_FAILED_SESSION_INVALID);
                                 }
                             }
-                        } else if (!ps.getInstantApp(args.mUser.getIdentifier())) {
+                        } else if (!ps.getInstantApp(request.getUserId())) {
                             // can't downgrade from full to instant
                             Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
-                                    + " for user: " + args.mUser.getIdentifier());
+                                    + " for user: " + request.getUserId());
                             throw new PrepareFailure(
                                     PackageManager.INSTALL_FAILED_SESSION_INVALID);
                         }
@@ -1582,25 +1572,29 @@
                 }
 
                 // Update what is removed
-                res.mRemovedInfo = new PackageRemovedInfo(mPm);
-                res.mRemovedInfo.mUid = oldPackage.getUid();
-                res.mRemovedInfo.mRemovedPackage = oldPackage.getPackageName();
-                res.mRemovedInfo.mInstallerPackageName = ps.getInstallSource().installerPackageName;
-                res.mRemovedInfo.mIsStaticSharedLib =
+                PackageRemovedInfo removedInfo = new PackageRemovedInfo(mPm);
+                removedInfo.mUid = oldPackage.getUid();
+                removedInfo.mRemovedPackage = oldPackage.getPackageName();
+                removedInfo.mInstallerPackageName =
+                        ps.getInstallSource().installerPackageName;
+                removedInfo.mIsStaticSharedLib =
                         parsedPackage.getStaticSharedLibName() != null;
-                res.mRemovedInfo.mIsUpdate = true;
-                res.mRemovedInfo.mOrigUsers = installedUsers;
-                res.mRemovedInfo.mInstallReasons = new SparseArray<>(installedUsers.length);
+                removedInfo.mIsUpdate = true;
+                removedInfo.mOrigUsers = installedUsers;
+                removedInfo.mInstallReasons = new SparseIntArray(installedUsers.length);
                 for (int i = 0; i < installedUsers.length; i++) {
                     final int userId = installedUsers[i];
-                    res.mRemovedInfo.mInstallReasons.put(userId, ps.getInstallReason(userId));
+                    removedInfo.mInstallReasons.put(userId,
+                            ps.getInstallReason(userId));
                 }
-                res.mRemovedInfo.mUninstallReasons = new SparseArray<>(uninstalledUsers.length);
+                removedInfo.mUninstallReasons = new SparseIntArray(uninstalledUsers.length);
                 for (int i = 0; i < uninstalledUsers.length; i++) {
                     final int userId = uninstalledUsers[i];
-                    res.mRemovedInfo.mUninstallReasons.put(userId, ps.getUninstallReason(userId));
+                    removedInfo.mUninstallReasons.put(userId,
+                            ps.getUninstallReason(userId));
                 }
-                res.mRemovedInfo.mIsExternal = oldPackage.isExternalStorage();
+                removedInfo.mIsExternal = oldPackage.isExternalStorage();
+                request.setRemovedInfo(removedInfo);
 
                 sysPkg = oldPackage.isSystem();
                 if (sysPkg) {
@@ -1625,7 +1619,7 @@
                         Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
                                 + ", old=" + oldPackage);
                     }
-                    res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
+                    request.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
                     targetParseFlags = systemParseFlags;
                     targetScanFlags = systemScanFlags;
                 } else { // non system replace
@@ -1674,7 +1668,7 @@
                     oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
                     ps, disabledPs);
         } finally {
-            res.mFreezer = freezer;
+            request.setFreezer(freezer);
             if (shouldCloseFreezerBeforeReturn) {
                 freezer.close();
             }
@@ -1686,24 +1680,26 @@
      * scanned package should be updated to reflect the rename.
      */
     @GuardedBy("mPm.mInstallLock")
-    private void doRenameLI(InstallArgs args, int status, String statusMsg,
+    private void doRenameLI(InstallRequest request,
             ParsedPackage parsedPackage) throws PrepareFailure {
-        if (args.mMoveInfo != null) {
+        final int status = request.getReturnCode();
+        final String statusMsg = request.getReturnMsg();
+        if (request.isMoveInstall()) {
             if (status != PackageManager.INSTALL_SUCCEEDED) {
-                mRemovePackageHelper.cleanUpForMoveInstall(args.mMoveInfo.mToUuid,
-                        args.mMoveInfo.mPackageName, args.mMoveInfo.mFromCodePath);
+                mRemovePackageHelper.cleanUpForMoveInstall(request.getMoveToUuid(),
+                        request.getMovePackageName(), request.getMoveFromCodePath());
                 throw new PrepareFailure(status, statusMsg);
             }
             return;
         }
         // For file installations
         if (status != PackageManager.INSTALL_SUCCEEDED) {
-            mRemovePackageHelper.removeCodePath(args.mCodeFile);
+            mRemovePackageHelper.removeCodePath(request.getCodeFile());
             throw new PrepareFailure(status, statusMsg);
         }
 
-        final File targetDir = resolveTargetDir(args);
-        final File beforeCodeFile = args.mCodeFile;
+        final File targetDir = resolveTargetDir(request.getInstallFlags(), request.getCodeFile());
+        final File beforeCodeFile = request.getCodeFile();
         final File afterCodeFile = PackageManagerServiceUtils.getNextCodePath(targetDir,
                 parsedPackage.getPackageName());
 
@@ -1732,7 +1728,7 @@
         }
 
         // Reflect the rename internally
-        args.mCodeFile = afterCodeFile;
+        request.setCodeFile(afterCodeFile);
 
         // Reflect the rename in scanned details
         try {
@@ -1750,12 +1746,12 @@
 
     // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged
     //  flow, we won't need this method anymore.
-    private File resolveTargetDir(InstallArgs args) {
-        boolean isStagedInstall = (args.mInstallFlags & INSTALL_STAGED) != 0;
+    private File resolveTargetDir(int installFlags, File codeFile) {
+        boolean isStagedInstall = (installFlags & INSTALL_STAGED) != 0;
         if (isStagedInstall) {
             return Environment.getDataAppDirectory(null);
         } else {
-            return args.mCodeFile.getParentFile();
+            return codeFile.getParentFile();
         }
     }
 
@@ -1905,7 +1901,7 @@
             final ScanRequest scanRequest = scanResult.mRequest;
             final ParsedPackage parsedPackage = scanRequest.mParsedPackage;
             final String packageName = parsedPackage.getPackageName();
-            final PackageInstalledInfo res = reconciledPkg.mInstallResult;
+            final InstallRequest installRequest = reconciledPkg.mInstallRequest;
             final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
             final DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm);
 
@@ -1921,9 +1917,10 @@
                         .setFirstInstallTimeFromReplaced(deletedPkgSetting, request.mAllUsers)
                         .setLastUpdateTime(System.currentTimeMillis());
 
-                res.mRemovedInfo.mBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(
-                        mPm.snapshotComputer(), reconciledPkg.mPkgSetting, request.mAllUsers,
-                        mPm.mSettings.getPackagesLocked());
+                installRequest.getRemovedInfo().mBroadcastAllowList =
+                        mPm.mAppsFilter.getVisibilityAllowList(mPm.snapshotComputer(),
+                                reconciledPkg.mPkgSetting, request.mAllUsers,
+                                mPm.mSettings.getPackagesLocked());
                 if (reconciledPkg.mPrepareResult.mSystem) {
                     // Remove existing system package
                     removePackageHelper.removePackage(oldPackage, true);
@@ -1931,7 +1928,7 @@
                         // We didn't need to disable the .apk as a current system package,
                         // which means we are replacing another update that is already
                         // installed.  We need to make sure to delete the older one's .apk.
-                        res.mRemovedInfo.mArgs = new InstallArgs(
+                        installRequest.getRemovedInfo().mArgs = new InstallArgs(
                                 oldPackage.getPath(),
                                 getAppDexInstructionSets(
                                         AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
@@ -1939,7 +1936,7 @@
                                         AndroidPackageUtils.getSecondaryCpuAbi(oldPackage,
                                                 deletedPkgSetting)));
                     } else {
-                        res.mRemovedInfo.mArgs = null;
+                        installRequest.getRemovedInfo().mArgs = null;
                     }
                 } else {
                     try {
@@ -1957,7 +1954,7 @@
                     // Update the in-memory copy of the previous code paths.
                     PackageSetting ps1 = mPm.mSettings.getPackageLPr(
                             reconciledPkg.mPrepareResult.mExistingPackage.getPackageName());
-                    if ((reconciledPkg.mInstallArgs.mInstallFlags & PackageManager.DONT_KILL_APP)
+                    if ((installRequest.getInstallFlags() & PackageManager.DONT_KILL_APP)
                             == 0) {
                         Set<String> oldCodePaths = ps1.getOldCodePaths();
                         if (oldCodePaths == null) {
@@ -1970,12 +1967,11 @@
                         ps1.setOldCodePaths(null);
                     }
 
-                    if (reconciledPkg.mInstallResult.mReturnCode
-                            == PackageManager.INSTALL_SUCCEEDED) {
+                    if (installRequest.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) {
                         PackageSetting ps2 = mPm.mSettings.getPackageLPr(
                                 parsedPackage.getPackageName());
                         if (ps2 != null) {
-                            res.mRemovedInfo.mRemovedForAllUsers =
+                            installRequest.getRemovedInfo().mRemovedForAllUsers =
                                     mPm.mPackages.get(ps2.getPackageName()) == null;
                         }
                     }
@@ -1984,15 +1980,16 @@
 
             AndroidPackage pkg = commitReconciledScanResultLocked(
                     reconciledPkg, request.mAllUsers);
-            updateSettingsLI(pkg, reconciledPkg, request.mAllUsers, res);
+            updateSettingsLI(pkg, reconciledPkg, request.mAllUsers, installRequest);
 
             final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
             if (ps != null) {
-                res.mNewUsers = ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true);
+                installRequest.setNewUsers(
+                        ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true));
                 ps.setUpdateAvailable(false /*updateAvailable*/);
             }
-            if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED) {
-                mPm.updateSequenceNumberLP(ps, res.mNewUsers);
+            if (installRequest.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) {
+                mPm.updateSequenceNumberLP(ps, installRequest.getNewUsers());
                 mPm.updateInstantAppInstallerLocked(packageName);
             }
         }
@@ -2005,20 +2002,18 @@
     }
 
     private void updateSettingsLI(AndroidPackage newPackage, ReconciledPackage reconciledPkg,
-            int[] allUsers, PackageInstalledInfo res) {
-        updateSettingsInternalLI(newPackage, reconciledPkg, allUsers, res);
+            int[] allUsers, InstallRequest installRequest) {
+        updateSettingsInternalLI(newPackage, reconciledPkg, allUsers, installRequest);
     }
 
     private void updateSettingsInternalLI(AndroidPackage pkg, ReconciledPackage reconciledPkg,
-            int[] allUsers, PackageInstalledInfo res) {
+            int[] allUsers, InstallRequest installRequest) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
 
         final String pkgName = pkg.getPackageName();
-        final int[] installedForUsers = res.mOrigUsers;
-        final InstallArgs installArgs = reconciledPkg.mInstallArgs;
-        final int installReason = installArgs.mInstallReason;
-        InstallSource installSource = installArgs.mInstallSource;
-        final String installerPackageName = installSource.installerPackageName;
+        final int[] installedForUsers = installRequest.getOriginUsers();
+        final int installReason = installRequest.getInstallReason();
+        final String installerPackageName = installRequest.getSourceInstallerPackageName();
 
         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getPath());
         synchronized (mPm.mLock) {
@@ -2026,15 +2021,15 @@
             // of the package implies that the user actually wants to run that new code,
             // so we enable the package.
             final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
-            final int userId = installArgs.mUser.getIdentifier();
+            final int userId = installRequest.getUserId();
             if (ps != null) {
                 if (pkg.isSystem()) {
                     if (DEBUG_INSTALL) {
                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
                     }
                     // Enable system package for requested users
-                    if (res.mOrigUsers != null) {
-                        for (int origUserId : res.mOrigUsers) {
+                    if (installedForUsers != null) {
+                        for (int origUserId : installedForUsers) {
                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
                                         origUserId, installerPackageName);
@@ -2101,20 +2096,27 @@
                 // When replacing an existing package, preserve the original install reason for all
                 // users that had the package installed before. Similarly for uninstall reasons.
                 final Set<Integer> previousUserIds = new ArraySet<>();
-                if (res.mRemovedInfo != null && res.mRemovedInfo.mInstallReasons != null) {
-                    final int installReasonCount = res.mRemovedInfo.mInstallReasons.size();
+                if (installRequest.getRemovedInfo() != null
+                        && installRequest.getRemovedInfo().mInstallReasons != null) {
+                    final int installReasonCount =
+                            installRequest.getRemovedInfo().mInstallReasons.size();
                     for (int i = 0; i < installReasonCount; i++) {
-                        final int previousUserId = res.mRemovedInfo.mInstallReasons.keyAt(i);
+                        final int previousUserId =
+                                installRequest.getRemovedInfo().mInstallReasons.keyAt(i);
                         final int previousInstallReason =
-                                res.mRemovedInfo.mInstallReasons.valueAt(i);
+                                installRequest.getRemovedInfo().mInstallReasons.valueAt(i);
                         ps.setInstallReason(previousInstallReason, previousUserId);
                         previousUserIds.add(previousUserId);
                     }
                 }
-                if (res.mRemovedInfo != null && res.mRemovedInfo.mUninstallReasons != null) {
-                    for (int i = 0; i < res.mRemovedInfo.mUninstallReasons.size(); i++) {
-                        final int previousUserId = res.mRemovedInfo.mUninstallReasons.keyAt(i);
-                        final int previousReason = res.mRemovedInfo.mUninstallReasons.valueAt(i);
+                if (installRequest.getRemovedInfo() != null
+                        && installRequest.getRemovedInfo().mUninstallReasons != null) {
+                    for (int i = 0; i < installRequest.getRemovedInfo().mUninstallReasons.size();
+                            i++) {
+                        final int previousUserId =
+                                installRequest.getRemovedInfo().mUninstallReasons.keyAt(i);
+                        final int previousReason =
+                                installRequest.getRemovedInfo().mUninstallReasons.valueAt(i);
                         ps.setUninstallReason(previousReason, previousUserId);
                     }
                 }
@@ -2153,41 +2155,41 @@
                 final PermissionManagerServiceInternal.PackageInstalledParams.Builder
                         permissionParamsBuilder =
                         new PermissionManagerServiceInternal.PackageInstalledParams.Builder();
-                final boolean grantPermissions = (installArgs.mInstallFlags
+                final boolean grantPermissions = (installRequest.getInstallFlags()
                         & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
                 if (grantPermissions) {
                     final List<String> grantedPermissions =
-                            installArgs.mInstallGrantPermissions != null
-                                    ? Arrays.asList(installArgs.mInstallGrantPermissions)
+                            installRequest.getInstallGrantPermissions() != null
+                                    ? Arrays.asList(installRequest.getInstallGrantPermissions())
                                     : pkg.getRequestedPermissions();
                     permissionParamsBuilder.setGrantedPermissions(grantedPermissions);
                 }
                 final boolean allowlistAllRestrictedPermissions =
-                        (installArgs.mInstallFlags
+                        (installRequest.getInstallFlags()
                                 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0;
                 final List<String> allowlistedRestrictedPermissions =
                         allowlistAllRestrictedPermissions ? pkg.getRequestedPermissions()
-                                : installArgs.mAllowlistedRestrictedPermissions;
+                                : installRequest.getAllowlistedRestrictedPermissions();
                 if (allowlistedRestrictedPermissions != null) {
                     permissionParamsBuilder.setAllowlistedRestrictedPermissions(
                             allowlistedRestrictedPermissions);
                 }
-                final int autoRevokePermissionsMode = installArgs.mAutoRevokePermissionsMode;
+                final int autoRevokePermissionsMode = installRequest.getAutoRevokePermissionsMode();
                 permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode);
                 final ScanResult scanResult = reconciledPkg.mScanResult;
                 mPm.mPermissionManager.onPackageInstalled(pkg, scanResult.mPreviousAppId,
                         permissionParamsBuilder.build(), userId);
                 // Apply restricted settings on potentially dangerous packages.
-                if (installArgs.mPackageSource == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE
-                        || installArgs.mPackageSource
+                if (installRequest.getPackageSource() == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE
+                        || installRequest.getPackageSource()
                         == PackageInstaller.PACKAGE_SOURCE_DOWNLOADED_FILE) {
                     enableRestrictedSettings(pkgName, pkg.getUid());
                 }
             }
-            res.mName = pkgName;
-            res.mUid = pkg.getUid();
-            res.mPkg = pkg;
-            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
+            installRequest.setName(pkgName);
+            installRequest.setUid(pkg.getUid());
+            installRequest.setPkg(pkg);
+            installRequest.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
             //to update install status
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
             mPm.writeSettingsLPrTEMP();
@@ -2252,13 +2254,13 @@
             // can be used for optimizations.
             mArtManagerService.prepareAppProfiles(
                     pkg,
-                    mPm.resolveUserIds(reconciledPkg.mInstallArgs.mUser.getIdentifier()),
+                    mPm.resolveUserIds(reconciledPkg.mInstallRequest.getUserId()),
                     /* updateReferenceProfileContent= */ true);
 
             // Compute the compilation reason from the installation scenario.
             final int compilationReason =
                     mDexManager.getCompilationReasonForInstallScenario(
-                            reconciledPkg.mInstallArgs.mInstallScenario);
+                            reconciledPkg.mInstallRequest.getInstallScenario());
 
             // Construct the DexoptOptions early to see if we should skip running dexopt.
             //
@@ -2267,8 +2269,9 @@
             //
             // Also, don't fail application installs if the dexopt step fails.
             final boolean isBackupOrRestore =
-                    reconciledPkg.mInstallArgs.mInstallReason == INSTALL_REASON_DEVICE_RESTORE
-                            || reconciledPkg.mInstallArgs.mInstallReason
+                    reconciledPkg.mInstallRequest.getInstallReason()
+                            == INSTALL_REASON_DEVICE_RESTORE
+                            || reconciledPkg.mInstallRequest.getInstallReason()
                             == INSTALL_REASON_DEVICE_SETUP;
 
             final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
@@ -2580,35 +2583,31 @@
         }
     }
 
-    void handlePackagePostInstall(PackageInstalledInfo res, InstallArgs installArgs,
-            boolean launchedForRestore) {
+    void handlePackagePostInstall(InstallRequest request, boolean launchedForRestore) {
         final boolean killApp =
-                (installArgs.mInstallFlags & PackageManager.INSTALL_DONT_KILL_APP) == 0;
+                (request.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) == 0;
         final boolean virtualPreload =
-                ((installArgs.mInstallFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
-        final String installerPackage = installArgs.mInstallSource.installerPackageName;
-        final IPackageInstallObserver2 installObserver = installArgs.mObserver;
-        final int dataLoaderType = installArgs.mDataLoaderType;
-        final boolean succeeded = res.mReturnCode == PackageManager.INSTALL_SUCCEEDED;
-        final boolean update = res.mRemovedInfo != null && res.mRemovedInfo.mRemovedPackage != null;
-        final String packageName = res.mName;
+                ((request.getInstallFlags() & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
+        final String installerPackage = request.getInstallerPackageName();
+        final int dataLoaderType = request.getDataLoaderType();
+        final boolean succeeded = request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED;
+        final boolean update = request.isUpdate();
+        final String packageName = request.getName();
         final PackageStateInternal pkgSetting =
                 succeeded ? mPm.snapshotComputer().getPackageStateInternal(packageName) : null;
         final boolean removedBeforeUpdate = (pkgSetting == null)
                 || (pkgSetting.isSystem() && !pkgSetting.getPath().getPath().equals(
-                res.mPkg.getPath()));
+                request.getPkg().getPath()));
         if (succeeded && removedBeforeUpdate) {
             Slog.e(TAG, packageName + " was removed before handlePackagePostInstall "
                     + "could be executed");
-            res.mReturnCode = INSTALL_FAILED_PACKAGE_CHANGED;
-            res.mReturnMsg = "Package was removed before install could complete.";
+            request.setReturnCode(INSTALL_FAILED_PACKAGE_CHANGED);
+            request.setReturnMessage("Package was removed before install could complete.");
 
             // Remove the update failed package's older resources safely now
-            InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null;
-            if (args != null) {
-                mRemovePackageHelper.cleanUpResources(args);
-            }
-            mPm.notifyInstallObserver(res, installObserver);
+            mRemovePackageHelper.cleanUpResources(request.getOldCodeFile(),
+                    request.getOldInstructionSet());
+            mPm.notifyInstallObserver(request);
             return;
         }
 
@@ -2617,28 +2616,31 @@
             mPm.mPerUidReadTimeoutsCache = null;
 
             // Send the removed broadcasts
-            if (res.mRemovedInfo != null) {
-                if (res.mRemovedInfo.mIsExternal) {
+            if (request.getRemovedInfo() != null) {
+                if (request.getRemovedInfo().mIsExternal) {
                     if (DEBUG_INSTALL) {
-                        Slog.i(TAG, "upgrading pkg " + res.mRemovedInfo.mRemovedPackage
+                        Slog.i(TAG, "upgrading pkg " + request.getRemovedInfo().mRemovedPackage
                                 + " is ASEC-hosted -> UNAVAILABLE");
                     }
-                    final String[] pkgNames = new String[]{res.mRemovedInfo.mRemovedPackage};
-                    final int[] uids = new int[]{res.mRemovedInfo.mUid};
+                    final String[] pkgNames = new String[]{
+                            request.getRemovedInfo().mRemovedPackage};
+                    final int[] uids = new int[]{request.getRemovedInfo().mUid};
                     mBroadcastHelper.sendResourcesChangedBroadcast(mPm::snapshotComputer,
                             false /* mediaStatus */, true /* replacing */, pkgNames, uids);
                 }
-                res.mRemovedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/);
+                request.getRemovedInfo().sendPackageRemovedBroadcasts(
+                        killApp, false /*removedBySystem*/);
             }
 
             final String installerPackageName =
-                    res.mInstallerPackageName != null
-                            ? res.mInstallerPackageName
-                            : res.mRemovedInfo != null
-                                    ? res.mRemovedInfo.mInstallerPackageName
+                    request.getInstallerPackageName() != null
+                            ? request.getInstallerPackageName()
+                            : request.getRemovedInfo() != null
+                                    ? request.getRemovedInfo().mInstallerPackageName
                                     : null;
 
-            mPm.notifyInstantAppPackageInstalled(res.mPkg.getPackageName(), res.mNewUsers);
+            mPm.notifyInstantAppPackageInstalled(request.getPkg().getPackageName(),
+                    request.getNewUsers());
 
             // Determine the set of users who are adding this package for
             // the first time vs. those who are seeing an update.
@@ -2646,8 +2648,9 @@
             int[] firstInstantUserIds = EMPTY_INT_ARRAY;
             int[] updateUserIds = EMPTY_INT_ARRAY;
             int[] instantUserIds = EMPTY_INT_ARRAY;
-            final boolean allNewUsers = res.mOrigUsers == null || res.mOrigUsers.length == 0;
-            for (int newUser : res.mNewUsers) {
+            final boolean allNewUsers = request.getOriginUsers() == null
+                    || request.getOriginUsers().length == 0;
+            for (int newUser : request.getNewUsers()) {
                 final boolean isInstantApp = pkgSetting.getUserStateOrDefault(newUser)
                         .isInstantApp();
                 if (allNewUsers) {
@@ -2659,7 +2662,7 @@
                     continue;
                 }
                 boolean isNew = true;
-                for (int origUser : res.mOrigUsers) {
+                for (int origUser : request.getOriginUsers()) {
                     if (origUser == newUser) {
                         isNew = false;
                         break;
@@ -2681,20 +2684,20 @@
             }
 
             // Send installed broadcasts if the package is not a static shared lib.
-            if (res.mPkg.getStaticSharedLibName() == null) {
-                mPm.mProcessLoggingHandler.invalidateBaseApkHash(res.mPkg.getBaseApkPath());
+            if (request.getPkg().getStaticSharedLibName() == null) {
+                mPm.mProcessLoggingHandler.invalidateBaseApkHash(request.getPkg().getBaseApkPath());
 
                 // Send added for users that see the package for the first time
                 // sendPackageAddedForNewUsers also deals with system apps
-                int appId = UserHandle.getAppId(res.mUid);
-                boolean isSystem = res.mPkg.isSystem();
+                int appId = UserHandle.getAppId(request.getUid());
+                boolean isSystem = request.getPkg().isSystem();
                 mPm.sendPackageAddedForNewUsers(mPm.snapshotComputer(), packageName,
                         isSystem || virtualPreload, virtualPreload /*startReceiver*/, appId,
                         firstUserIds, firstInstantUserIds, dataLoaderType);
 
                 // Send added for users that don't see the package for the first time
                 Bundle extras = new Bundle();
-                extras.putInt(Intent.EXTRA_UID, res.mUid);
+                extras.putInt(Intent.EXTRA_UID, request.getUid());
                 if (update) {
                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
                 }
@@ -2743,8 +2746,8 @@
                     mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                             packageName, extras, 0 /*flags*/,
                             null /*targetPackage*/, null /*finishedReceiver*/,
-                            updateUserIds, instantUserIds, res.mRemovedInfo.mBroadcastAllowList,
-                            null);
+                            updateUserIds, instantUserIds,
+                            request.getRemovedInfo().mBroadcastAllowList, null);
                     if (installerPackageName != null) {
                         mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                 extras, 0 /*flags*/,
@@ -2768,7 +2771,7 @@
                             null /*broadcastAllowList*/,
                             mBroadcastHelper.getTemporaryAppAllowlistBroadcastOptions(
                                     REASON_PACKAGE_REPLACED).toBundle());
-                } else if (launchedForRestore && !res.mPkg.isSystem()) {
+                } else if (launchedForRestore && !request.getPkg().isSystem()) {
                     // First-install and we did a restore, so we're responsible for the
                     // first-launch broadcast.
                     if (DEBUG_BACKUP) {
@@ -2780,17 +2783,17 @@
                 }
 
                 // Send broadcast package appeared if external for all users
-                if (res.mPkg.isExternalStorage()) {
+                if (request.getPkg().isExternalStorage()) {
                     if (!update) {
                         final StorageManager storageManager =
                                 mInjector.getSystemService(StorageManager.class);
                         VolumeInfo volume =
                                 storageManager.findVolumeByUuid(
                                         StorageManager.convert(
-                                                res.mPkg.getVolumeUuid()).toString());
+                                                request.getPkg().getVolumeUuid()).toString());
                         int packageExternalStorageType =
                                 PackageManagerServiceUtils.getPackageExternalStorageType(volume,
-                                        res.mPkg.isExternalStorage());
+                                        request.getPkg().isExternalStorage());
                         // If the package was installed externally, log it.
                         if (packageExternalStorageType != StorageEnums.UNKNOWN) {
                             FrameworkStatsLog.write(
@@ -2799,19 +2802,20 @@
                         }
                     }
                     if (DEBUG_INSTALL) {
-                        Slog.i(TAG, "upgrading pkg " + res.mPkg + " is external");
+                        Slog.i(TAG, "upgrading pkg " + request.getPkg() + " is external");
                     }
                     final String[] pkgNames = new String[]{packageName};
-                    final int[] uids = new int[]{res.mPkg.getUid()};
+                    final int[] uids = new int[]{request.getPkg().getUid()};
                     mBroadcastHelper.sendResourcesChangedBroadcast(mPm::snapshotComputer,
                             true /* mediaStatus */, true /* replacing */, pkgNames, uids);
                 }
-            } else if (!ArrayUtils.isEmpty(res.mLibraryConsumers)) { // if static shared lib
+            } else if (!ArrayUtils.isEmpty(request.getLibraryConsumers())) { // if static shared lib
                 // No need to kill consumers if it's installation of new version static shared lib.
                 final Computer snapshot = mPm.snapshotComputer();
-                final boolean dontKillApp = !update && res.mPkg.getStaticSharedLibName() != null;
-                for (int i = 0; i < res.mLibraryConsumers.size(); i++) {
-                    AndroidPackage pkg = res.mLibraryConsumers.get(i);
+                final boolean dontKillApp = !update
+                        && request.getPkg().getStaticSharedLibName() != null;
+                for (int i = 0; i < request.getLibraryConsumers().size(); i++) {
+                    AndroidPackage pkg = request.getLibraryConsumers().get(i);
                     // send broadcast that all consumers of the static shared library have changed
                     mPm.sendPackageChangedBroadcast(snapshot, pkg.getPackageName(), dontKillApp,
                             new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
@@ -2828,9 +2832,9 @@
             }
 
             if (allNewUsers && !update) {
-                mPm.notifyPackageAdded(packageName, res.mUid);
+                mPm.notifyPackageAdded(packageName, request.getUid());
             } else {
-                mPm.notifyPackageChanged(packageName, res.mUid);
+                mPm.notifyPackageChanged(packageName, request.getUid());
             }
 
             // Log current value of "unknown sources" setting
@@ -2838,7 +2842,8 @@
                     getUnknownSourcesSettings());
 
             // Remove the replaced package's older resources safely now
-            InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null;
+            InstallArgs args = request.getRemovedInfo() != null
+                    ? request.getRemovedInfo().mArgs : null;
             if (args != null) {
                 if (!killApp) {
                     // If we didn't kill the app, defer the deletion of code/resource files, since
@@ -2847,7 +2852,7 @@
                     // ApplicationInfo changes have propagated to all application threads.
                     mPm.scheduleDeferredNoKillPostDelete(args);
                 } else {
-                    mRemovePackageHelper.cleanUpResources(args);
+                    mRemovePackageHelper.cleanUpResources(args.mCodeFile, args.mInstructionSets);
                 }
             } else {
                 // Force a gc to clear up things. Ask for a background one, it's fine to go on
@@ -2874,21 +2879,21 @@
         final boolean deferInstallObserver = succeeded && update;
         if (deferInstallObserver) {
             if (killApp) {
-                mPm.scheduleDeferredPendingKillInstallObserver(res, installObserver);
+                mPm.scheduleDeferredPendingKillInstallObserver(request);
             } else {
-                mPm.scheduleDeferredNoKillInstallObserver(res, installObserver);
+                mPm.scheduleDeferredNoKillInstallObserver(request);
             }
         } else {
-            mPm.notifyInstallObserver(res, installObserver);
+            mPm.notifyInstallObserver(request);
         }
 
         // Prune unused static shared libraries which have been cached a period of time
         mPm.schedulePruneUnusedStaticSharedLibraries(true /* delay */);
 
         // Log tracing if needed
-        if (installArgs.mTraceMethod != null) {
-            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, installArgs.mTraceMethod,
-                    installArgs.mTraceCookie);
+        if (request.getTraceMethod() != null) {
+            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, request.getTraceMethod(),
+                    request.getTraceCookie());
         }
     }
 
@@ -3936,10 +3941,10 @@
                             + "; " + pkgSetting.getPathString()
                             + " --> " + parsedPackage.getPath());
 
-            final InstallArgs args = new InstallArgs(
-                    pkgSetting.getPathString(), getAppDexInstructionSets(
-                    pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()));
-            mRemovePackageHelper.cleanUpResources(args);
+            mRemovePackageHelper.cleanUpResources(
+                    new File(pkgSetting.getPathString()),
+                    getAppDexInstructionSets(pkgSetting.getPrimaryCpuAbi(),
+                            pkgSetting.getSecondaryCpuAbi()));
             synchronized (mPm.mLock) {
                 mPm.mSettings.enableSystemPackageLPw(pkgSetting.getPackageName());
             }
@@ -4021,10 +4026,9 @@
                                 + parsedPackage.getLongVersionCode()
                                 + "; " + pkgSetting.getPathString() + " --> "
                                 + parsedPackage.getPath());
-                InstallArgs args = new InstallArgs(
-                        pkgSetting.getPathString(), getAppDexInstructionSets(
-                        pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()));
-                mRemovePackageHelper.cleanUpResources(args);
+                mRemovePackageHelper.cleanUpResources(new File(pkgSetting.getPathString()),
+                        getAppDexInstructionSets(
+                                pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()));
             } else {
                 // The application on /system is older than the application on /data. Hide
                 // the application on /system and the version on /data will be scanned later
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index 753d012..36bbf41 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -16,12 +16,389 @@
 
 package com.android.server.pm;
 
-final class InstallRequest {
-    public final InstallArgs mArgs;
-    public final PackageInstalledInfo mInstallResult;
+import static android.content.pm.PackageManager.INSTALL_REASON_UNKNOWN;
+import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT;
 
-    InstallRequest(InstallArgs args, PackageInstalledInfo res) {
-        mArgs = args;
-        mInstallResult = res;
+import static com.android.server.pm.PackageManagerService.TAG;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.apex.ApexInfo;
+import android.app.AppOpsManager;
+import android.content.pm.DataLoaderType;
+import android.content.pm.IPackageInstallObserver2;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.SigningDetails;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.util.ExceptionUtils;
+import android.util.Slog;
+
+import com.android.server.pm.pkg.AndroidPackage;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+final class InstallRequest {
+    private final int mUserId;
+    @Nullable
+    private final InstallArgs mInstallArgs;
+    @NonNull
+    private final PackageInstalledInfo mInstalledInfo;
+    @Nullable
+    private Runnable mPostInstallRunnable;
+    @Nullable
+    private PackageRemovedInfo mRemovedInfo;
+
+    // New install
+    InstallRequest(InstallingSession params) {
+        mUserId = params.getUser().getIdentifier();
+        mInstallArgs = new InstallArgs(params.mOriginInfo, params.mMoveInfo, params.mObserver,
+                params.mInstallFlags, params.mInstallSource, params.mVolumeUuid,
+                params.getUser(), null /*instructionSets*/, params.mPackageAbiOverride,
+                params.mGrantedRuntimePermissions, params.mAllowlistedRestrictedPermissions,
+                params.mAutoRevokePermissionsMode,
+                params.mTraceMethod, params.mTraceCookie, params.mSigningDetails,
+                params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride,
+                params.mDataLoaderType, params.mPackageSource);
+        mInstalledInfo = new PackageInstalledInfo();
+    }
+
+    // Install existing package as user
+    InstallRequest(int userId, int returnCode, AndroidPackage pkg, int[] newUsers,
+            Runnable runnable) {
+        mUserId = userId;
+        mInstallArgs = null;
+        mInstalledInfo = new PackageInstalledInfo();
+        mInstalledInfo.mReturnCode = returnCode;
+        mInstalledInfo.mPkg = pkg;
+        mInstalledInfo.mNewUsers = newUsers;
+        mPostInstallRunnable = runnable;
+    }
+
+    private static class PackageInstalledInfo {
+        String mName;
+        int mUid = -1;
+        // The set of users that originally had this package installed.
+        int[] mOrigUsers;
+        // The set of users that now have this package installed.
+        int[] mNewUsers;
+        AndroidPackage mPkg;
+        int mReturnCode;
+        String mReturnMsg;
+        String mInstallerPackageName;
+        // The set of packages consuming this shared library or null if no consumers exist.
+        ArrayList<AndroidPackage> mLibraryConsumers;
+        PackageFreezer mFreezer;
+        // In some error cases we want to convey more info back to the observer
+        String mOrigPackage;
+        String mOrigPermission;
+        // The ApexInfo returned by ApexManager#installPackage, used by rebootless APEX install
+        ApexInfo mApexInfo;
+    }
+
+    public String getName() {
+        return mInstalledInfo.mName;
+    }
+
+    public String getReturnMsg() {
+        return mInstalledInfo.mReturnMsg;
+    }
+
+    public OriginInfo getOriginInfo() {
+        return mInstallArgs == null ? null : mInstallArgs.mOriginInfo;
+    }
+
+    public PackageRemovedInfo getRemovedInfo() {
+        return mRemovedInfo;
+    }
+
+    public String getOrigPackage() {
+        return mInstalledInfo.mOrigPackage;
+    }
+
+    public String getOrigPermission() {
+        return mInstalledInfo.mOrigPermission;
+    }
+
+    @Nullable
+    public File getCodeFile() {
+        return mInstallArgs == null ? null : mInstallArgs.mCodeFile;
+    }
+
+    @Nullable
+    public String getCodePath() {
+        return (mInstallArgs != null && mInstallArgs.mCodeFile != null)
+                ? mInstallArgs.mCodeFile.getAbsolutePath() : null;
+    }
+
+    @Nullable
+    public String getAbiOverride() {
+        return mInstallArgs == null ? null : mInstallArgs.mAbiOverride;
+    }
+
+    public int getReturnCode() {
+        return mInstalledInfo.mReturnCode;
+    }
+
+    @Nullable
+    public IPackageInstallObserver2 getObserver() {
+        return mInstallArgs == null ? null : mInstallArgs.mObserver;
+    }
+
+    public boolean isMoveInstall() {
+        return mInstallArgs != null && mInstallArgs.mMoveInfo != null;
+    }
+
+    @Nullable
+    public String getMoveToUuid() {
+        return (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
+                ? mInstallArgs.mMoveInfo.mToUuid : null;
+    }
+
+    @Nullable
+    public String getMovePackageName() {
+        return  (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
+                ? mInstallArgs.mMoveInfo.mPackageName : null;
+    }
+
+    @Nullable
+    public String getMoveFromCodePath() {
+        return  (mInstallArgs != null && mInstallArgs.mMoveInfo != null)
+                ? mInstallArgs.mMoveInfo.mFromCodePath : null;
+    }
+
+    @Nullable
+    public File getOldCodeFile() {
+        return (mRemovedInfo != null && mRemovedInfo.mArgs != null)
+                ? mRemovedInfo.mArgs.mCodeFile : null;
+    }
+
+    @Nullable
+    public String[] getOldInstructionSet() {
+        return (mRemovedInfo != null && mRemovedInfo.mArgs != null)
+                ? mRemovedInfo.mArgs.mInstructionSets : null;
+    }
+
+    public UserHandle getUser() {
+        return new UserHandle(mUserId);
+    }
+
+    public int getUserId() {
+        return mUserId;
+    }
+
+    public int getInstallFlags() {
+        return mInstallArgs == null ? 0 : mInstallArgs.mInstallFlags;
+    }
+
+    public int getInstallReason() {
+        return mInstallArgs == null ? INSTALL_REASON_UNKNOWN : mInstallArgs.mInstallReason;
+    }
+
+    @Nullable
+    public String getVolumeUuid() {
+        return mInstallArgs == null ? null : mInstallArgs.mVolumeUuid;
+    }
+
+    public AndroidPackage getPkg() {
+        return mInstalledInfo.mPkg;
+    }
+
+    @Nullable
+    public String getTraceMethod() {
+        return mInstallArgs == null ? null : mInstallArgs.mTraceMethod;
+    }
+
+    public int getTraceCookie() {
+        return mInstallArgs == null ? 0 : mInstallArgs.mTraceCookie;
+    }
+
+    public boolean isUpdate() {
+        return mRemovedInfo != null && mRemovedInfo.mRemovedPackage != null;
+    }
+
+    @Nullable
+    public String getRemovedPackage() {
+        return mRemovedInfo != null ? mRemovedInfo.mRemovedPackage : null;
+    }
+
+    public boolean isInstallForExistingUser() {
+        return mInstallArgs == null;
+    }
+
+    @Nullable
+    public InstallSource getInstallSource() {
+        return mInstallArgs == null ? null : mInstallArgs.mInstallSource;
+    }
+
+    @Nullable
+    public String getInstallerPackageName() {
+        return (mInstallArgs != null && mInstallArgs.mInstallSource != null)
+                ? mInstallArgs.mInstallSource.installerPackageName : null;
+    }
+
+    public int getDataLoaderType() {
+        return mInstallArgs == null ? DataLoaderType.NONE : mInstallArgs.mDataLoaderType;
+    }
+
+    public int getSignatureSchemeVersion() {
+        return mInstallArgs == null ? SigningDetails.SignatureSchemeVersion.UNKNOWN
+                : mInstallArgs.mSigningDetails.getSignatureSchemeVersion();
+    }
+
+    @NonNull
+    public SigningDetails getSigningDetails() {
+        return mInstallArgs == null ? SigningDetails.UNKNOWN : mInstallArgs.mSigningDetails;
+    }
+
+    @Nullable
+    public Uri getOriginUri() {
+        return mInstallArgs == null ?  null : Uri.fromFile(mInstallArgs.mOriginInfo.mResolvedFile);
+    }
+
+    public ApexInfo getApexInfo() {
+        return mInstalledInfo.mApexInfo;
+    }
+
+    public String getSourceInstallerPackageName() {
+        return mInstallArgs.mInstallSource.installerPackageName;
+    }
+
+    public boolean isRollback() {
+        return mInstallArgs != null
+                && mInstallArgs.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
+    }
+
+    public int[] getNewUsers() {
+        return mInstalledInfo.mNewUsers;
+    }
+
+    public int[] getOriginUsers() {
+        return mInstalledInfo.mOrigUsers;
+    }
+
+    public int getUid() {
+        return mInstalledInfo.mUid;
+    }
+
+    @Nullable
+    public String[] getInstallGrantPermissions() {
+        return mInstallArgs == null ?  null : mInstallArgs.mInstallGrantPermissions;
+    }
+
+    public ArrayList<AndroidPackage> getLibraryConsumers() {
+        return mInstalledInfo.mLibraryConsumers;
+    }
+
+    @Nullable
+    public List<String> getAllowlistedRestrictedPermissions() {
+        return mInstallArgs == null ? null : mInstallArgs.mAllowlistedRestrictedPermissions;
+    }
+
+    public int getAutoRevokePermissionsMode() {
+        return mInstallArgs == null
+                ? AppOpsManager.MODE_DEFAULT : mInstallArgs.mAutoRevokePermissionsMode;
+    }
+
+    public int getPackageSource() {
+        return mInstallArgs == null
+                ? PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED : mInstallArgs.mPackageSource;
+    }
+
+    public int getInstallScenario() {
+        return mInstallArgs == null ? INSTALL_SCENARIO_DEFAULT : mInstallArgs.mInstallScenario;
+    }
+
+    public boolean isForceQueryableOverride() {
+        return mInstallArgs != null && mInstallArgs.mForceQueryableOverride;
+    }
+
+    public void closeFreezer() {
+        if (mInstalledInfo.mFreezer != null) {
+            mInstalledInfo.mFreezer.close();
+        }
+    }
+
+    public void runPostInstallRunnable() {
+        if (mPostInstallRunnable != null) {
+            mPostInstallRunnable.run();
+        }
+    }
+
+    public void setCodeFile(File codeFile) {
+        if (mInstallArgs != null) {
+            mInstallArgs.mCodeFile = codeFile;
+        }
+    }
+
+    public void setError(int code, String msg) {
+        setReturnCode(code);
+        setReturnMessage(msg);
+        Slog.w(TAG, msg);
+    }
+
+    public void setError(String msg, PackageManagerException e) {
+        mInstalledInfo.mReturnCode = e.error;
+        setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
+        Slog.w(TAG, msg, e);
+    }
+
+    public void setReturnCode(int returnCode) {
+        mInstalledInfo.mReturnCode = returnCode;
+    }
+
+    public void setReturnMessage(String returnMsg) {
+        mInstalledInfo.mReturnMsg = returnMsg;
+    }
+
+    public void setApexInfo(ApexInfo apexInfo) {
+        mInstalledInfo.mApexInfo = apexInfo;
+    }
+
+    public void setPkg(AndroidPackage pkg) {
+        mInstalledInfo.mPkg = pkg;
+    }
+
+    public void setUid(int uid) {
+        mInstalledInfo.mUid = uid;
+    }
+
+    public void setNewUsers(int[] newUsers) {
+        mInstalledInfo.mNewUsers = newUsers;
+    }
+
+    public void setOriginPackage(String originPackage) {
+        mInstalledInfo.mOrigPackage = originPackage;
+    }
+
+    public void setOriginPermission(String originPermission) {
+        mInstalledInfo.mOrigPermission = originPermission;
+    }
+
+    public void setInstallerPackageName(String installerPackageName) {
+        mInstalledInfo.mInstallerPackageName = installerPackageName;
+    }
+
+    public void setName(String packageName) {
+        mInstalledInfo.mName = packageName;
+    }
+
+    public void setOriginUsers(int[] userIds) {
+        mInstalledInfo.mOrigUsers = userIds;
+    }
+
+    public void setFreezer(PackageFreezer freezer) {
+        mInstalledInfo.mFreezer = freezer;
+    }
+
+    public void setRemovedInfo(PackageRemovedInfo removedInfo) {
+        mRemovedInfo = removedInfo;
+    }
+
+    public void setLibraryConsumers(ArrayList<AndroidPackage> libraryConsumers) {
+        mInstalledInfo.mLibraryConsumers = libraryConsumers;
     }
 }
diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java
index a7f1727..8d5a5e1 100644
--- a/services/core/java/com/android/server/pm/InstallingSession.java
+++ b/services/core/java/com/android/server/pm/InstallingSession.java
@@ -253,68 +253,69 @@
     }
 
     private void processPendingInstall() {
-        InstallArgs args = new InstallArgs(this);
+        InstallRequest installRequest = new InstallRequest(this);
         if (mRet == PackageManager.INSTALL_SUCCEEDED) {
-            mRet = copyApk(args);
+            mRet = copyApk(installRequest);
         }
         if (mRet == PackageManager.INSTALL_SUCCEEDED) {
             F2fsUtils.releaseCompressedBlocks(
-                    mPm.mContext.getContentResolver(), new File(args.getCodePath()));
+                    mPm.mContext.getContentResolver(), new File(installRequest.getCodePath()));
         }
+        installRequest.setReturnCode(mRet);
         if (mParentInstallingSession != null) {
-            mParentInstallingSession.tryProcessInstallRequest(args, mRet);
+            mParentInstallingSession.tryProcessInstallRequest(installRequest);
         } else {
-            PackageInstalledInfo res = new PackageInstalledInfo(mRet);
             // Queue up an async operation since the package installation may take a little while.
             mPm.mHandler.post(() -> processInstallRequests(
-                    res.mReturnCode == PackageManager.INSTALL_SUCCEEDED /* success */,
-                    Collections.singletonList(new InstallRequest(args, res))));
+                    mRet == PackageManager.INSTALL_SUCCEEDED /* success */,
+                    Collections.singletonList(installRequest)));
         }
     }
 
-    private int copyApk(InstallArgs args) {
+    private int copyApk(InstallRequest request) {
         if (mMoveInfo == null) {
-            return copyApkForFileInstall(args);
+            return copyApkForFileInstall(request);
         } else {
-            return copyApkForMoveInstall(args);
+            return copyApkForMoveInstall(request);
         }
     }
 
-    private int copyApkForFileInstall(InstallArgs args) {
+    private int copyApkForFileInstall(InstallRequest request) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
         try {
             if (mOriginInfo.mStaged) {
                 if (DEBUG_INSTALL) {
                     Slog.d(TAG, mOriginInfo.mFile + " already staged; skipping copy");
                 }
-                args.mCodeFile = mOriginInfo.mFile;
+                request.setCodeFile(mOriginInfo.mFile);
                 return PackageManager.INSTALL_SUCCEEDED;
             }
 
             try {
                 final boolean isEphemeral =
                         (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
-                args.mCodeFile =
-                        mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral);
+                request.setCodeFile(
+                        mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral));
             } catch (IOException e) {
                 Slog.w(TAG, "Failed to create copy file: " + e);
                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
             }
 
             int ret = PackageManagerServiceUtils.copyPackage(
-                    mOriginInfo.mFile.getAbsolutePath(), args.mCodeFile);
+                    mOriginInfo.mFile.getAbsolutePath(), request.getCodeFile());
             if (ret != PackageManager.INSTALL_SUCCEEDED) {
                 Slog.e(TAG, "Failed to copy package");
                 return ret;
             }
 
-            final boolean isIncremental = isIncrementalPath(args.mCodeFile.getAbsolutePath());
-            final File libraryRoot = new File(args.mCodeFile, LIB_DIR_NAME);
+            final boolean isIncremental = isIncrementalPath(
+                    request.getCodeFile().getAbsolutePath());
+            final File libraryRoot = new File(request.getCodeFile(), LIB_DIR_NAME);
             NativeLibraryHelper.Handle handle = null;
             try {
-                handle = NativeLibraryHelper.Handle.create(args.mCodeFile);
+                handle = NativeLibraryHelper.Handle.create(request.getCodeFile());
                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
-                        args.mAbiOverride, isIncremental);
+                        request.getAbiOverride(), isIncremental);
             } catch (IOException e) {
                 Slog.e(TAG, "Copying native libraries failed", e);
                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
@@ -328,7 +329,7 @@
         }
     }
 
-    private int copyApkForMoveInstall(InstallArgs args) {
+    private int copyApkForMoveInstall(InstallRequest request) {
         if (DEBUG_INSTALL) {
             Slog.d(TAG, "Moving " + mMoveInfo.mPackageName + " from "
                     + mMoveInfo.mFromUuid + " to " + mMoveInfo.mToUuid);
@@ -345,8 +346,9 @@
         }
 
         final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
-        args.mCodeFile = new File(Environment.getDataAppDirectory(mMoveInfo.mToUuid), toPathName);
-        if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + args.mCodeFile);
+        request.setCodeFile(
+                new File(Environment.getDataAppDirectory(mMoveInfo.mToUuid), toPathName));
+        if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + request.getCodeFile());
 
         return PackageManager.INSTALL_SUCCEEDED;
     }
@@ -460,7 +462,7 @@
         List<InstallRequest> apexInstallRequests = new ArrayList<>();
         List<InstallRequest> apkInstallRequests = new ArrayList<>();
         for (InstallRequest request : installRequests) {
-            if ((request.mArgs.mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
+            if ((request.getInstallFlags() & PackageManager.INSTALL_APEX) != 0) {
                 apexInstallRequests.add(request);
             } else {
                 apkInstallRequests.add(request);
@@ -485,7 +487,7 @@
                 // processInstallRequestAsync. In that case just notify the observer about the
                 // failure.
                 InstallRequest request = apexInstallRequests.get(0);
-                mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
+                mPm.notifyInstallObserver(request);
             }
             return;
         }
@@ -496,28 +498,25 @@
     private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) {
         if (success) {
             for (InstallRequest request : installRequests) {
-                if (request.mInstallResult.mReturnCode != PackageManager.INSTALL_SUCCEEDED) {
-                    cleanUpForFailedInstall(request.mArgs);
+                if (request.getReturnCode() != PackageManager.INSTALL_SUCCEEDED) {
+                    cleanUpForFailedInstall(request);
                 }
             }
 
             mInstallPackageHelper.installPackagesTraced(installRequests);
 
             for (InstallRequest request : installRequests) {
-                doPostInstall(request.mInstallResult.mReturnCode, request.mArgs);
+                doPostInstall(request);
             }
         }
         for (InstallRequest request : installRequests) {
-            mInstallPackageHelper.restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
-                    request.mInstallResult,
-                    new PostInstallData(request.mArgs,
-                            request.mInstallResult, null));
+            mInstallPackageHelper.restoreAndPostInstall(request);
         }
     }
 
-    private void doPostInstall(int status, InstallArgs args) {
+    private void doPostInstall(InstallRequest request) {
         if (mMoveInfo != null) {
-            if (status == PackageManager.INSTALL_SUCCEEDED) {
+            if (request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) {
                 mRemovePackageHelper.cleanUpForMoveInstall(mMoveInfo.mFromUuid,
                         mMoveInfo.mPackageName, mMoveInfo.mFromCodePath);
             } else {
@@ -525,18 +524,18 @@
                         mMoveInfo.mPackageName, mMoveInfo.mFromCodePath);
             }
         } else {
-            if (status != PackageManager.INSTALL_SUCCEEDED) {
-                mRemovePackageHelper.removeCodePath(args.mCodeFile);
+            if (request.getReturnCode() != PackageManager.INSTALL_SUCCEEDED) {
+                mRemovePackageHelper.removeCodePath(request.getCodeFile());
             }
         }
     }
 
-    private void cleanUpForFailedInstall(InstallArgs args) {
-        if (args.mMoveInfo != null) {
-            mRemovePackageHelper.cleanUpForMoveInstall(args.mMoveInfo.mToUuid,
-                    args.mMoveInfo.mPackageName, args.mMoveInfo.mFromCodePath);
+    private void cleanUpForFailedInstall(InstallRequest request) {
+        if (request.isMoveInstall()) {
+            mRemovePackageHelper.cleanUpForMoveInstall(request.getMoveToUuid(),
+                    request.getMovePackageName(), request.getMoveFromCodePath());
         } else {
-            mRemovePackageHelper.removeCodePath(args.mCodeFile);
+            mRemovePackageHelper.removeCodePath(request.getCodeFile());
         }
     }
 
@@ -560,7 +559,7 @@
         InstallRequest request = requests.get(0);
         try {
             // Should directory scanning logic be moved to ApexManager for better test coverage?
-            final File dir = request.mArgs.mOriginInfo.mResolvedFile;
+            final File dir = request.getOriginInfo().mResolvedFile;
             final File[] apexes = dir.listFiles();
             if (apexes == null) {
                 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
@@ -580,7 +579,7 @@
                     // The newly installed APEX will not be reverted even if
                     // processApkInstallRequests() fails. Need a way to keep info stored in apexd
                     // and PMS in sync in the face of install failures.
-                    request.mInstallResult.mApexInfo = apexInfo;
+                    request.setApexInfo(apexInfo);
                     mPm.mHandler.post(() -> processApkInstallRequests(true, requests));
                     return;
                 } else {
@@ -588,10 +587,10 @@
                 }
             }
         } catch (PackageManagerException e) {
-            request.mInstallResult.setError("APEX installation failed", e);
+            request.setError("APEX installation failed", e);
         }
         PackageManagerService.invalidatePackageInfoCache();
-        mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
+        mPm.notifyInstallObserver(request);
     }
 
     /**
@@ -600,7 +599,7 @@
      */
     private class MultiPackageInstallingSession {
         private final List<InstallingSession> mChildInstallingSessions;
-        private final Map<InstallArgs, Integer> mCurrentState;
+        private final Map<InstallRequest, Integer> mCurrentState;
         @NonNull
         final PackageManagerService mPm;
         final UserHandle mUser;
@@ -636,8 +635,8 @@
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
 
-        public void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
-            mCurrentState.put(args, currentStatus);
+        public void tryProcessInstallRequest(InstallRequest request) {
+            mCurrentState.put(request, request.getReturnCode());
             if (mCurrentState.size() != mChildInstallingSessions.size()) {
                 return;
             }
@@ -651,9 +650,9 @@
                 }
             }
             final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
-            for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
-                installRequests.add(new InstallRequest(entry.getKey(),
-                        new PackageInstalledInfo(completeStatus)));
+            for (Map.Entry<InstallRequest, Integer> entry : mCurrentState.entrySet()) {
+                entry.getKey().setReturnCode(completeStatus);
+                installRequests.add(entry.getKey());
             }
             int finalCompleteStatus = completeStatus;
             mPm.mHandler.post(() -> processInstallRequests(
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index 1ea4d62..4e8b0a1 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -89,18 +89,14 @@
             case POST_INSTALL: {
                 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
 
-                PostInstallData data = mPm.mRunningInstalls.get(msg.arg1);
+                InstallRequest request = mPm.mRunningInstalls.get(msg.arg1);
                 final boolean didRestore = (msg.arg2 != 0);
                 mPm.mRunningInstalls.delete(msg.arg1);
 
-                if (data != null && data.res.mFreezer != null) {
-                    data.res.mFreezer.close();
-                }
-
-                if (data != null && data.mPostInstallRunnable != null) {
-                    data.mPostInstallRunnable.run();
-                } else if (data != null && data.args != null) {
-                    mInstallPackageHelper.handlePackagePostInstall(data.res, data.args, didRestore);
+                request.closeFreezer();
+                request.runPostInstallRunnable();
+                if (!request.isInstallForExistingUser()) {
+                    mInstallPackageHelper.handlePackagePostInstall(request, didRestore);
                 } else if (DEBUG_INSTALL) {
                     // No post-install when we run restore from installExistingPackageForUser
                     Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1);
@@ -111,7 +107,7 @@
             case DEFERRED_NO_KILL_POST_DELETE: {
                 InstallArgs args = (InstallArgs) msg.obj;
                 if (args != null) {
-                    mRemovePackageHelper.cleanUpResources(args);
+                    mRemovePackageHelper.cleanUpResources(args.mCodeFile, args.mInstructionSets);
                 }
             } break;
             case DEFERRED_NO_KILL_INSTALL_OBSERVER:
diff --git a/services/core/java/com/android/server/pm/PackageInstalledInfo.java b/services/core/java/com/android/server/pm/PackageInstalledInfo.java
deleted file mode 100644
index 247abf3..0000000
--- a/services/core/java/com/android/server/pm/PackageInstalledInfo.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import static com.android.server.pm.PackageManagerService.TAG;
-
-import android.apex.ApexInfo;
-import android.util.ExceptionUtils;
-import android.util.Slog;
-
-import com.android.server.pm.pkg.AndroidPackage;
-
-import java.util.ArrayList;
-
-final class PackageInstalledInfo {
-    String mName;
-    int mUid;
-    // The set of users that originally had this package installed.
-    int[] mOrigUsers;
-    // The set of users that now have this package installed.
-    int[] mNewUsers;
-    AndroidPackage mPkg;
-    int mReturnCode;
-    String mReturnMsg;
-    String mInstallerPackageName;
-    PackageRemovedInfo mRemovedInfo;
-    // The set of packages consuming this shared library or null if no consumers exist.
-    ArrayList<AndroidPackage> mLibraryConsumers;
-    PackageFreezer mFreezer;
-
-    // In some error cases we want to convey more info back to the observer
-    String mOrigPackage;
-    String mOrigPermission;
-
-    // The ApexInfo returned by ApexManager#installPackage, used by rebootless APEX install
-    ApexInfo mApexInfo;
-
-    PackageInstalledInfo(int currentStatus) {
-        mReturnCode = currentStatus;
-        mUid = -1;
-        mPkg = null;
-        mRemovedInfo = null;
-    }
-
-    public void setError(int code, String msg) {
-        setReturnCode(code);
-        setReturnMessage(msg);
-        Slog.w(TAG, msg);
-    }
-
-    public void setError(String msg, PackageManagerException e) {
-        mReturnCode = e.error;
-        setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
-        Slog.w(TAG, msg, e);
-    }
-
-    public void setReturnCode(int returnCode) {
-        mReturnCode = returnCode;
-    }
-
-    private void setReturnMessage(String returnMsg) {
-        mReturnMsg = returnMsg;
-    }
-}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 66a97b3..218d9d1 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1344,9 +1344,14 @@
         }
 
         private String getDeviceOwnerDeletedPackageMsg() {
-            DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
-            return dpm.getResources().getString(PACKAGE_DELETED_BY_DO,
-                    () -> mContext.getString(R.string.package_deleted_device_owner));
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+                return dpm.getResources().getString(PACKAGE_DELETED_BY_DO,
+                        () -> mContext.getString(R.string.package_deleted_device_owner));
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
index 34d6d29..65e7ce1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -465,6 +465,20 @@
                 filterCallingUid);
     }
 
+    /**
+     * @deprecated similar to {@link resolveIntent} but limits the matches to exported components.
+     */
+    @Override
+    @Deprecated
+    public final ResolveInfo resolveIntentExported(Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags,
+            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
+            boolean resolveForStart, int filterCallingUid) {
+        return getResolveIntentHelper().resolveIntentInternal(snapshot(),
+                intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
+                filterCallingUid, true);
+    }
+
     @Override
     @Deprecated
     public final ResolveInfo resolveService(Intent intent, String resolvedType,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 259202f..39a6eb7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -82,7 +82,6 @@
 import android.content.pm.IOnChecksumsReadyListener;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver2;
-import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageLoadingProgressCallback;
 import android.content.pm.IPackageManager;
 import android.content.pm.IPackageMoveObserver;
@@ -826,10 +825,10 @@
     @Watched(manual = true)
     private final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
 
-    private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
+    private final Map<String, InstallRequest>
             mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
 
-    private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
+    private final Map<String, InstallRequest>
             mPendingKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
 
     // Internal interface for permission manager
@@ -908,7 +907,7 @@
     // Stores a list of users whose package restrictions file needs to be updated
     final ArraySet<Integer> mDirtyUsers = new ArraySet<>();
 
-    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<>();
+    final SparseArray<InstallRequest> mRunningInstalls = new SparseArray<>();
     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
 
     final @NonNull String[] mRequiredVerifierPackages;
@@ -1155,32 +1154,30 @@
     }
 
     void notifyInstallObserver(String packageName, boolean killApp) {
-        final Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
+        final InstallRequest installRequest =
                 killApp ? mPendingKillInstallObservers.remove(packageName)
                         : mNoKillInstallObservers.remove(packageName);
 
-        if (pair != null) {
-            notifyInstallObserver(pair.first, pair.second);
+        if (installRequest != null) {
+            notifyInstallObserver(installRequest);
         }
     }
 
-    void notifyInstallObserver(PackageInstalledInfo info,
-            IPackageInstallObserver2 installObserver) {
-        if (installObserver != null) {
+    void notifyInstallObserver(InstallRequest request) {
+        if (request.getObserver() != null) {
             try {
-                Bundle extras = extrasForInstallResult(info);
-                installObserver.onPackageInstalled(info.mName, info.mReturnCode,
-                        info.mReturnMsg, extras);
+                Bundle extras = extrasForInstallResult(request);
+                request.getObserver().onPackageInstalled(request.getName(),
+                        request.getReturnCode(), request.getReturnMsg(), extras);
             } catch (RemoteException e) {
                 Slog.i(TAG, "Observer no longer exists.");
             }
         }
     }
 
-    void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
-            IPackageInstallObserver2 observer) {
-        String packageName = info.mPkg.getPackageName();
-        mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
+    void scheduleDeferredNoKillInstallObserver(InstallRequest request) {
+        String packageName = request.getPkg().getPackageName();
+        mNoKillInstallObservers.put(packageName, request);
         Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
         mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
     }
@@ -1196,10 +1193,9 @@
                 delay ? getPruneUnusedSharedLibrariesDelay() : 0);
     }
 
-    void scheduleDeferredPendingKillInstallObserver(PackageInstalledInfo info,
-            IPackageInstallObserver2 observer) {
-        final String packageName = info.mPkg.getPackageName();
-        mPendingKillInstallObservers.put(packageName, Pair.create(info, observer));
+    void scheduleDeferredPendingKillInstallObserver(InstallRequest request) {
+        final String packageName = request.getPkg().getPackageName();
+        mPendingKillInstallObservers.put(packageName, request);
         final Message message = mHandler.obtainMessage(DEFERRED_PENDING_KILL_INSTALL_OBSERVER,
                 packageName);
         mHandler.sendMessageDelayed(message, DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS);
@@ -1312,21 +1308,22 @@
         }
     }
 
-    private static Bundle extrasForInstallResult(PackageInstalledInfo res) {
+    private static Bundle extrasForInstallResult(InstallRequest request) {
         Bundle extras = null;
-        switch (res.mReturnCode) {
+        switch (request.getReturnCode()) {
             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
                 extras = new Bundle();
                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
-                        res.mOrigPermission);
+                        request.getOrigPermission());
                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
-                        res.mOrigPackage);
+                        request.getOrigPackage());
                 break;
             }
             case PackageManager.INSTALL_SUCCEEDED: {
                 extras = new Bundle();
                 extras.putBoolean(Intent.EXTRA_REPLACING,
-                        res.mRemovedInfo != null && res.mRemovedInfo.mRemovedPackage != null);
+                        request.getRemovedInfo() != null
+                                && request.getRemovedInfo().mRemovedPackage != null);
                 break;
             }
         }
@@ -3111,14 +3108,14 @@
         // state for observers to see the FIRST_LAUNCH signal.
         mHandler.post(() -> {
             for (int i = 0; i < mRunningInstalls.size(); i++) {
-                final PostInstallData data = mRunningInstalls.valueAt(i);
-                if (data.res.mReturnCode != PackageManager.INSTALL_SUCCEEDED) {
+                final InstallRequest installRequest = mRunningInstalls.valueAt(i);
+                if (installRequest.getReturnCode() != PackageManager.INSTALL_SUCCEEDED) {
                     continue;
                 }
-                if (packageName.equals(data.res.mPkg.getPackageName())) {
+                if (packageName.equals(installRequest.getPkg().getPackageName())) {
                     // right package; but is it for the right user?
-                    for (int uIndex = 0; uIndex < data.res.mNewUsers.length; uIndex++) {
-                        if (userId == data.res.mNewUsers[uIndex]) {
+                    for (int uIndex = 0; uIndex < installRequest.getNewUsers().length; uIndex++) {
+                        if (userId == installRequest.getNewUsers()[uIndex]) {
                             if (DEBUG_BACKUP) {
                                 Slog.i(TAG, "Package " + packageName
                                         + " being restored so deferring FIRST_LAUNCH");
diff --git a/services/core/java/com/android/server/pm/PackageRemovedInfo.java b/services/core/java/com/android/server/pm/PackageRemovedInfo.java
index 28ad4b6..3c863d0 100644
--- a/services/core/java/com/android/server/pm/PackageRemovedInfo.java
+++ b/services/core/java/com/android/server/pm/PackageRemovedInfo.java
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.PowerExemptionManager;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
@@ -42,8 +43,8 @@
     int[] mRemovedUsers = null;
     int[] mBroadcastUsers = null;
     int[] mInstantUserIds = null;
-    SparseArray<Integer> mInstallReasons;
-    SparseArray<Integer> mUninstallReasons;
+    SparseIntArray mInstallReasons;
+    SparseIntArray mUninstallReasons;
     boolean mIsRemovedPackageSystemUpdate = false;
     boolean mIsUpdate;
     boolean mDataRemoved;
diff --git a/services/core/java/com/android/server/pm/PostInstallData.java b/services/core/java/com/android/server/pm/PostInstallData.java
deleted file mode 100644
index 65d2a65..0000000
--- a/services/core/java/com/android/server/pm/PostInstallData.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-/**
- * Record-keeping of restore-after-install operations that are currently in flight
- * between the Package Manager and the Backup Manager
- */
-public final class PostInstallData {
-    @Nullable
-    public final InstallArgs args;
-    @NonNull
-    public final PackageInstalledInfo res;
-    @Nullable
-    public final Runnable mPostInstallRunnable;
-
-    PostInstallData(@Nullable InstallArgs args, @NonNull PackageInstalledInfo res,
-            @Nullable Runnable postInstallRunnable) {
-        this.args = args;
-        this.res = res;
-        mPostInstallRunnable = postInstallRunnable;
-    }
-}
diff --git a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
index 0f7c652..165b450 100644
--- a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
+++ b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
@@ -77,11 +77,10 @@
             }
 
             // the following may be null if we're just reconciling on boot (and not during install)
-            final InstallArgs installArgs = request.mInstallArgs.get(installPackageName);
-            final PackageInstalledInfo res = request.mInstallResults.get(installPackageName);
+            final InstallRequest installRequest = request.mInstallRequests.get(installPackageName);
             final PrepareResult prepareResult = request.mPreparedPackages.get(installPackageName);
-            final boolean isInstall = installArgs != null;
-            if (isInstall && (res == null || prepareResult == null)) {
+            final boolean isInstall = installRequest != null;
+            if (isInstall && prepareResult == null) {
                 throw new ReconcileFailure("Reconcile arguments are not balanced for "
                         + installPackageName + "!");
             }
@@ -92,7 +91,8 @@
                 final boolean killApp = (scanResult.mRequest.mScanFlags & SCAN_DONT_KILL_APP) == 0;
                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA
                         | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
-                deletePackageAction = DeletePackageHelper.mayDeletePackageLocked(res.mRemovedInfo,
+                deletePackageAction = DeletePackageHelper.mayDeletePackageLocked(
+                        installRequest.getRemovedInfo(),
                         prepareResult.mOriginalPs, prepareResult.mDisabledPs,
                         deleteFlags, null /* all users */);
                 if (deletePackageAction == null) {
@@ -146,8 +146,8 @@
                             request.mVersionInfos.get(installPackageName);
                     final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
                     final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
-                    final boolean isRollback = installArgs != null
-                            && installArgs.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
+                    final boolean isRollback = installRequest != null
+                            && installRequest.isRollback();
                     final boolean compatMatch =
                             PackageManagerServiceUtils.verifySignatures(signatureCheckPs,
                                     sharedUserSetting, disabledPkgSetting,
@@ -257,8 +257,8 @@
             }
 
             result.put(installPackageName,
-                    new ReconciledPackage(request, installArgs, scanResult.mPkgSetting,
-                            res, request.mPreparedPackages.get(installPackageName), scanResult,
+                    new ReconciledPackage(request, installRequest, scanResult.mPkgSetting,
+                            request.mPreparedPackages.get(installPackageName), scanResult,
                             deletePackageAction, allowedSharedLibInfos, signingDetails,
                             sharedUserSignaturesChanged, removeAppKeySetData));
         }
diff --git a/services/core/java/com/android/server/pm/ReconcileRequest.java b/services/core/java/com/android/server/pm/ReconcileRequest.java
index 84b292f..3568c15 100644
--- a/services/core/java/com/android/server/pm/ReconcileRequest.java
+++ b/services/core/java/com/android/server/pm/ReconcileRequest.java
@@ -34,20 +34,17 @@
     public final Map<String, ScanResult> mScannedPackages;
 
     public final Map<String, AndroidPackage> mAllPackages;
-    public final Map<String, InstallArgs> mInstallArgs;
-    public final Map<String, PackageInstalledInfo> mInstallResults;
+    public final Map<String, InstallRequest> mInstallRequests;
     public final Map<String, PrepareResult> mPreparedPackages;
     public final Map<String, Settings.VersionInfo> mVersionInfos;
 
     ReconcileRequest(Map<String, ScanResult> scannedPackages,
-            Map<String, InstallArgs> installArgs,
-            Map<String, PackageInstalledInfo> installResults,
+            Map<String, InstallRequest> installRequests,
             Map<String, PrepareResult> preparedPackages,
             Map<String, AndroidPackage> allPackages,
             Map<String, Settings.VersionInfo> versionInfos) {
         mScannedPackages = scannedPackages;
-        mInstallArgs = installArgs;
-        mInstallResults = installResults;
+        mInstallRequests = installRequests;
         mPreparedPackages = preparedPackages;
         mAllPackages = allPackages;
         mVersionInfos = versionInfos;
@@ -56,7 +53,7 @@
     ReconcileRequest(Map<String, ScanResult> scannedPackages,
             Map<String, AndroidPackage> allPackages,
             Map<String, Settings.VersionInfo> versionInfos) {
-        this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
+        this(scannedPackages, Collections.emptyMap(),
                 Collections.emptyMap(), allPackages, versionInfos);
     }
 }
diff --git a/services/core/java/com/android/server/pm/ReconciledPackage.java b/services/core/java/com/android/server/pm/ReconciledPackage.java
index 3bb5a1b..d4da6c7 100644
--- a/services/core/java/com/android/server/pm/ReconciledPackage.java
+++ b/services/core/java/com/android/server/pm/ReconciledPackage.java
@@ -37,9 +37,8 @@
     public final PackageSetting mPkgSetting;
     public final ScanResult mScanResult;
     // TODO: Remove install-specific details from the reconcile result
-    public final PackageInstalledInfo mInstallResult;
     @Nullable public final PrepareResult mPrepareResult;
-    @Nullable public final InstallArgs mInstallArgs;
+    @Nullable public final InstallRequest mInstallRequest;
     public final DeletePackageAction mDeletePackageAction;
     public final List<SharedLibraryInfo> mAllowedSharedLibraryInfos;
     public final SigningDetails mSigningDetails;
@@ -48,9 +47,8 @@
     public final boolean mRemoveAppKeySetData;
 
     ReconciledPackage(ReconcileRequest request,
-            InstallArgs installArgs,
+            InstallRequest installRequest,
             PackageSetting pkgSetting,
-            PackageInstalledInfo installResult,
             PrepareResult prepareResult,
             ScanResult scanResult,
             DeletePackageAction deletePackageAction,
@@ -59,9 +57,8 @@
             boolean sharedUserSignaturesChanged,
             boolean removeAppKeySetData) {
         mRequest = request;
-        mInstallArgs = installArgs;
+        mInstallRequest = installRequest;
         mPkgSetting = pkgSetting;
-        mInstallResult = installResult;
         mPrepareResult = prepareResult;
         mScanResult = scanResult;
         mDeletePackageAction = deletePackageAction;
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index a025965..55d4b36 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -385,29 +385,29 @@
         }
     }
 
-    void cleanUpResources(InstallArgs args) {
+    void cleanUpResources(File codeFile, String[] instructionSets) {
         synchronized (mPm.mInstallLock) {
-            cleanUpResourcesLI(args);
+            cleanUpResourcesLI(codeFile, instructionSets);
         }
     }
 
     // Need installer lock especially for dex file removal.
     @GuardedBy("mPm.mInstallLock")
-    private void cleanUpResourcesLI(InstallArgs args) {
+    private void cleanUpResourcesLI(File codeFile, String[] instructionSets) {
         // Try enumerating all code paths before deleting
         List<String> allCodePaths = Collections.EMPTY_LIST;
-        if (args.mCodeFile != null && args.mCodeFile.exists()) {
+        if (codeFile != null && codeFile.exists()) {
             final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
             final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
-                    input.reset(), args.mCodeFile, /* flags */ 0);
+                    input.reset(), codeFile, /* flags */ 0);
             if (result.isSuccess()) {
                 // Ignore error; we tried our best
                 allCodePaths = result.getResult().getAllApkPaths();
             }
         }
 
-        removeCodePathLI(args.mCodeFile);
-        removeDexFilesLI(allCodePaths, args.mInstructionSets);
+        removeCodePathLI(codeFile);
+        removeDexFilesLI(allCodePaths, instructionSets);
     }
 
     @GuardedBy("mPm.mInstallLock")
diff --git a/services/core/java/com/android/server/pm/ResolveIntentHelper.java b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
index c2fd637..fada577 100644
--- a/services/core/java/com/android/server/pm/ResolveIntentHelper.java
+++ b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
@@ -52,6 +52,7 @@
 
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.util.ArrayUtils;
+import com.android.server.am.ActivityManagerService;
 import com.android.server.compat.PlatformCompat;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageStateInternal;
@@ -100,6 +101,38 @@
         mInstantAppInstallerActivitySupplier = instantAppInstallerActivitySupplier;
     }
 
+    private static void filterNonExportedComponents(Intent intent, int filterCallingUid,
+            List<ResolveInfo> query, PlatformCompat platformCompat, Computer computer) {
+        if (query == null
+                || intent.getPackage() != null
+                || intent.getComponent() != null
+                || ActivityManager.canAccessUnexportedComponents(filterCallingUid)) {
+            return;
+        }
+        AndroidPackage caller = computer.getPackage(filterCallingUid);
+        String callerPackage = caller == null ? "Not specified" : caller.getPackageName();
+        for (int i = query.size() - 1; i >= 0; i--) {
+            if (!query.get(i).getComponentInfo().exported) {
+                if (!platformCompat.isChangeEnabledByUid(
+                        ActivityManagerService.IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS,
+                        filterCallingUid)) {
+                    Slog.w(TAG, "Non-exported component not filtered out "
+                            + "(will be filtered out once the app targets U+)- intent: "
+                            + intent.getAction() + ", component: "
+                            + query.get(i).getComponentInfo()
+                            .getComponentName().flattenToShortString()
+                            + ", starter: " + callerPackage);
+                    return;
+                }
+                Slog.w(TAG, "Non-exported component filtered out - intent: "
+                        + intent.getAction() + ", component: "
+                        + query.get(i).getComponentInfo().getComponentName().flattenToShortString()
+                        + ", starter: " + callerPackage);
+                query.remove(i);
+            }
+        }
+    }
+
     /**
      * Normally instant apps can only be resolved when they're visible to the caller.
      * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
@@ -109,6 +142,20 @@
             @PackageManager.ResolveInfoFlagsBits long flags,
             @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
             boolean resolveForStart, int filterCallingUid) {
+        return resolveIntentInternal(computer, intent, resolvedType, flags,
+                privateResolveFlags, userId, resolveForStart, filterCallingUid, false);
+    }
+
+    /**
+     * Normally instant apps can only be resolved when they're visible to the caller.
+     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
+     * since we need to allow the system to start any installed application.
+     * Allows picking exported components only.
+     */
+    public ResolveInfo resolveIntentInternal(Computer computer, Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags,
+            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
+            boolean resolveForStart, int filterCallingUid, boolean exportedComponentsOnly) {
         try {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
 
@@ -124,6 +171,10 @@
             final List<ResolveInfo> query = computer.queryIntentActivitiesInternal(intent,
                     resolvedType, flags, privateResolveFlags, filterCallingUid, userId,
                     resolveForStart, true /*allowDynamicSplits*/);
+            if (exportedComponentsOnly) {
+                filterNonExportedComponents(intent, filterCallingUid, query,
+                        mPlatformCompat, computer);
+            }
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
             final boolean queryMayBeFiltered =
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 4f5fd02..b620249 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -328,8 +328,10 @@
      * <p>On most devices this call will be a no-op, but it will be used on devices that support
      * multiple users on multiple displays (like automotives with passenger displays).
      *
-     * <p><b>NOTE: </b>this method is meant to be used only by {@code UserController} when a user is
-     * started and it doesn't validate if the display exists.
+     * <p><b>NOTE: </b>this method doesn't validate if the display exists, it's up to the caller to
+     * check it. In fact, one of the intended clients for this method is
+     * {@code DisplayManagerService}, which will call it when a virtual display is created (another
+     * client is {@code UserController}, which will call it when a user is started).
      *
      */
     public abstract void assignUserToDisplay(@UserIdInt int userId, int displayId);
@@ -340,8 +342,8 @@
      * <p>On most devices this call will be a no-op, but it will be used on devices that support
      * multiple users on multiple displays (like automotives with passenger displays).
      *
-     * <p><b>NOTE: </b>this method is meant to be used only by {@code UserController} when a user is
-     * stopped.
+     * <p><b>NOTE: </b>this method is meant to be used only by {@code UserController} (when a user
+     * is stopped) and {@code DisplayManagerService} (when a virtual display is destroyed).
      */
     public abstract void unassignUserFromDisplay(@UserIdInt int userId);
 
@@ -361,11 +363,14 @@
      * Returns the display id assigned to the user, or {@code Display.INVALID_DISPLAY} if the
      * user is not assigned to any display.
      *
-     * <p>The current foreground user is associated with the
+     * <p>The current foreground user and its running profiles are associated with the
      * {@link android.view.Display#DEFAULT_DISPLAY default display}, while other users would only be
-     * assigned to a display if they were started with
-     * {@code ActivityManager.startUserInBackgroundOnSecondaryDisplay()}. If the user is a profile
-     * and is running, it's assigned to its parent display.
+     * assigned to a display if a call to {@link #assignUserToDisplay(int, int)} is made for such
+     * user / display combination (for example, if the user was started with
+     * {@code ActivityManager.startUserInBackgroundOnSecondaryDisplay()}, {@code UserController}
+     * would make such call).
+     *
+     * <p>If the user is a profile and is running, it's assigned to its parent display.
      */
     public abstract int getDisplayAssignedToUser(@UserIdInt int userId);
 
@@ -375,8 +380,11 @@
      * associated with the display.
      *
      * <p>The {@link android.view.Display#DEFAULT_DISPLAY default display} is always assigned to
-     * the current foreground user, while other displays would be associated with the user that was
-     * started with {@code ActivityManager.startUserInBackgroundOnSecondaryDisplay()}.
+     * the current foreground user, while other displays would only be associated with users through
+     * a explicit {@link #assignUserToDisplay(int, int)} call with that user / display combination
+     * (for example, if the user was started with
+     * {@code ActivityManager.startUserInBackgroundOnSecondaryDisplay()}, {@code UserController}
+     * would make such call).
      */
     public abstract @UserIdInt int getUserAssignedToDisplay(int displayId);
 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 07ec80b..c77459d 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1785,18 +1785,10 @@
 
     @VisibleForTesting
     int getUserAssignedToDisplay(int displayId) {
-        if (displayId == Display.DEFAULT_DISPLAY) {
+        if (displayId == Display.DEFAULT_DISPLAY || !mUsersOnSecondaryDisplaysEnabled) {
             return getCurrentUserId();
         }
 
-        if (!mUsersOnSecondaryDisplaysEnabled) {
-            int currentUserId = getCurrentUserId();
-            Slogf.w(LOG_TAG, "getUsersAssignedToDisplay(%d) called with non-DEFAULT_DISPLAY on "
-                    + "system that doesn't support that; returning current user (%d)", displayId,
-                    currentUserId);
-            return currentUserId;
-        }
-
         synchronized (mUsersOnSecondaryDisplays) {
             for (int i = 0; i < mUsersOnSecondaryDisplays.size(); i++) {
                 if (mUsersOnSecondaryDisplays.valueAt(i) != displayId) {
@@ -2056,8 +2048,8 @@
         }
     }
 
-    @Override
-    public boolean isUserSwitcherEnabled(@UserIdInt int mUserId) {
+    @VisibleForTesting
+    boolean isUserSwitcherEnabled(@UserIdInt int mUserId) {
         boolean multiUserSettingOn = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.USER_SWITCHER_ENABLED,
                 Resources.getSystem().getBoolean(com.android.internal
@@ -2070,6 +2062,33 @@
     }
 
     @Override
+    public boolean isUserSwitcherEnabled(boolean showEvenIfNotActionable,
+            @UserIdInt int mUserId) {
+        if (!isUserSwitcherEnabled(mUserId)) {
+            return false;
+        }
+        // The feature is enabled. But is it worth showing?
+        return showEvenIfNotActionable
+                || !hasUserRestriction(UserManager.DISALLOW_ADD_USER, mUserId) // Can add new user
+                || areThereMultipleSwitchableUsers(); // There are switchable users
+    }
+
+    /** Returns true if there is more than one user that can be switched to. */
+    private boolean areThereMultipleSwitchableUsers() {
+        List<UserInfo> aliveUsers = getUsers(true, true, true);
+        boolean isAnyAliveUser = false;
+        for (UserInfo userInfo : aliveUsers) {
+            if (userInfo.supportsSwitchToByUser()) {
+                if (isAnyAliveUser) {
+                    return true;
+                }
+                isAnyAliveUser = true;
+            }
+        }
+        return false;
+    }
+
+    @Override
     public boolean isRestricted(@UserIdInt int userId) {
         if (userId != UserHandle.getCallingUserId()) {
             checkCreateUsersPermission("query isRestricted for user " + userId);
@@ -6844,20 +6863,22 @@
 
                 // Check if display is available
                 for (int i = 0; i < mUsersOnSecondaryDisplays.size(); i++) {
-                    // Make sure display is not used by other users...
-                    // TODO(b/240736142); currently, if a user was started in a display, it
-                    // would need to be stopped first, so "switching" a user on secondary
-                    // diplay requires 2 non-atomic operations (stop and start). Once this logic
-                    // is refactored, it should be atomic.
-                    if (mUsersOnSecondaryDisplays.valueAt(i) == displayId) {
-                        throw new IllegalStateException("Cannot assign " + userId + " to "
-                                + "display " + displayId + " as it's already assigned to "
-                                + "user " + mUsersOnSecondaryDisplays.keyAt(i));
+                    int assignedUserId = mUsersOnSecondaryDisplays.keyAt(i);
+                    int assignedDisplayId = mUsersOnSecondaryDisplays.valueAt(i);
+                    if (DBG_MUMD) {
+                        Slogf.d(LOG_TAG, "%d: assignedUserId=%d, assignedDisplayId=%d",
+                                i, assignedUserId, assignedDisplayId);
                     }
-                    // TODO(b/239982558) also check that user is not already assigned to other
-                    // display (including 0). That would be harder to tested under CTS though
-                    // (for example, would need to add a new AM method to start user in bg on
-                    // main display), so it's better to test on unit tests
+                    if (displayId == assignedDisplayId) {
+                        throw new IllegalStateException("Cannot assign user " + userId + " to "
+                                + "display " + displayId + " because such display is already "
+                                + "assigned to user " + assignedUserId);
+                    }
+                    if (userId == assignedUserId) {
+                        throw new IllegalStateException("Cannot assign user " + userId + " to "
+                                + "display " + displayId + " because such user is as already "
+                                + "assigned to display " + assignedDisplayId);
+                    }
                 }
 
                 if (DBG_MUMD) {
@@ -7078,4 +7099,5 @@
         }
         return mAmInternal;
     }
+
 }
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 073776f..37abeac 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -781,7 +781,7 @@
             for (String voiceInteractPackageName : voiceInteractPackageNames) {
                 grantPermissionsToSystemPackage(pm, voiceInteractPackageName, userId,
                         CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS, MICROPHONE_PERMISSIONS,
-                        PHONE_PERMISSIONS, SMS_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
+                        PHONE_PERMISSIONS, SMS_PERMISSIONS, COARSE_BACKGROUND_LOCATION_PERMISSIONS,
                         NEARBY_DEVICES_PERMISSIONS, NOTIFICATION_PERMISSIONS);
             }
         }
diff --git a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
index 6078d4a..8a82d6e 100644
--- a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
@@ -34,6 +34,7 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.SigningDetails;
 import android.os.Bundle;
+import android.processor.immutability.Immutable;
 import android.util.ArraySet;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -65,6 +66,7 @@
  * @hide
  */
 //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+@Immutable
 public interface AndroidPackage {
 
     /**
@@ -86,6 +88,7 @@
      * @see ActivityInfo
      * @see PackageInfo#activities
      */
+    @Immutable.Ignore
     @NonNull
     List<ParsedActivity> getActivities();
 
@@ -101,6 +104,7 @@
     /**
      * @see R.styleable#AndroidManifestApexSystemService
      */
+    @Immutable.Ignore
     @NonNull
     List<ParsedApexSystemService> getApexSystemServices();
 
@@ -111,6 +115,7 @@
     @Nullable
     String getAppComponentFactory();
 
+    @Immutable.Ignore
     @NonNull
     List<ParsedAttribution> getAttributions();
 
@@ -189,6 +194,7 @@
      * @see PackageInfo#configPreferences
      * @see R.styleable#AndroidManifestUsesConfiguration
      */
+    @Immutable.Ignore
     @NonNull
     List<ConfigurationInfo> getConfigPreferences();
 
@@ -208,6 +214,7 @@
      * @see PackageInfo#featureGroups
      * @see R.styleable#AndroidManifestUsesFeature
      */
+    @Immutable.Ignore
     @NonNull
     List<FeatureGroupInfo> getFeatureGroups();
 
@@ -247,6 +254,7 @@
      * @see InstrumentationInfo
      * @see PackageInfo#instrumentation
      */
+    @Immutable.Ignore
     @NonNull
     List<ParsedInstrumentation> getInstrumentations();
 
@@ -257,6 +265,7 @@
      * @see R.styleable#AndroidManifestKeySet
      * @see R.styleable#AndroidManifestPublicKey
      */
+    @Immutable.Ignore
     @NonNull
     Map<String, ArraySet<PublicKey>> getKeySetMapping();
 
@@ -341,6 +350,7 @@
     /**
      * TODO(b/135203078): Make all the Bundles immutable (and non-null by shared empty reference?)
      */
+    @Immutable.Ignore
     @Nullable
     Bundle getMetaData();
 
@@ -356,6 +366,7 @@
     /**
      * @see R.styleable#AndroidManifestExtensionSdk
      */
+    @Immutable.Ignore
     @Nullable
     SparseIntArray getMinExtensionVersions();
 
@@ -464,6 +475,7 @@
     /**
      * @see android.content.pm.PermissionGroupInfo
      */
+    @Immutable.Ignore
     @NonNull
     List<ParsedPermissionGroup> getPermissionGroups();
 
@@ -471,6 +483,7 @@
      * @see PermissionInfo
      * @see PackageInfo#permissions
      */
+    @Immutable.Ignore
     @NonNull
     List<ParsedPermission> getPermissions();
 
@@ -480,6 +493,7 @@
      * Map of component className to intent info inside that component. TODO(b/135203078): Is this
      * actually used/working?
      */
+    @Immutable.Ignore
     @NonNull
     List<Pair<String, ParsedIntentInfo>> getPreferredActivityFilters();
 
@@ -493,12 +507,14 @@
     /**
      * @see android.content.pm.ProcessInfo
      */
+    @Immutable.Ignore
     @NonNull
     Map<String, ParsedProcess> getProcesses();
 
     /**
      * Returns the properties set on the application
      */
+    @Immutable.Ignore
     @NonNull
     Map<String, PackageManager.Property> getProperties();
 
@@ -522,6 +538,7 @@
      * @see ProviderInfo
      * @see PackageInfo#providers
      */
+    @Immutable.Ignore
     @NonNull
     List<ParsedProvider> getProviders();
 
@@ -530,6 +547,7 @@
      *
      * @see R.styleable#AndroidManifestQueriesIntent
      */
+    @Immutable.Ignore
     @NonNull
     List<Intent> getQueriesIntents();
 
@@ -566,6 +584,7 @@
      * @see ActivityInfo
      * @see PackageInfo#receivers
      */
+    @Immutable.Ignore
     @NonNull
     List<ParsedActivity> getReceivers();
 
@@ -573,6 +592,7 @@
      * @see PackageInfo#reqFeatures
      * @see R.styleable#AndroidManifestUsesFeature
      */
+    @Immutable.Ignore
     @NonNull
     List<FeatureInfo> getRequestedFeatures();
 
@@ -615,6 +635,7 @@
      *
      * @see R.styleable#AndroidManifestRestrictUpdate
      */
+    @Immutable.Ignore
     @Nullable
     byte[] getRestrictUpdateHash();
 
@@ -662,6 +683,7 @@
      * @see ServiceInfo
      * @see PackageInfo#services
      */
+    @Immutable.Ignore
     @NonNull
     List<ParsedService> getServices();
 
@@ -682,6 +704,7 @@
      * The signature data of all APKs in this package, which must be exactly the same across the
      * base and splits.
      */
+    @Immutable.Ignore
     @NonNull
     SigningDetails getSigningDetails();
 
@@ -689,6 +712,7 @@
      * @see ApplicationInfo#splitClassLoaderNames
      * @see R.styleable#AndroidManifestApplication_classLoader
      */
+    @Immutable.Ignore
     @Nullable
     String[] getSplitClassLoaderNames();
 
@@ -696,18 +720,21 @@
      * @see ApplicationInfo#splitSourceDirs
      * @see ApplicationInfo#getSplitCodePaths
      */
+    @Immutable.Ignore
     @NonNull
     String[] getSplitCodePaths();
 
     /**
      * @see ApplicationInfo#splitDependencies
      */
+    @Immutable.Ignore
     @NonNull
     SparseArray<int[]> getSplitDependencies();
 
     /**
      * Flags of any split APKs; ordered by parsed splitName
      */
+    @Immutable.Ignore
     @Nullable
     int[] getSplitFlags();
 
@@ -717,12 +744,14 @@
      * @see ApplicationInfo#splitNames
      * @see PackageInfo#splitNames
      */
+    @Immutable.Ignore
     @NonNull
     String[] getSplitNames();
 
     /**
      * @see PackageInfo#splitRevisionCodes
      */
+    @Immutable.Ignore
     @NonNull
     int[] getSplitRevisionCodes();
 
@@ -818,6 +847,7 @@
     @NonNull
     List<String> getUsesOptionalNativeLibraries();
 
+    @Immutable.Ignore
     @NonNull
     List<ParsedUsesPermission> getUsesPermissions();
 
@@ -832,12 +862,14 @@
     /**
      * @see R.styleable#AndroidManifestUsesSdkLibrary_certDigest
      */
+    @Immutable.Ignore
     @Nullable
     String[][] getUsesSdkLibrariesCertDigests();
 
     /**
      * @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor
      */
+    @Immutable.Ignore
     @Nullable
     long[] getUsesSdkLibrariesVersionsMajor();
 
@@ -852,12 +884,14 @@
     /**
      * @see R.styleable#AndroidManifestUsesStaticLibrary_certDigest
      */
+    @Immutable.Ignore
     @Nullable
     String[][] getUsesStaticLibrariesCertDigests();
 
     /**
      * @see R.styleable#AndroidManifestUsesStaticLibrary_version
      */
+    @Immutable.Ignore
     @Nullable
     long[] getUsesStaticLibrariesVersions();
 
diff --git a/services/core/java/com/android/server/pm/pkg/PackageState.java b/services/core/java/com/android/server/pm/pkg/PackageState.java
index f0e386c..12e9671 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageState.java
@@ -25,6 +25,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.SigningInfo;
+import android.processor.immutability.Immutable;
 import android.util.SparseArray;
 
 import com.android.server.pm.PackageSetting;
@@ -55,6 +56,7 @@
  * @hide
  */
 //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+@Immutable
 public interface PackageState {
 
     /**
@@ -109,6 +111,7 @@
      * Keys are indexes into the array represented by {@link PackageManager.NotifyReason}, values
      * are in epoch milliseconds.
      */
+    @Immutable.Ignore
     @Size(PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT)
     @NonNull
     long[] getLastPackageUsageTime();
@@ -172,9 +175,11 @@
      */
     int getSharedUserAppId();
 
+    @Immutable.Ignore
     @NonNull
     SigningInfo getSigningInfo();
 
+    @Immutable.Ignore
     @NonNull
     SparseArray<? extends PackageUserState> getUserStates();
 
@@ -199,30 +204,35 @@
     /**
      * @see R.styleable#AndroidManifestUsesLibrary
      */
+    @Immutable.Ignore
     @NonNull
     List<SharedLibraryInfo> getUsesLibraryInfos();
 
     /**
      * @see R.styleable#AndroidManifestUsesSdkLibrary
      */
+    @Immutable.Ignore
     @NonNull
     String[] getUsesSdkLibraries();
 
     /**
      * @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor
      */
+    @Immutable.Ignore
     @NonNull
     long[] getUsesSdkLibrariesVersionsMajor();
 
     /**
      * @see R.styleable#AndroidManifestUsesStaticLibrary
      */
+    @Immutable.Ignore
     @NonNull
     String[] getUsesStaticLibraries();
 
     /**
      * @see R.styleable#AndroidManifestUsesStaticLibrary_version
      */
+    @Immutable.Ignore
     @NonNull
     long[] getUsesStaticLibrariesVersions();
 
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserState.java b/services/core/java/com/android/server/pm/pkg/PackageUserState.java
index e19e555..2d25385 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserState.java
@@ -21,6 +21,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.overlay.OverlayPaths;
 import android.os.UserHandle;
+import android.processor.immutability.Immutable;
 import android.util.ArraySet;
 
 import java.util.Map;
@@ -35,6 +36,7 @@
  */
 // TODO(b/173807334): Expose API
 //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+@Immutable.Ignore(reason = "Exposed through PackageState pending refactor")
 public interface PackageUserState {
 
     /** @hide */
diff --git a/services/core/java/com/android/server/pm/pkg/component/ParsedProvider.java b/services/core/java/com/android/server/pm/pkg/component/ParsedProvider.java
index ba85e07..c66a5c1 100644
--- a/services/core/java/com/android/server/pm/pkg/component/ParsedProvider.java
+++ b/services/core/java/com/android/server/pm/pkg/component/ParsedProvider.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.content.pm.PathPermission;
 import android.os.PatternMatcher;
+import android.processor.immutability.Immutable;
 
 import java.util.List;
 
@@ -34,12 +35,14 @@
 
     boolean isMultiProcess();
 
+    @Immutable.Ignore
     @NonNull
     List<PathPermission> getPathPermissions();
 
     @Nullable
     String getReadPermission();
 
+    @Immutable.Ignore
     @NonNull
     List<PatternMatcher> getUriPermissionPatterns();
 
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index e332ac7..675819a 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3052,6 +3052,13 @@
                     }
                 }
                 break;
+            case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY:
+            case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY:
+            case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY:
+            case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL:
+                Slog.wtf(TAG, "KEYCODE_STYLUS_BUTTON_* should be handled in"
+                        + " interceptKeyBeforeQueueing");
+                return key_consumed;
         }
 
         if (isValidGlobalKey(keyCode)
@@ -4104,6 +4111,14 @@
                 result &= ~ACTION_PASS_TO_USER;
                 break;
             }
+            case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY:
+            case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY:
+            case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY:
+            case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL: {
+                // TODO(go/android-stylus-buttons): Handle stylus button presses.
+                result &= ~ACTION_PASS_TO_USER;
+                break;
+            }
         }
 
         if (useHapticFeedback) {
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
index 05d92be..b0f03ef 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java
@@ -17,6 +17,7 @@
 package com.android.server.soundtrigger_middleware;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.media.soundtrigger.ModelParameterRange;
 import android.media.soundtrigger.PhraseRecognitionEvent;
 import android.media.soundtrigger.PhraseSoundModel;
@@ -289,43 +290,60 @@
      * they were pushed.
      * <li>Events can be flushed via {@link #flush()}. This will block until all events pushed prior
      * to this call have been fully processed.
+     * TODO(b/246584464) Remove and replace with Handler (and other concurrency fixes).
      * </ul>
      */
-    private static class CallbackThread {
+    private static class CallbackThread implements Runnable {
         private final Queue<Runnable> mList = new LinkedList<>();
         private int mPushCount = 0;
         private int mProcessedCount = 0;
-
+        private boolean mQuitting = false;
+        private final Thread mThread;
         /**
          * Ctor. Starts the thread.
          */
         CallbackThread() {
-            new Thread(() -> {
-                try {
-                    while (true) {
-                        pop().run();
-                        synchronized (mList) {
-                            mProcessedCount++;
-                            mList.notifyAll();
-                        }
-                    }
-                } catch (InterruptedException e) {
-                    // If interrupted, exit.
-                }
-            }).start();
+            mThread = new Thread(this , "STHAL Concurrent Capture Handler Callback");
+            mThread.start();
         }
-
+        /**
+         * Consume items in the queue until quit is called.
+         */
+        public void run() {
+            try {
+                while (true) {
+                    Runnable toRun = pop();
+                    if (toRun == null) {
+                      // There are no longer any runnables to run,
+                      // and quit() has been called.
+                      return;
+                    }
+                    toRun.run();
+                    synchronized (mList) {
+                        mProcessedCount++;
+                        mList.notifyAll();
+                    }
+                }
+            } catch (InterruptedException e) {
+                // If interrupted, exit.
+                // Note, this is dangerous wrt to flush.
+            }
+        }
         /**
          * Push a new runnable to the queue, with no deduping.
+         * If quit has been called, the runnable will not be pushed.
          *
          * @param runnable The runnable to push.
+         * @return If the runnable was successfully pushed.
          */
-        void push(Runnable runnable) {
+        boolean push(Runnable runnable) {
             synchronized (mList) {
+                if (mQuitting) return false;
                 mList.add(runnable);
                 mPushCount++;
                 mList.notifyAll();
             }
+            return true;
         }
 
         /**
@@ -343,11 +361,26 @@
             }
         }
 
-        private Runnable pop() throws InterruptedException {
+        /**
+         * Quit processing after the queue is cleared.
+         * All subsequent calls to push will fail.
+         * Note, this does not flush.
+         */
+        void quit() {
+            synchronized(mList) {
+                mQuitting = true;
+                mList.notifyAll();
+            }
+        }
+
+        // Returns the next runnable when available.
+        // Returns null iff the list is empty and quit has been called.
+        private @Nullable Runnable pop() throws InterruptedException {
             synchronized (mList) {
-                while (mList.isEmpty()) {
+                while (mList.isEmpty() && !mQuitting) {
                     mList.wait();
                 }
+                if (mList.isEmpty() && mQuitting) return null;
                 return mList.remove();
             }
         }
@@ -372,6 +405,7 @@
     public void detach() {
         mDelegate.detach();
         mNotifier.unregisterListener(this);
+        mCallbackThread.quit();
     }
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalWatchdog.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalWatchdog.java
index 227424e..b817821 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalWatchdog.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalWatchdog.java
@@ -150,6 +150,8 @@
     @Override
     public void detach() {
         mUnderlying.detach();
+        // We should no longer have any pending calls
+        mTimer.quit();
     }
 
     private class Watchdog implements AutoCloseable {
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/UptimeTimer.java b/services/core/java/com/android/server/soundtrigger_middleware/UptimeTimer.java
index bfcc7d8..fe91e66 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/UptimeTimer.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/UptimeTimer.java
@@ -18,9 +18,7 @@
 
 import android.annotation.NonNull;
 import android.os.Handler;
-import android.os.Looper;
-
-import java.util.concurrent.atomic.AtomicReference;
+import android.os.HandlerThread;
 
 /**
  * A simple timer, similar to java.util.Timer, but using the "uptime clock".
@@ -33,58 +31,45 @@
  * task.cancel();
  */
 class UptimeTimer {
-    private Handler mHandler = null;
+    private final Handler mHandler;
+    private final HandlerThread mHandlerThread;
 
     interface Task {
         void cancel();
     }
 
     UptimeTimer(String threadName) {
-        new Thread(this::threadFunc, threadName).start();
-        synchronized (this) {
-            while (mHandler == null) {
-                try {
-                    wait();
-                } catch (InterruptedException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        }
+        mHandlerThread = new HandlerThread(threadName);
+        mHandlerThread.start();
+        // Blocks until looper init
+        mHandler = new Handler(mHandlerThread.getLooper());
     }
 
+    // Note, this method is not internally synchronized.
+    // This is safe since Handlers are internally synchronized.
     Task createTask(@NonNull Runnable runnable, long uptimeMs) {
-        TaskImpl task = new TaskImpl(runnable);
-        mHandler.postDelayed(task, uptimeMs);
+        Object token = new Object();
+        TaskImpl task = new TaskImpl(mHandler, token);
+        mHandler.postDelayed(runnable, token, uptimeMs);
         return task;
     }
 
-    private void threadFunc() {
-        Looper.prepare();
-        synchronized (this) {
-            mHandler = new Handler(Looper.myLooper());
-            notifyAll();
-        }
-        Looper.loop();
+    void quit() {
+        mHandlerThread.quitSafely();
     }
 
-    private static class TaskImpl implements Task, Runnable {
-        private AtomicReference<Runnable> mRunnable = new AtomicReference<>();
+    private static class TaskImpl implements Task {
+        private final Handler mHandler;
+        private final Object mToken;
 
-        TaskImpl(@NonNull Runnable runnable) {
-            mRunnable.set(runnable);
+        public TaskImpl(Handler handler, Object token) {
+            mHandler = handler;
+            mToken = token;
         }
 
         @Override
         public void cancel() {
-            mRunnable.set(null);
+            mHandler.removeCallbacksAndMessages(mToken);
         }
-
-        @Override
-        public void run() {
-            Runnable runnable = mRunnable.get();
-            if (runnable != null) {
-                runnable.run();
-            }
-        }
-    }
+    };
 }
diff --git a/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java b/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
index 1fb7cf5..421f7ce 100644
--- a/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
@@ -260,10 +260,11 @@
     private void suggestGnssTime(LocationTime locationTime) {
         logDebug("suggestGnssTime()");
 
-        long gnssTime = locationTime.getTime();
+        long gnssUnixEpochTimeMillis = locationTime.getUnixEpochTimeMillis();
         long elapsedRealtimeMs = locationTime.getElapsedRealtimeNanos() / 1_000_000L;
 
-        TimestampedValue<Long> timeSignal = new TimestampedValue<>(elapsedRealtimeMs, gnssTime);
+        TimestampedValue<Long> timeSignal =
+                new TimestampedValue<>(elapsedRealtimeMs, gnssUnixEpochTimeMillis);
         mLastSuggestedGnssTime = timeSignal;
 
         GnssTimeSuggestion timeSuggestion = new GnssTimeSuggestion(timeSignal);
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index e21feae..99950a0 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -93,6 +93,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 
@@ -254,6 +255,7 @@
             return;
         }
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
+            checkNewAgents();
             mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
             mReceiver.register(mContext);
             mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
@@ -262,7 +264,7 @@
             refreshAgentList(UserHandle.USER_ALL);
             refreshDeviceLockedForUser(UserHandle.USER_ALL);
         } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
-            maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
+            maybeEnableFactoryTrustAgents(UserHandle.USER_SYSTEM);
         }
     }
 
@@ -1083,7 +1085,7 @@
         return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
     }
 
-    private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
+    private void maybeEnableFactoryTrustAgents(int userId) {
         if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
             return;
@@ -1100,8 +1102,7 @@
         } else { // A default agent is not set; perform regular trust agent discovery
             for (ResolveInfo resolveInfo : resolveInfos) {
                 ComponentName componentName = getComponentName(resolveInfo);
-                int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
-                if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                if (!isSystemTrustAgent(resolveInfo)) {
                     Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
                             + "is not a system package.");
                     continue;
@@ -1110,13 +1111,88 @@
             }
         }
 
-        List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
-        discoveredAgents.addAll(previouslyEnabledAgents);
-        utils.setEnabledTrustAgents(discoveredAgents, userId);
+        enableNewAgents(discoveredAgents, userId);
         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
     }
 
+    private void checkNewAgents() {
+        for (UserInfo userInfo : mUserManager.getAliveUsers()) {
+            checkNewAgentsForUser(userInfo.id);
+        }
+    }
+
+    /**
+     * Checks for any new trust agents that become available after the first boot, add them to the
+     * list of known agents, and enable them if they should be enabled by default.
+     */
+    private void checkNewAgentsForUser(int userId) {
+        // When KNOWN_TRUST_AGENTS_INITIALIZED is not set, only update the known agent list but do
+        // not enable any agent.
+        // These agents will be enabled by #maybeEnableFactoryTrustAgents if this is the first time
+        // that this device boots and TRUST_AGENTS_INITIALIZED is not already set.
+        // Otherwise, these agents may have been manually disabled by the user, and we should not
+        // re-enable them.
+        if (0 == Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED, 0, userId)) {
+            initializeKnownAgents(userId);
+            return;
+        }
+
+        List<ComponentName> knownAgents = mLockPatternUtils.getKnownTrustAgents(userId);
+        List<ResolveInfo> agentInfoList = resolveAllowedTrustAgents(mContext.getPackageManager(),
+                userId);
+        ArraySet<ComponentName> newAgents = new ArraySet<>(agentInfoList.size());
+        ArraySet<ComponentName> newSystemAgents = new ArraySet<>(agentInfoList.size());
+
+        for (ResolveInfo agentInfo : agentInfoList) {
+            ComponentName agentComponentName = getComponentName(agentInfo);
+            if (knownAgents.contains(agentComponentName)) {
+                continue;
+            }
+            newAgents.add(agentComponentName);
+            if (isSystemTrustAgent(agentInfo)) {
+                newSystemAgents.add(agentComponentName);
+            }
+        }
+
+        if (newAgents.isEmpty()) {
+            return;
+        }
+
+        ArraySet<ComponentName> updatedKnowAgents = new ArraySet<>(knownAgents);
+        updatedKnowAgents.addAll(newAgents);
+        mLockPatternUtils.setKnownTrustAgents(updatedKnowAgents, userId);
+
+        // Do not auto enable new trust agents when the default agent is set
+        boolean hasDefaultAgent = getDefaultFactoryTrustAgent(mContext) != null;
+        if (!hasDefaultAgent) {
+            enableNewAgents(newSystemAgents, userId);
+        }
+    }
+
+    private void enableNewAgents(Collection<ComponentName> agents, int userId) {
+        if (agents.isEmpty()) {
+            return;
+        }
+
+        ArraySet<ComponentName> agentsToEnable = new ArraySet<>(agents);
+        agentsToEnable.addAll(mLockPatternUtils.getEnabledTrustAgents(userId));
+        mLockPatternUtils.setEnabledTrustAgents(agentsToEnable, userId);
+    }
+
+    private void initializeKnownAgents(int userId) {
+        List<ResolveInfo> agentInfoList = resolveAllowedTrustAgents(mContext.getPackageManager(),
+                userId);
+        ArraySet<ComponentName> agentComponentNames = new ArraySet<>(agentInfoList.size());
+        for (ResolveInfo agentInfo : agentInfoList) {
+            agentComponentNames.add(getComponentName(agentInfo));
+        }
+        mLockPatternUtils.setKnownTrustAgents(agentComponentNames, userId);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED, 1, userId);
+    }
+
     /**
      * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
      * is no trust agent set.
@@ -1152,6 +1228,10 @@
         return allowedAgents;
     }
 
+    private static boolean isSystemTrustAgent(ResolveInfo agentInfo) {
+        return (agentInfo.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+
     // Agent dispatch and aggregation
 
     private boolean aggregateIsTrusted(int userId) {
@@ -1825,7 +1905,13 @@
         }
 
         @Override
+        public void onPackageAdded(String packageName, int uid) {
+            checkNewAgentsForUser(UserHandle.getUserId(uid));
+        }
+
+        @Override
         public boolean onPackageChanged(String packageName, int uid, String[] components) {
+            checkNewAgentsForUser(UserHandle.getUserId(uid));
             // We're interested in all changes, even if just some components get enabled / disabled.
             return true;
         }
@@ -1860,7 +1946,7 @@
                     action)) {
                 int userId = getUserId(intent);
                 if (userId > 0) {
-                    maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
+                    maybeEnableFactoryTrustAgents(userId);
                 }
             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                 int userId = getUserId(intent);
diff --git a/services/core/java/com/android/server/utils/AlarmQueue.java b/services/core/java/com/android/server/utils/AlarmQueue.java
index 3f4def6..09ba195 100644
--- a/services/core/java/com/android/server/utils/AlarmQueue.java
+++ b/services/core/java/com/android/server/utils/AlarmQueue.java
@@ -34,6 +34,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.Comparator;
 import java.util.PriorityQueue;
 import java.util.function.Predicate;
 
@@ -52,14 +53,22 @@
     private static final boolean DEBUG = false;
 
     private static final long NOT_SCHEDULED = -1;
+    /**
+     * The threshold used to consider a new trigger time to be significantly different from the
+     * currently used trigger time.
+     */
+    private static final long SIGNIFICANT_TRIGGER_TIME_CHANGE_THRESHOLD_MS = MINUTE_IN_MILLIS;
 
     /**
      * Internal priority queue for each key's alarm, ordered by the time the alarm should go off.
      * The pair is the key and its associated alarm time (in the elapsed realtime timebase).
      */
     private static class AlarmPriorityQueue<Q> extends PriorityQueue<Pair<Q, Long>> {
+        private static final Comparator<Pair<?, Long>> sTimeComparator =
+                (o1, o2) -> Long.compare(o1.second, o2.second);
+
         AlarmPriorityQueue() {
-            super(1, (o1, o2) -> (int) (o1.second - o2.second));
+            super(1, sTimeComparator);
         }
 
         /**
@@ -306,8 +315,10 @@
         // earlier but not significantly so, then we essentially delay the check for some
         // apps by up to a minute.
         // 3. The alarm is after the current alarm.
+        final long timeShiftThresholdMs =
+                Math.min(SIGNIFICANT_TRIGGER_TIME_CHANGE_THRESHOLD_MS, mMinTimeBetweenAlarmsMs);
         if (mTriggerTimeElapsed == NOT_SCHEDULED
-                || nextTriggerTimeElapsed < mTriggerTimeElapsed - MINUTE_IN_MILLIS
+                || nextTriggerTimeElapsed < mTriggerTimeElapsed - timeShiftThresholdMs
                 || mTriggerTimeElapsed < nextTriggerTimeElapsed) {
             if (DEBUG) {
                 Slog.d(TAG, "Scheduling alarm at " + nextTriggerTimeElapsed
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index fcf0a90..6012993 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -224,8 +224,6 @@
 
     public void onSystemReady() {
         PowerManagerInternal pm = LocalServices.getService(PowerManagerInternal.class);
-        VirtualDeviceManagerInternal vdm = LocalServices.getService(
-                VirtualDeviceManagerInternal.class);
         AudioManager am = mContext.getSystemService(AudioManager.class);
         int ringerMode = am.getRingerModeInternal();
 
@@ -263,9 +261,11 @@
                     }
                 });
 
-        if (vdm != null){
-          vdm.registerVirtualDisplayListener(mVirtualDeviceListener);
-          vdm.registerAppsOnVirtualDeviceListener(mVirtualDeviceListener);
+        VirtualDeviceManagerInternal vdm = LocalServices.getService(
+                VirtualDeviceManagerInternal.class);
+        if (vdm != null) {
+            vdm.registerVirtualDisplayListener(mVirtualDeviceListener);
+            vdm.registerAppsOnVirtualDeviceListener(mVirtualDeviceListener);
         }
 
         registerSettingsChangeReceiver(USER_SWITCHED_INTENT_FILTER);
@@ -791,33 +791,35 @@
                 mAppsOnVirtualDevice.clear();
                 mAppsOnVirtualDevice.addAll(allRunningUids);
             }
-
-
         }
 
         /**
          * @param uid:       uid of the calling app.
          * @param displayId: the id of a Display.
          * @return Returns true if:
-         * 1) the displayId is valid, and it's owned by a virtual device
-         * 2) the displayId is invalid, and the calling app (uid) is running on a virtual device.
+         * <ul>
+         *   <li> the displayId is valid, and it's owned by a virtual device.</li>
+         *   <li> the displayId is invalid, and the calling app (uid) is running on a virtual
+         *        device.</li>
+         * </ul>
          */
         public boolean isAppOrDisplayOnAnyVirtualDevice(int uid, int displayId) {
+            if (displayId == Display.DEFAULT_DISPLAY) {
+                // The default display is the primary physical display on the phone.
+                return false;
+            }
+
             synchronized (mLock) {
-                switch (displayId) {
-                    case Display.DEFAULT_DISPLAY:
-                        // The default display is the primary physical display on the phone.
-                        return false;
-                    case Display.INVALID_DISPLAY:
-                        // There is no Display object associated with the Context of calling
-                        // {@link SystemVibratorManager}, checking the calling UID instead.
-                        return mAppsOnVirtualDevice.contains(uid);
-                    default:
-                        // Other valid display IDs representing valid logical displays will be
-                        // checked
-                        // against the active virtual displays set built with the registered
-                        // {@link VirtualDisplayListener}.
-                        return mVirtualDisplays.contains(displayId);
+                if (displayId == Display.INVALID_DISPLAY) {
+                    // There is no Display object associated with the Context of calling
+                    // {@link SystemVibratorManager}, checking the calling UID instead.
+                    return mAppsOnVirtualDevice.contains(uid);
+                } else {
+                    // Other valid display IDs representing valid logical displays will be
+                    // checked
+                    // against the active virtual displays set built with the registered
+                    // {@link VirtualDisplayListener}.
+                    return mVirtualDisplays.contains(displayId);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index f8cbd8b3d..7067ae4 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -197,10 +197,16 @@
      * launched successfully.
      */
     static final class LaunchingState {
-        /** The device uptime of {@link #notifyActivityLaunching}. */
-        private final long mCurrentUpTimeMs = SystemClock.uptimeMillis();
-        /** The timestamp of {@link #notifyActivityLaunching}. */
-        private long mCurrentTransitionStartTimeNs;
+        /**
+         * The device uptime of {@link #notifyActivityLaunching}. It can be used as a key for
+         * observer to identify which callbacks belong to a launch event.
+         */
+        final long mStartUptimeNs = SystemClock.uptimeNanos();
+        /**
+         * The timestamp of {@link #notifyActivityLaunching}. It is used to provide the time
+         * relative to the wall-time.
+         */
+        final long mStartRealtimeNs = SystemClock.elapsedRealtimeNanos();
         /** Non-null when a {@link TransitionInfo} is created for this state. */
         private TransitionInfo mAssociatedTransitionInfo;
         /** The sequence id for trace. It is used to map the traces before resolving intent. */
@@ -263,13 +269,7 @@
          * @see LaunchingState#mAssociatedTransitionInfo
          */
         final LaunchingState mLaunchingState;
-        /**
-         * The timestamp of the first {@link #notifyActivityLaunching}. It can be used as a key for
-         * observer to identify which callbacks belong to a launch event.
-         */
-        final long mTransitionStartTimeNs;
-        /** The device uptime in millis when this transition info is created. */
-        final long mTransitionDeviceUptimeMs;
+
         /** The type can be cold (new process), warm (new activity), or hot (bring to front). */
         final int mTransitionType;
         /** Whether the process was already running when the transition started. */
@@ -289,11 +289,11 @@
         @SourceInfo.SourceType int mSourceType;
         /** The time from the source event (e.g. touch) to {@link #notifyActivityLaunching}. */
         int mSourceEventDelayMs = INVALID_DELAY;
-        /** The time from {@link #mTransitionStartTimeNs} to {@link #notifyTransitionStarting}. */
+        /** The time from {@link #notifyActivityLaunching} to {@link #notifyTransitionStarting}. */
         int mCurrentTransitionDelayMs;
-        /** The time from {@link #mTransitionStartTimeNs} to {@link #notifyStartingWindowDrawn}. */
+        /** The time from {@link #notifyActivityLaunching} to {@link #notifyStartingWindowDrawn}. */
         int mStartingWindowDelayMs = INVALID_DELAY;
-        /** The time from {@link #mTransitionStartTimeNs} to {@link #notifyBindApplication}. */
+        /** The time from {@link #notifyActivityLaunching} to {@link #notifyBindApplication}. */
         int mBindApplicationDelayMs = INVALID_DELAY;
         /** Elapsed time from when we launch an activity to when its windows are drawn. */
         int mWindowsDrawnDelayMs;
@@ -339,13 +339,11 @@
                 ActivityOptions options, int transitionType, boolean processRunning,
                 boolean processSwitch, int processState, int processOomAdj) {
             mLaunchingState = launchingState;
-            mTransitionStartTimeNs = launchingState.mCurrentTransitionStartTimeNs;
             mTransitionType = transitionType;
             mProcessRunning = processRunning;
             mProcessSwitch = processSwitch;
             mProcessState = processState;
             mProcessOomAdj = processOomAdj;
-            mTransitionDeviceUptimeMs = launchingState.mCurrentUpTimeMs;
             setLatestLaunchedActivity(r);
             // The launching state can be reused by consecutive launch. Its original association
             // shouldn't be changed by a separated transition.
@@ -356,8 +354,8 @@
                 final SourceInfo sourceInfo = options.getSourceInfo();
                 if (sourceInfo != null) {
                     mSourceType = sourceInfo.type;
-                    mSourceEventDelayMs =
-                            (int) (launchingState.mCurrentUpTimeMs - sourceInfo.eventTimeMs);
+                    mSourceEventDelayMs = (int) (TimeUnit.NANOSECONDS.toMillis(
+                            launchingState.mStartUptimeNs) - sourceInfo.eventTimeMs);
                 }
             }
         }
@@ -403,12 +401,13 @@
         }
 
         int calculateCurrentDelay() {
-            return calculateDelay(SystemClock.elapsedRealtimeNanos());
+            return calculateDelay(SystemClock.uptimeNanos());
         }
 
         int calculateDelay(long timestampNs) {
             // Shouldn't take more than 25 days to launch an app, so int is fine here.
-            return (int) TimeUnit.NANOSECONDS.toMillis(timestampNs - mTransitionStartTimeNs);
+            return (int) TimeUnit.NANOSECONDS.toMillis(
+                    timestampNs - mLaunchingState.mStartUptimeNs);
         }
 
         @Override
@@ -583,7 +582,6 @@
      */
     LaunchingState notifyActivityLaunching(Intent intent, @Nullable ActivityRecord caller,
             int callingUid) {
-        final long transitionStartTimeNs = SystemClock.elapsedRealtimeNanos();
         TransitionInfo existingInfo = null;
         if (callingUid != IGNORE_CALLER) {
             // Associate the launching event to an active transition if the caller is found in its
@@ -608,12 +606,10 @@
 
         if (existingInfo == null) {
             final LaunchingState launchingState = new LaunchingState();
-            launchingState.mCurrentTransitionStartTimeNs = transitionStartTimeNs;
             // Only notify the observer for a new launching event.
-            launchObserverNotifyIntentStarted(intent, transitionStartTimeNs);
+            launchObserverNotifyIntentStarted(intent, launchingState.mStartUptimeNs);
             return launchingState;
         }
-        existingInfo.mLaunchingState.mCurrentTransitionStartTimeNs = transitionStartTimeNs;
         return existingInfo.mLaunchingState;
     }
 
@@ -716,7 +712,7 @@
             launchObserverNotifyActivityLaunched(newInfo);
         } else {
             // As abort for no process switch.
-            launchObserverNotifyIntentFailed(newInfo.mTransitionStartTimeNs);
+            launchObserverNotifyIntentFailed(newInfo.mLaunchingState.mStartUptimeNs);
         }
         scheduleCheckActivityToBeDrawnIfSleeping(launchedActivity);
 
@@ -749,9 +745,10 @@
      *         to invisible (removed from active transition) or it was already drawn.
      */
     @Nullable
-    TransitionInfoSnapshot notifyWindowsDrawn(@NonNull ActivityRecord r, long timestampNs) {
+    TransitionInfoSnapshot notifyWindowsDrawn(@NonNull ActivityRecord r) {
         if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn " + r);
 
+        final long timestampNs = SystemClock.uptimeNanos();
         final TransitionInfo info = getActiveTransitionInfo(r);
         if (info == null || info.mIsDrawn) {
             if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn not pending drawn " + info);
@@ -778,7 +775,7 @@
         }
         if (DEBUG_METRICS) Slog.i(TAG, "notifyStartingWindowDrawn " + r);
         info.mLoggedStartingWindowDrawn = true;
-        info.mStartingWindowDelayMs = info.calculateDelay(SystemClock.elapsedRealtimeNanos());
+        info.mStartingWindowDelayMs = info.calculateCurrentDelay();
     }
 
     /**
@@ -790,7 +787,7 @@
     void notifyTransitionStarting(ArrayMap<WindowContainer, Integer> activityToReason) {
         if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting " + activityToReason);
 
-        final long timestampNs = SystemClock.elapsedRealtimeNanos();
+        final long timestampNs = SystemClock.uptimeNanos();
         for (int index = activityToReason.size() - 1; index >= 0; index--) {
             final WindowContainer<?> wc = activityToReason.keyAt(index);
             final ActivityRecord activity = wc.asActivityRecord();
@@ -948,7 +945,7 @@
         }
         if (DEBUG_METRICS) Slog.i(TAG, "abort launch cause=" + cause);
         state.stopTrace(true /* abort */, null /* endInfo */);
-        launchObserverNotifyIntentFailed(state.mCurrentTransitionStartTimeNs);
+        launchObserverNotifyIntentFailed(state.mStartUptimeNs);
     }
 
     /** Aborts tracking of current launch metrics. */
@@ -1013,13 +1010,13 @@
         // This will avoid any races with other operations that modify the ActivityRecord.
         final TransitionInfoSnapshot infoSnapshot = new TransitionInfoSnapshot(info);
         if (info.isInterestingToLoggerAndObserver()) {
-            final long timestamp = info.mTransitionStartTimeNs;
-            final long uptime = info.mTransitionDeviceUptimeMs;
+            final long timestampNs = info.mLaunchingState.mStartRealtimeNs;
+            final long uptimeNs = info.mLaunchingState.mStartUptimeNs;
             final int transitionDelay = info.mCurrentTransitionDelayMs;
             final int processState = info.mProcessState;
             final int processOomAdj = info.mProcessOomAdj;
             mLoggerHandler.post(() -> logAppTransition(
-                    timestamp, uptime, transitionDelay, infoSnapshot, isHibernating,
+                    timestampNs, uptimeNs, transitionDelay, infoSnapshot, isHibernating,
                     processState, processOomAdj));
         }
         mLoggerHandler.post(() -> logAppDisplayed(infoSnapshot));
@@ -1031,7 +1028,7 @@
     }
 
     // This gets called on another thread without holding the activity manager lock.
-    private void logAppTransition(long transitionStartTimeNs, long transitionDeviceUptimeMs,
+    private void logAppTransition(long transitionStartTimeNs, long transitionDeviceUptimeNs,
             int currentTransitionDelayMs, TransitionInfoSnapshot info, boolean isHibernating,
             int processState, int processOomAdj) {
         final LogMaker builder = new LogMaker(APP_TRANSITION);
@@ -1049,7 +1046,7 @@
         }
         builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
         builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
-                TimeUnit.MILLISECONDS.toSeconds(transitionDeviceUptimeMs));
+                TimeUnit.NANOSECONDS.toSeconds(transitionDeviceUptimeNs));
         builder.addTaggedData(APP_TRANSITION_DELAY_MS, currentTransitionDelayMs);
         builder.setSubtype(info.reason);
         if (info.startingWindowDelayMs != INVALID_DELAY) {
@@ -1188,10 +1185,11 @@
             return null;
         }
 
-        final long currentTimestampNs = SystemClock.elapsedRealtimeNanos();
+        final long currentTimestampNs = SystemClock.uptimeNanos();
         final long startupTimeMs = info.mPendingFullyDrawn != null
                 ? info.mWindowsDrawnDelayMs
-                : TimeUnit.NANOSECONDS.toMillis(currentTimestampNs - info.mTransitionStartTimeNs);
+                : TimeUnit.NANOSECONDS.toMillis(
+                        currentTimestampNs - info.mLaunchingState.mStartUptimeNs);
         final TransitionInfoSnapshot infoSnapshot =
                 new TransitionInfoSnapshot(info, r, (int) startupTimeMs);
         mLoggerHandler.post(() -> logAppFullyDrawn(infoSnapshot));
@@ -1603,7 +1601,7 @@
         }
         info.mLaunchTraceName = "launching: " + info.mLastLaunchedActivity.packageName;
         Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, info.mLaunchTraceName,
-                (int) info.mTransitionStartTimeNs /* cookie */);
+                (int) info.mLaunchingState.mStartRealtimeNs /* cookie */);
     }
 
     /** Stops trace for the launch is completed or cancelled. */
@@ -1613,7 +1611,7 @@
             return;
         }
         Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, info.mLaunchTraceName,
-                (int) info.mTransitionStartTimeNs /* cookie */);
+                (int) info.mLaunchingState.mStartRealtimeNs /* cookie */);
         info.mLaunchTraceName = null;
     }
 
@@ -1658,7 +1656,7 @@
                 convertTransitionTypeToLaunchObserverTemperature(info.mTransitionType);
 
         // Beginning a launch is timing sensitive and so should be observed as soon as possible.
-        mLaunchObserver.onActivityLaunched(info.mTransitionStartTimeNs,
+        mLaunchObserver.onActivityLaunched(info.mLaunchingState.mStartUptimeNs,
                 info.mLastLaunchedActivity.mActivityComponent, temperature);
 
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -1670,7 +1668,7 @@
     private void launchObserverNotifyReportFullyDrawn(TransitionInfo info, long timestampNs) {
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
             "MetricsLogger:launchObserverNotifyReportFullyDrawn");
-        mLaunchObserver.onReportFullyDrawn(info.mTransitionStartTimeNs, timestampNs);
+        mLaunchObserver.onReportFullyDrawn(info.mLaunchingState.mStartUptimeNs, timestampNs);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
@@ -1682,7 +1680,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                 "MetricsLogger:launchObserverNotifyActivityLaunchCancelled");
 
-        mLaunchObserver.onActivityLaunchCancelled(info.mTransitionStartTimeNs);
+        mLaunchObserver.onActivityLaunchCancelled(info.mLaunchingState.mStartUptimeNs);
 
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
@@ -1695,7 +1693,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                 "MetricsLogger:launchObserverNotifyActivityLaunchFinished");
 
-        mLaunchObserver.onActivityLaunchFinished(info.mTransitionStartTimeNs,
+        mLaunchObserver.onActivityLaunchFinished(info.mLaunchingState.mStartUptimeNs,
                 info.mLastLaunchedActivity.mActivityComponent, timestampNs);
 
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 1c583be..98d3adc 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2755,6 +2755,7 @@
         }
 
         final StartingSurfaceController.StartingSurface surface;
+        final WindowState startingWindow = mStartingWindow;
         final boolean animate;
         if (mStartingData != null) {
             animate = prepareAnimation && mStartingData.needRevealAnimation()
@@ -2779,7 +2780,19 @@
             return;
         }
 
-        surface.remove(animate);
+        if (animate && mTransitionController.inCollectingTransition(startingWindow)
+                && startingWindow.cancelAndRedraw()) {
+            // Defer remove starting window after transition start.
+            // If splash screen window was in collecting, the client side is unable to draw because
+            // of Session#cancelDraw, which will blocking the remove animation.
+            startingWindow.mSyncTransaction.addTransactionCommittedListener(Runnable::run, () -> {
+                synchronized (mAtmService.mGlobalLock) {
+                    surface.remove(true);
+                }
+            });
+        } else {
+            surface.remove(animate);
+        }
     }
 
     /**
@@ -6536,9 +6549,9 @@
     }
 
     /** Called when the windows associated app window container are drawn. */
-    private void onWindowsDrawn(long timestampNs) {
+    private void onWindowsDrawn() {
         final TransitionInfoSnapshot info = mTaskSupervisor
-                .getActivityMetricsLogger().notifyWindowsDrawn(this, timestampNs);
+                .getActivityMetricsLogger().notifyWindowsDrawn(this);
         final boolean validInfo = info != null;
         final int windowsDrawnDelayMs = validInfo ? info.windowsDrawnDelayMs : INVALID_DELAY;
         final @WaitResult.LaunchState int launchState =
@@ -6665,7 +6678,7 @@
                 + numInteresting + " visible=" + numVisible);
         if (nowDrawn != mReportedDrawn) {
             if (nowDrawn) {
-                onWindowsDrawn(SystemClock.elapsedRealtimeNanos());
+                onWindowsDrawn();
             }
             mReportedDrawn = nowDrawn;
         }
@@ -6776,27 +6789,37 @@
      * @return True if input dispatching should be aborted.
      */
     public boolean inputDispatchingTimedOut(TimeoutRecord timeoutRecord, int windowPid) {
-        ActivityRecord anrActivity;
-        WindowProcessController anrApp;
-        boolean blameActivityProcess;
-        synchronized (mAtmService.mGlobalLock) {
-            anrActivity = getWaitingHistoryRecordLocked();
-            anrApp = app;
-            blameActivityProcess =  hasProcess()
-                    && (app.getPid() == windowPid || windowPid == INVALID_PID);
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    "ActivityRecord#inputDispatchingTimedOut()");
+            ActivityRecord anrActivity;
+            WindowProcessController anrApp;
+            boolean blameActivityProcess;
+            timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
+            synchronized (mAtmService.mGlobalLock) {
+                timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
+                anrActivity = getWaitingHistoryRecordLocked();
+                anrApp = app;
+                blameActivityProcess =  hasProcess()
+                        && (app.getPid() == windowPid || windowPid == INVALID_PID);
+            }
+
+            if (blameActivityProcess) {
+                return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
+                        anrActivity.shortComponentName, anrActivity.info.applicationInfo,
+                        shortComponentName, app, false, timeoutRecord);
+            } else {
+                // In this case another process added windows using this activity token.
+                // So, we call the generic service input dispatch timed out method so
+                // that the right process is blamed.
+                long timeoutMillis = mAtmService.mAmInternal.inputDispatchingTimedOut(
+                        windowPid, false /* aboveSystem */, timeoutRecord);
+                return timeoutMillis <= 0;
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
 
-        if (blameActivityProcess) {
-            return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
-                    anrActivity.shortComponentName, anrActivity.info.applicationInfo,
-                    shortComponentName, app, false, timeoutRecord);
-        } else {
-            // In this case another process added windows using this activity token. So, we call the
-            // generic service input dispatch timed out method so that the right process is blamed.
-            long timeoutMillis = mAtmService.mAmInternal.inputDispatchingTimedOut(
-                    windowPid, false /* aboveSystem */, timeoutRecord);
-            return timeoutMillis <= 0;
-        }
     }
 
     private ActivityRecord getWaitingHistoryRecordLocked() {
@@ -8033,11 +8056,7 @@
         // Horizontal position
         int offsetX = 0;
         if (parentBounds.width() != screenResolvedBounds.width()) {
-            if (screenResolvedBounds.width() >= parentAppBounds.width()) {
-                // If resolved bounds overlap with insets, center within app bounds.
-                offsetX = getCenterOffset(
-                        parentAppBounds.width(), screenResolvedBounds.width());
-            } else {
+            if (screenResolvedBounds.width() <= parentAppBounds.width()) {
                 float positionMultiplier =
                         mLetterboxUiController.getHorizontalPositionMultiplier(
                                 newParentConfiguration);
@@ -8049,11 +8068,7 @@
         // Vertical position
         int offsetY = 0;
         if (parentBounds.height() != screenResolvedBounds.height()) {
-            if (screenResolvedBounds.height() >= parentAppBounds.height()) {
-                // If resolved bounds overlap with insets, center within app bounds.
-                offsetY = getCenterOffset(
-                        parentAppBounds.height(), screenResolvedBounds.height());
-            } else {
+            if (screenResolvedBounds.height() <= parentAppBounds.height()) {
                 float positionMultiplier =
                         mLetterboxUiController.getVerticalPositionMultiplier(
                                 newParentConfiguration);
@@ -8071,6 +8086,15 @@
             offsetBounds(resolvedConfig, offsetX, offsetY);
         }
 
+        // If the top is aligned with parentAppBounds add the vertical insets back so that the app
+        // content aligns with the status bar
+        if (resolvedConfig.windowConfiguration.getAppBounds().top == parentAppBounds.top) {
+            resolvedConfig.windowConfiguration.getBounds().top = parentBounds.top;
+            if (mSizeCompatBounds != null) {
+                mSizeCompatBounds.top = parentBounds.top;
+            }
+        }
+
         // Since bounds has changed, the configuration needs to be computed accordingly.
         getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration);
     }
@@ -8448,7 +8472,7 @@
         // Above coordinates are in "@" space, now place "*" and "#" to screen space.
         final boolean fillContainer = resolvedBounds.equals(containingBounds);
         final int screenPosX = fillContainer ? containerBounds.left : containerAppBounds.left;
-        final int screenPosY  = fillContainer ? containerBounds.top : containerAppBounds.top;
+        final int screenPosY = fillContainer ? containerBounds.top : containerAppBounds.top;
 
         if (screenPosX != 0 || screenPosY != 0) {
             if (mSizeCompatBounds != null) {
@@ -8794,24 +8818,22 @@
         // Also account for the insets (e.g. display cutouts, navigation bar), which will be
         // clipped away later in {@link Task#computeConfigResourceOverrides()}, i.e., the out
         // bounds are the app bounds restricted by aspect ratio + clippable insets. Otherwise,
-        // the app bounds would end up too small.
+        // the app bounds would end up too small. To achieve this we will also add clippable insets
+        // when the corresponding dimension fully fills the parent
+
         int right = activityWidth + containingAppBounds.left;
+        int left = containingAppBounds.left;
         if (right >= containingAppBounds.right) {
-            right += containingBounds.right - containingAppBounds.right;
+            right = containingBounds.right;
+            left = containingBounds.left;
         }
         int bottom = activityHeight + containingAppBounds.top;
+        int top = containingAppBounds.top;
         if (bottom >= containingAppBounds.bottom) {
-            bottom += containingBounds.bottom - containingAppBounds.bottom;
+            bottom = containingBounds.bottom;
+            top = containingBounds.top;
         }
-        outBounds.set(containingBounds.left, containingBounds.top, right, bottom);
-
-        // If the bounds are restricted by fixed aspect ratio, then out bounds should be put in the
-        // container app bounds. Otherwise the entire container bounds are available.
-        if (!outBounds.equals(containingBounds)) {
-            // The horizontal position should not cover insets (e.g. display cutout).
-            outBounds.left = containingAppBounds.left;
-        }
-
+        outBounds.set(left, top, right, bottom);
         return true;
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 8f5d838..e1f40a8 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -5296,7 +5296,7 @@
             if (app != null && app.getPid() > 0) {
                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
                 firstPids.add(app.getPid());
-                dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null);
+                dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null, null);
             }
 
             File lastTracesFile = null;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index dc91c15..28cd001 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -744,7 +744,7 @@
             // (e.g. AMS.startActivityAsUser).
             final long token = Binder.clearCallingIdentity();
             try {
-                return mService.getPackageManagerInternalLocked().resolveIntent(
+                return mService.getPackageManagerInternalLocked().resolveIntentExported(
                         intent, resolvedType, modifiedFlags, privateResolveFlags, userId, true,
                         filterCallingUid);
             } finally {
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 01098de..df72260 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -27,6 +27,7 @@
 import android.os.IBinder;
 import android.os.Process;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -64,47 +65,55 @@
 
     void notifyAppUnresponsive(InputApplicationHandle applicationHandle,
             TimeoutRecord timeoutRecord) {
-        preDumpIfLockTooSlow();
-        final ActivityRecord activity;
-        synchronized (mService.mGlobalLock) {
-            activity = ActivityRecord.forTokenLocked(applicationHandle.token);
-            if (activity == null) {
-                Slog.e(TAG_WM, "Unknown app appToken:" + applicationHandle.name
-                        + ". Dropping notifyNoFocusedWindowAnr request");
-                return;
-            }
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyAppUnresponsive()");
+            preDumpIfLockTooSlow();
+            final ActivityRecord activity;
+            timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
+            synchronized (mService.mGlobalLock) {
+                timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
+                activity = ActivityRecord.forTokenLocked(applicationHandle.token);
+                if (activity == null) {
+                    Slog.e(TAG_WM, "Unknown app appToken:" + applicationHandle.name
+                            + ". Dropping notifyNoFocusedWindowAnr request");
+                    return;
+                }
 
-            // App is unresponsive, but we are actively trying to give focus to a window.
-            // Blame the window if possible since the window may not belong to the app.
-            DisplayContent display = mService.mRoot.getDisplayContent(activity.getDisplayId());
-            IBinder focusToken = display == null ? null : display.getInputMonitor().mInputFocus;
-            InputTarget focusTarget = mService.getInputTargetFromToken(focusToken);
+                // App is unresponsive, but we are actively trying to give focus to a window.
+                // Blame the window if possible since the window may not belong to the app.
+                DisplayContent display = mService.mRoot.getDisplayContent(activity.getDisplayId());
+                IBinder focusToken =
+                        display == null ? null : display.getInputMonitor().mInputFocus;
+                InputTarget focusTarget = mService.getInputTargetFromToken(focusToken);
 
-            if (focusTarget != null) {
-                // Check if we have a recent focus request, newer than the dispatch timeout, then
-                // ignore the focus request.
-                WindowState targetWindowState = focusTarget.getWindowState();
-                boolean requestIsValid = SystemClock.uptimeMillis()
-                        - display.getInputMonitor().mInputFocusRequestTimeMillis
-                        >= getInputDispatchingTimeoutMillisLocked(
-                                targetWindowState.getActivityRecord());
+                if (focusTarget != null) {
+                    // Check if we have a recent focus request, newer than the dispatch timeout,
+                    // then ignore the focus request.
+                    WindowState targetWindowState = focusTarget.getWindowState();
+                    boolean requestIsValid = SystemClock.uptimeMillis()
+                            - display.getInputMonitor().mInputFocusRequestTimeMillis
+                            >= getInputDispatchingTimeoutMillisLocked(
+                                    targetWindowState.getActivityRecord());
 
-                if (requestIsValid) {
-                    if (notifyWindowUnresponsive(focusToken, timeoutRecord)) {
-                        Slog.i(TAG_WM, "Blamed " + focusTarget.getWindowState().getName()
-                                + " using pending focus request. Focused activity: "
-                                + activity.getName());
-                        return;
+                    if (requestIsValid) {
+                        if (notifyWindowUnresponsive(focusToken, timeoutRecord)) {
+                            Slog.i(TAG_WM, "Blamed " + focusTarget.getWindowState().getName()
+                                    + " using pending focus request. Focused activity: "
+                                    + activity.getName());
+                            return;
+                        }
                     }
                 }
+
+                Slog.i(TAG_WM, "ANR in " + activity.getName() + ".  Reason: "
+                        + timeoutRecord.mReason);
+                dumpAnrStateLocked(activity, null /* windowState */, timeoutRecord.mReason);
+                mUnresponsiveAppByDisplay.put(activity.getDisplayId(), activity);
             }
-
-
-            Slog.i(TAG_WM, "ANR in " + activity.getName() + ".  Reason: " + timeoutRecord.mReason);
-            dumpAnrStateLocked(activity, null /* windowState */, timeoutRecord.mReason);
-            mUnresponsiveAppByDisplay.put(activity.getDisplayId(), activity);
+            activity.inputDispatchingTimedOut(timeoutRecord, INVALID_PID);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
-        activity.inputDispatchingTimedOut(timeoutRecord, INVALID_PID);
     }
 
 
@@ -117,14 +126,20 @@
      */
     void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid,
             @NonNull TimeoutRecord timeoutRecord) {
-        if (notifyWindowUnresponsive(token, timeoutRecord)) {
-            return;
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyWindowUnresponsive()");
+            if (notifyWindowUnresponsive(token, timeoutRecord)) {
+                return;
+            }
+            if (!pid.isPresent()) {
+                Slog.w(TAG_WM, "Failed to notify that window token=" + token
+                        + " was unresponsive.");
+                return;
+            }
+            notifyWindowUnresponsive(pid.getAsInt(), timeoutRecord);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
-        if (!pid.isPresent()) {
-            Slog.w(TAG_WM, "Failed to notify that window token=" + token + " was unresponsive.");
-            return;
-        }
-        notifyWindowUnresponsive(pid.getAsInt(), timeoutRecord);
     }
 
     /**
@@ -139,7 +154,9 @@
         final int pid;
         final boolean aboveSystem;
         final ActivityRecord activity;
+        timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
         synchronized (mService.mGlobalLock) {
+            timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
             InputTarget target = mService.getInputTargetFromToken(inputToken);
             if (target == null) {
                 return false;
@@ -168,7 +185,9 @@
     private void notifyWindowUnresponsive(int pid, TimeoutRecord timeoutRecord) {
         Slog.i(TAG_WM,
                 "ANR in input window owned by pid=" + pid + ". Reason: " + timeoutRecord.mReason);
+        timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
         synchronized (mService.mGlobalLock) {
+            timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
             dumpAnrStateLocked(null /* activity */, null /* windowState */, timeoutRecord.mReason);
         }
 
@@ -254,68 +273,83 @@
         if (mLastPreDumpTimeMs > 0 && now - mLastPreDumpTimeMs < PRE_DUMP_MIN_INTERVAL_MS) {
             return;
         }
-
-        final boolean[] shouldDumpSf = { true };
-        final ArrayMap<String, Runnable> monitors = new ArrayMap<>(2);
-        monitors.put(TAG_WM, mService::monitor);
-        monitors.put("ActivityManager", mService.mAmInternal::monitor);
-        final CountDownLatch latch = new CountDownLatch(monitors.size());
-        // The pre-dump will execute if one of the monitors doesn't complete within the timeout.
-        for (int i = 0; i < monitors.size(); i++) {
-            final String name = monitors.keyAt(i);
-            final Runnable monitor = monitors.valueAt(i);
-            // Always create new thread to avoid noise of existing threads. Suppose here won't
-            // create too many threads because it means that watchdog will be triggered first.
-            new Thread() {
-                @Override
-                public void run() {
-                    monitor.run();
-                    latch.countDown();
-                    final long elapsed = SystemClock.uptimeMillis() - now;
-                    if (elapsed > PRE_DUMP_MONITOR_TIMEOUT_MS) {
-                        Slog.i(TAG_WM, "Pre-dump acquired " + name + " in " + elapsed + "ms");
-                    } else if (TAG_WM.equals(name)) {
-                        // Window manager is the main client of SurfaceFlinger. If window manager
-                        // is responsive, the stack traces of SurfaceFlinger may not be important.
-                        shouldDumpSf[0] = false;
-                    }
-                };
-            }.start();
-        }
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "preDumpIfLockTooSlow()");
         try {
-            if (latch.await(PRE_DUMP_MONITOR_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
-                return;
+            final boolean[] shouldDumpSf = { true };
+            final ArrayMap<String, Runnable> monitors = new ArrayMap<>(2);
+            monitors.put(TAG_WM, mService::monitor);
+            monitors.put("ActivityManager", mService.mAmInternal::monitor);
+            final CountDownLatch latch = new CountDownLatch(monitors.size());
+            // The pre-dump will execute if one of the monitors doesn't complete within
+            // the timeout.
+            for (int i = 0; i < monitors.size(); i++) {
+                final String name = monitors.keyAt(i);
+                final Runnable monitor = monitors.valueAt(i);
+                // Always create new thread to avoid noise of existing threads. Suppose here won't
+                // create too many threads because it means that watchdog will be triggered first.
+                new Thread() {
+                    @Override
+                    public void run() {
+                        monitor.run();
+                        latch.countDown();
+                        final long elapsed = SystemClock.uptimeMillis() - now;
+                        if (elapsed > PRE_DUMP_MONITOR_TIMEOUT_MS) {
+                            Slog.i(TAG_WM, "Pre-dump acquired " + name + " in " + elapsed + "ms");
+                        } else if (TAG_WM.equals(name)) {
+                            // Window manager is the main client of SurfaceFlinger.
+                            // If window manager is responsive, the stack traces
+                            // of SurfaceFlinger may not be important.
+                            shouldDumpSf[0] = false;
+                        }
+                    };
+                }.start();
             }
-        } catch (InterruptedException ignored) { }
-        mLastPreDumpTimeMs = now;
-        Slog.i(TAG_WM, "Pre-dump for unresponsive");
+            try {
+                if (latch.await(PRE_DUMP_MONITOR_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+                    return;
+                }
+            } catch (InterruptedException ignored) { }
+            mLastPreDumpTimeMs = now;
+            Slog.i(TAG_WM, "Pre-dump for unresponsive");
 
-        final ArrayList<Integer> firstPids = new ArrayList<>(1);
-        firstPids.add(WindowManagerService.MY_PID);
-        ArrayList<Integer> nativePids = null;
-        final int[] pids = shouldDumpSf[0]
-                ? Process.getPidsForCommands(new String[] { "/system/bin/surfaceflinger" })
-                : null;
-        if (pids != null) {
-            nativePids = new ArrayList<>(1);
-            for (int pid : pids) {
-                nativePids.add(pid);
+            final ArrayList<Integer> firstPids = new ArrayList<>(1);
+            firstPids.add(WindowManagerService.MY_PID);
+            ArrayList<Integer> nativePids = null;
+            final int[] pids = shouldDumpSf[0]
+                    ? Process.getPidsForCommands(new String[] { "/system/bin/surfaceflinger" })
+                    : null;
+            if (pids != null) {
+                nativePids = new ArrayList<>(1);
+                for (int pid : pids) {
+                    nativePids.add(pid);
+                }
             }
+
+            String criticalEvents =
+                    CriticalEventLog.getInstance().logLinesForSystemServerTraceFile();
+            final File tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
+                    null /* processCpuTracker */, null /* lastPids */, nativePids,
+                    null /* logExceptionCreatingFile */, "Pre-dump", criticalEvents,
+                    null/* AnrLatencyTracker */);
+            if (tracesFile != null) {
+                tracesFile.renameTo(
+                        new File(tracesFile.getParent(), tracesFile.getName() + "_pre"));
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
 
-        String criticalEvents = CriticalEventLog.getInstance().logLinesForSystemServerTraceFile();
-        final File tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
-                null /* processCpuTracker */, null /* lastPids */, nativePids,
-                null /* logExceptionCreatingFile */, "Pre-dump", criticalEvents);
-        if (tracesFile != null) {
-            tracesFile.renameTo(new File(tracesFile.getParent(), tracesFile.getName() + "_pre"));
-        }
     }
 
     private void dumpAnrStateLocked(ActivityRecord activity, WindowState windowState,
                                     String reason) {
-        mService.saveANRStateLocked(activity, windowState, reason);
-        mService.mAtmService.saveANRState(reason);
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "dumpAnrStateLocked()");
+            mService.saveANRStateLocked(activity, windowState, reason);
+            mService.mAtmService.saveANRState(reason);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
     }
 
     private boolean isWindowAboveSystem(@NonNull WindowState windowState) {
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 7e62c61..2ea6a3f 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -467,16 +467,6 @@
             return TRANSIT_OLD_WALLPAPER_OPEN;
         }
 
-        // Some devices don't show a wallpaper. In that case we should still trigger wallpaper
-        // transitions when animating to/from the home activity
-        if (wallpaperTarget == null) {
-            if (topOpeningApp != null && topOpeningApp.isActivityTypeHome()) {
-                return TRANSIT_OLD_WALLPAPER_OPEN;
-            } else if (topClosingApp != null && topClosingApp.isActivityTypeHome()) {
-                return TRANSIT_OLD_WALLPAPER_CLOSE;
-            }
-        }
-
         final ArraySet<WindowContainer> openingWcs = getAnimationTargets(
                 openingApps, closingApps, true /* visible */);
         final ArraySet<WindowContainer> closingWcs = getAnimationTargets(
@@ -488,6 +478,11 @@
         @TransitContainerType int openingType = getTransitContainerType(openingContainer);
         @TransitContainerType int closingType = getTransitContainerType(closingContainer);
         if (appTransition.containsTransitRequest(TRANSIT_TO_FRONT) && openingType == TYPE_TASK) {
+            if (topOpeningApp != null && topOpeningApp.isActivityTypeHome()) {
+                // If we are opening the home task, we want to play an animation as if
+                // the task on top is being brought to back.
+                return TRANSIT_OLD_TASK_TO_BACK;
+            }
             return TRANSIT_OLD_TASK_TO_FRONT;
         }
         if (appTransition.containsTransitRequest(TRANSIT_TO_BACK) && closingType == TYPE_TASK) {
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 219092b..1266db5 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -357,7 +357,12 @@
      * or seamless transformation in a rotated display.
      */
     boolean shouldFreezeInsetsPosition(WindowState w) {
-        return mTransitionOp != OP_LEGACY && w.mTransitionController.inTransition()
+        if (TransitionController.SYNC_METHOD != BLASTSyncEngine.METHOD_BLAST) {
+            // Expect a screenshot layer has covered the screen, so it is fine to let client side
+            // insets animation runner update the position directly.
+            return false;
+        }
+        return mTransitionOp != OP_LEGACY && !mIsStartTransactionCommitted
                 && isTargetToken(w.mToken);
     }
 
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index d9ab971..a3f5401 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -36,6 +36,7 @@
 import android.view.SurfaceControl;
 import android.window.BackNavigationInfo;
 import android.window.OnBackInvokedCallbackInfo;
+import android.window.ScreenCapture;
 import android.window.TaskSnapshot;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -422,7 +423,7 @@
             ComponentName activityComponent) {
         // Check if we have a screenshot of the previous activity, indexed by its
         // component name.
-        SurfaceControl.ScreenshotHardwareBuffer backBuffer = task.mBackScreenshots
+        ScreenCapture.ScreenshotHardwareBuffer backBuffer = task.mBackScreenshots
                 .get(activityComponent.flattenToString());
         return backBuffer != null ? backBuffer.getHardwareBuffer() : null;
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 690c94a..2809307 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -231,6 +231,7 @@
 import android.view.WindowManagerPolicyConstants.PointerEventListener;
 import android.window.DisplayWindowPolicyController;
 import android.window.IDisplayAreaOrganizer;
+import android.window.ScreenCapture;
 import android.window.TransitionRequestInfo;
 
 import com.android.internal.R;
@@ -4234,7 +4235,7 @@
             return mImeTarget;
         }
 
-        private SurfaceControl createImeSurface(SurfaceControl.ScreenshotHardwareBuffer b,
+        private SurfaceControl createImeSurface(ScreenCapture.ScreenshotHardwareBuffer b,
                 Transaction t) {
             final HardwareBuffer buffer = b.getHardwareBuffer();
             ProtoLog.i(WM_DEBUG_IME, "create IME snapshot for %s, buff width=%s, height=%s",
@@ -4296,7 +4297,7 @@
                     || mImeSurface.getWidth() != dc.mInputMethodWindow.getFrame().width()
                     || mImeSurface.getHeight() != dc.mInputMethodWindow.getFrame().height();
             if (task != null && !task.isActivityTypeHomeOrRecents()) {
-                SurfaceControl.ScreenshotHardwareBuffer imeBuffer = renewImeSurface
+                ScreenCapture.ScreenshotHardwareBuffer imeBuffer = renewImeSurface
                         ? dc.mWmService.mTaskSnapshotController.snapshotImeFromAttachedTask(task)
                         : null;
                 if (imeBuffer != null) {
@@ -4905,12 +4906,12 @@
 
         // Send invalid rect and no width and height since it will screenshot the entire display.
         final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
-        final SurfaceControl.DisplayCaptureArgs captureArgs =
-                new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
+        final ScreenCapture.DisplayCaptureArgs captureArgs =
+                new ScreenCapture.DisplayCaptureArgs.Builder(displayToken)
                         .setUseIdentityTransform(inRotation)
                         .build();
-        final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                SurfaceControl.captureDisplay(captureArgs);
+        final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                ScreenCapture.captureDisplay(captureArgs);
         final Bitmap bitmap = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
         if (bitmap == null) {
             Slog.w(TAG_WM, "Failed to take screenshot");
diff --git a/services/core/java/com/android/server/wm/DisplayHashController.java b/services/core/java/com/android/server/wm/DisplayHashController.java
index 543d4ad..1a8b434 100644
--- a/services/core/java/com/android/server/wm/DisplayHashController.java
+++ b/services/core/java/com/android/server/wm/DisplayHashController.java
@@ -53,9 +53,9 @@
 import android.util.Size;
 import android.util.Slog;
 import android.view.MagnificationSpec;
-import android.view.SurfaceControl;
 import android.view.displayhash.DisplayHash;
 import android.view.displayhash.VerifiedDisplayHash;
+import android.window.ScreenCapture;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -194,7 +194,7 @@
         return true;
     }
 
-    void generateDisplayHash(SurfaceControl.LayerCaptureArgs.Builder args,
+    void generateDisplayHash(ScreenCapture.LayerCaptureArgs.Builder args,
             Rect boundsInWindow, String hashAlgorithm, int uid, RemoteCallback callback) {
         if (!allowedToGenerateHash(uid)) {
             sendDisplayHashError(callback, DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS);
@@ -217,8 +217,8 @@
 
         args.setGrayscale(displayHashParams.isGrayscaleBuffer());
 
-        SurfaceControl.ScreenshotHardwareBuffer screenshotHardwareBuffer =
-                SurfaceControl.captureLayers(args.build());
+        ScreenCapture.ScreenshotHardwareBuffer screenshotHardwareBuffer =
+                ScreenCapture.captureLayers(args.build());
         if (screenshotHardwareBuffer == null
                 || screenshotHardwareBuffer.getHardwareBuffer() == null) {
             Slog.w(TAG, "Failed to generate DisplayHash. Couldn't capture content");
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index f3bd1a1..2de8faf 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -64,6 +64,7 @@
 import android.view.InternalInsetsAnimationController;
 import android.view.SurfaceControl;
 import android.view.SyncRtSurfaceTransactionApplier;
+import android.view.WindowInsets;
 import android.view.WindowInsets.Type;
 import android.view.WindowInsetsAnimation;
 import android.view.WindowInsetsAnimation.Bounds;
@@ -398,16 +399,13 @@
 
         if (WindowConfiguration.isFloating(windowingMode)
                 || (windowingMode == WINDOWING_MODE_MULTI_WINDOW && isAlwaysOnTop)) {
+            // Keep frames, caption, and IME.
+            int types = WindowInsets.Type.captionBar();
+            if (windowingMode != WINDOWING_MODE_PINNED) {
+                types |= WindowInsets.Type.ime();
+            }
             InsetsState newState = new InsetsState();
-
-            // Only caption and IME are needed.
-            if (state.peekSource(ITYPE_CAPTION_BAR) != null) {
-                newState.addSource(state.peekSource(ITYPE_CAPTION_BAR));
-            }
-            if (windowingMode != WINDOWING_MODE_PINNED && state.peekSource(ITYPE_IME) != null) {
-                newState.addSource(state.peekSource(ITYPE_IME));
-            }
-
+            newState.set(state, types);
             state = newState;
             stateCopied = true;
         }
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 27550d9..3d00686 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -273,8 +273,8 @@
         @Override
         public boolean onDoubleTapEvent(MotionEvent e) {
             if (e.getAction() == MotionEvent.ACTION_UP) {
-                mDoubleTapCallbackX.accept((int) e.getX());
-                mDoubleTapCallbackY.accept((int) e.getY());
+                mDoubleTapCallbackX.accept((int) e.getRawX());
+                mDoubleTapCallbackY.accept((int) e.getRawY());
                 return true;
             }
             return false;
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 317c93e..ea82417 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -481,7 +481,7 @@
     }
 
     private void updateRoundedCorners(WindowState mainWindow) {
-        final SurfaceControl windowSurface = mainWindow.getClientViewRootSurface();
+        final SurfaceControl windowSurface = mainWindow.getSurfaceControl();
         if (windowSurface != null && windowSurface.isValid()) {
             final Transaction transaction = mActivityRecord.getSyncTransaction();
 
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index b3f3548..f66ba38 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1487,8 +1487,8 @@
             } else {
                 final String resolvedType =
                         homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
-                final ResolveInfo info = AppGlobals.getPackageManager()
-                        .resolveIntent(homeIntent, resolvedType, flags, userId);
+                final ResolveInfo info = mTaskSupervisor.resolveIntent(homeIntent, resolvedType,
+                        userId, flags, Binder.getCallingUid());
                 if (info != null) {
                     aInfo = info.activityInfo;
                 }
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index fd8b614..24d4e98 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -52,6 +52,7 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Transformation;
+import android.window.ScreenCapture;
 
 import com.android.internal.R;
 import com.android.internal.protolog.common.ProtoLog;
@@ -167,7 +168,7 @@
         final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
 
         try {
-            final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer;
+            final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer;
             if (isSizeChanged) {
                 final DisplayAddress address = displayInfo.address;
                 if (!(address instanceof DisplayAddress.Physical)) {
@@ -186,22 +187,22 @@
                 // the whole display to include the rounded corner overlays.
                 setSkipScreenshotForRoundedCornerOverlays(false, t);
                 mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays();
-                final SurfaceControl.DisplayCaptureArgs captureArgs =
-                        new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
+                final ScreenCapture.DisplayCaptureArgs captureArgs =
+                        new ScreenCapture.DisplayCaptureArgs.Builder(displayToken)
                                 .setSourceCrop(new Rect(0, 0, width, height))
                                 .setAllowProtected(true)
                                 .setCaptureSecureLayers(true)
                                 .build();
-                screenshotBuffer = SurfaceControl.captureDisplay(captureArgs);
+                screenshotBuffer = ScreenCapture.captureDisplay(captureArgs);
             } else {
-                SurfaceControl.LayerCaptureArgs captureArgs =
-                        new SurfaceControl.LayerCaptureArgs.Builder(
+                ScreenCapture.LayerCaptureArgs captureArgs =
+                        new ScreenCapture.LayerCaptureArgs.Builder(
                                 displayContent.getSurfaceControl())
                                 .setCaptureSecureLayers(true)
                                 .setAllowProtected(true)
                                 .setSourceCrop(new Rect(0, 0, width, height))
                                 .build();
-                screenshotBuffer = SurfaceControl.captureLayers(captureArgs);
+                screenshotBuffer = ScreenCapture.captureLayers(captureArgs);
             }
 
             if (screenshotBuffer == null) {
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index f3670e4..94d4dde 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -45,6 +45,7 @@
 import android.view.SurfaceControl.Transaction;
 import android.view.animation.Animation;
 import android.view.animation.Transformation;
+import android.window.ScreenCapture;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -433,16 +434,16 @@
     private void doCreateExtensionSurface(SurfaceControl leash, Rect edgeBounds,
             Rect extensionRect, int xPos, int yPos, String layerName,
             Transaction startTransaction) {
-        SurfaceControl.LayerCaptureArgs captureArgs =
-                new SurfaceControl.LayerCaptureArgs.Builder(leash /* surfaceToExtend */)
+        ScreenCapture.LayerCaptureArgs captureArgs =
+                new ScreenCapture.LayerCaptureArgs.Builder(leash /* surfaceToExtend */)
                         .setSourceCrop(edgeBounds)
                         .setFrameScale(1)
                         .setPixelFormat(PixelFormat.RGBA_8888)
                         .setChildrenOnly(true)
                         .setAllowProtected(true)
                         .build();
-        final SurfaceControl.ScreenshotHardwareBuffer edgeBuffer =
-                SurfaceControl.captureLayers(captureArgs);
+        final ScreenCapture.ScreenshotHardwareBuffer edgeBuffer =
+                ScreenCapture.captureLayers(captureArgs);
 
         if (edgeBuffer == null) {
             // The leash we are trying to screenshot may have been removed by this point, which is
diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java
index a7ef36b..0c36d27 100644
--- a/services/core/java/com/android/server/wm/SurfaceFreezer.java
+++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java
@@ -28,6 +28,7 @@
 import android.hardware.HardwareBuffer;
 import android.util.Slog;
 import android.view.SurfaceControl;
+import android.window.ScreenCapture;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
@@ -89,7 +90,7 @@
 
         freezeTarget = freezeTarget != null ? freezeTarget : mAnimatable.getFreezeSnapshotTarget();
         if (freezeTarget != null) {
-            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBufferInner(
+            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBufferInner(
                     freezeTarget, startBounds);
             final HardwareBuffer buffer = screenshotBuffer == null ? null
                     : screenshotBuffer.getHardwareBuffer();
@@ -183,31 +184,31 @@
         return mLeash != null;
     }
 
-    private static SurfaceControl.ScreenshotHardwareBuffer createSnapshotBuffer(
+    private static ScreenCapture.ScreenshotHardwareBuffer createSnapshotBuffer(
             @NonNull SurfaceControl target, @Nullable Rect bounds) {
         Rect cropBounds = null;
         if (bounds != null) {
             cropBounds = new Rect(bounds);
             cropBounds.offsetTo(0, 0);
         }
-        SurfaceControl.LayerCaptureArgs captureArgs =
-                new SurfaceControl.LayerCaptureArgs.Builder(target)
+        ScreenCapture.LayerCaptureArgs captureArgs =
+                new ScreenCapture.LayerCaptureArgs.Builder(target)
                         .setSourceCrop(cropBounds)
                         .setCaptureSecureLayers(true)
                         .setAllowProtected(true)
                         .build();
-        return SurfaceControl.captureLayers(captureArgs);
+        return ScreenCapture.captureLayers(captureArgs);
     }
 
     @VisibleForTesting
-    SurfaceControl.ScreenshotHardwareBuffer createSnapshotBufferInner(
+    ScreenCapture.ScreenshotHardwareBuffer createSnapshotBufferInner(
             SurfaceControl target, Rect bounds) {
         return createSnapshotBuffer(target, bounds);
     }
 
     @VisibleForTesting
     GraphicBuffer createFromHardwareBufferInner(
-            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) {
+            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer) {
         return GraphicBuffer.createFromHardwareBuffer(screenshotBuffer.getHardwareBuffer());
     }
 
@@ -220,7 +221,7 @@
          * @param screenshotBuffer A thumbnail or placeholder for thumbnail to initialize with.
          */
         Snapshot(SurfaceControl.Transaction t,
-                SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
+                ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
             GraphicBuffer graphicBuffer = createFromHardwareBufferInner(screenshotBuffer);
 
             mSurfaceControl = mAnimatable.makeAnimationLeash()
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 728102e..837045c 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.isStartResultSuccessful;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
 import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
@@ -5343,54 +5344,32 @@
 
         if (parent != null && foundParentInTask) {
             final int callingUid = srec.info.applicationInfo.uid;
-            final int parentLaunchMode = parent.info.launchMode;
-            final int destIntentFlags = destIntent.getFlags();
-            if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
-                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
-                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
-                    (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
-                boolean abort;
-                try {
-                    abort = !mTaskSupervisor.checkStartAnyActivityPermission(destIntent,
-                            parent.info, null /* resultWho */, -1 /* requestCode */, srec.getPid(),
-                            callingUid, srec.info.packageName, null /* callingFeatureId */,
-                            false /* ignoreTargetSecurity */, false /* launchingInTask */, srec.app,
-                            null /* resultRecord */, null /* resultRootTask */);
-                } catch (SecurityException e) {
-                    abort = true;
+            try {
+                ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
+                        destIntent.getComponent(), ActivityManagerService.STOCK_PM_FLAGS,
+                        srec.mUserId);
+                // TODO(b/64750076): Check if calling pid should really be -1.
+                final int res = mAtmService.getActivityStartController()
+                        .obtainStarter(destIntent, "navigateUpTo")
+                        .setCaller(srec.app.getThread())
+                        .setActivityInfo(aInfo)
+                        .setResultTo(parent.token)
+                        .setIntentGrants(destGrants)
+                        .setCallingPid(-1)
+                        .setCallingUid(callingUid)
+                        .setCallingPackage(srec.packageName)
+                        .setCallingFeatureId(parent.launchedFromFeatureId)
+                        .setRealCallingPid(-1)
+                        .setRealCallingUid(callingUid)
+                        .setComponentSpecified(true)
+                        .execute();
+                foundParentInTask = isStartResultSuccessful(res);
+                if (res == ActivityManager.START_SUCCESS) {
+                    parent.finishIfPossible(resultCode, resultData, resultGrants,
+                            "navigate-top", true /* oomAdj */);
                 }
-                if (abort) {
-                    android.util.EventLog.writeEvent(0x534e4554, "238605611", callingUid, "");
-                    foundParentInTask = false;
-                } else {
-                    parent.deliverNewIntentLocked(callingUid, destIntent, destGrants,
-                            srec.packageName);
-                }
-            } else {
-                try {
-                    ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
-                            destIntent.getComponent(), ActivityManagerService.STOCK_PM_FLAGS,
-                            srec.mUserId);
-                    // TODO(b/64750076): Check if calling pid should really be -1.
-                    final int res = mAtmService.getActivityStartController()
-                            .obtainStarter(destIntent, "navigateUpTo")
-                            .setCaller(srec.app.getThread())
-                            .setActivityInfo(aInfo)
-                            .setResultTo(parent.token)
-                            .setCallingPid(-1)
-                            .setCallingUid(callingUid)
-                            .setCallingPackage(srec.packageName)
-                            .setCallingFeatureId(parent.launchedFromFeatureId)
-                            .setRealCallingPid(-1)
-                            .setRealCallingUid(callingUid)
-                            .setComponentSpecified(true)
-                            .execute();
-                    foundParentInTask = res == ActivityManager.START_SUCCESS;
-                } catch (RemoteException e) {
-                    foundParentInTask = false;
-                }
-                parent.finishIfPossible(resultCode, resultData, resultGrants,
-                        "navigate-top", true /* oomAdj */);
+            } catch (RemoteException e) {
+                foundParentInTask = false;
             }
         }
         Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index f784f71..de4c84c 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -89,6 +89,7 @@
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 import android.window.ITaskFragmentOrganizer;
+import android.window.ScreenCapture;
 import android.window.TaskFragmentInfo;
 import android.window.TaskFragmentOrganizerToken;
 
@@ -306,7 +307,7 @@
 
     //TODO(b/207481538) Remove once the infrastructure to support per-activity screenshot is
     // implemented
-    HashMap<String, SurfaceControl.ScreenshotHardwareBuffer> mBackScreenshots = new HashMap<>();
+    HashMap<String, ScreenCapture.ScreenshotHardwareBuffer> mBackScreenshots = new HashMap<>();
 
     private final EnsureActivitiesVisibleHelper mEnsureActivitiesVisibleHelper =
             new EnsureActivitiesVisibleHelper(this);
@@ -1595,12 +1596,14 @@
         boolean pauseImmediately = false;
         boolean shouldAutoPip = false;
         if (resuming != null) {
+            // We do not want to trigger auto-PiP upon launch of a translucent activity.
+            final boolean resumingOccludesParent = resuming.occludesParent();
             // Resuming the new resume activity only if the previous activity can't go into Pip
             // since we want to give Pip activities a chance to enter Pip before resuming the
             // next activity.
             final boolean lastResumedCanPip = prev.checkEnterPictureInPictureState(
                     "shouldAutoPipWhilePausing", userLeaving);
-            if (userLeaving && lastResumedCanPip
+            if (userLeaving && resumingOccludesParent && lastResumedCanPip
                     && prev.pictureInPictureArgs.isAutoEnterEnabled()) {
                 shouldAutoPip = true;
             } else if (!lastResumedCanPip) {
@@ -1859,7 +1862,7 @@
                 ProtoLog.v(WM_DEBUG_BACK_PREVIEW, "Screenshotting Activity %s",
                         r.mActivityComponent.flattenToString());
                 Rect outBounds = r.getBounds();
-                SurfaceControl.ScreenshotHardwareBuffer backBuffer = SurfaceControl.captureLayers(
+                ScreenCapture.ScreenshotHardwareBuffer backBuffer = ScreenCapture.captureLayers(
                         r.mSurfaceControl,
                         new Rect(0, 0, outBounds.width(), outBounds.height()),
                         1f);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 534616f..9306749 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -58,6 +58,7 @@
 import android.view.WindowInsets.Type;
 import android.view.WindowInsetsController.Appearance;
 import android.view.WindowManager.LayoutParams;
+import android.window.ScreenCapture;
 import android.window.TaskSnapshot;
 
 import com.android.internal.R;
@@ -389,11 +390,11 @@
     }
 
     @Nullable
-    SurfaceControl.ScreenshotHardwareBuffer createTaskSnapshot(@NonNull Task task,
+    ScreenCapture.ScreenshotHardwareBuffer createTaskSnapshot(@NonNull Task task,
             TaskSnapshot.Builder builder) {
         Point taskSize = new Point();
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "createTaskSnapshot");
-        final SurfaceControl.ScreenshotHardwareBuffer taskSnapshot = createTaskSnapshot(task,
+        final ScreenCapture.ScreenshotHardwareBuffer taskSnapshot = createTaskSnapshot(task,
                 mHighResTaskSnapshotScale, builder.getPixelFormat(), taskSize, builder);
         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
         builder.setTaskSize(taskSize);
@@ -401,7 +402,7 @@
     }
 
     @Nullable
-    private SurfaceControl.ScreenshotHardwareBuffer createImeSnapshot(@NonNull Task task,
+    private ScreenCapture.ScreenshotHardwareBuffer createImeSnapshot(@NonNull Task task,
             int pixelFormat) {
         if (task.getSurfaceControl() == null) {
             if (DEBUG_SCREENSHOT) {
@@ -410,11 +411,11 @@
             return null;
         }
         final WindowState imeWindow = task.getDisplayContent().mInputMethodWindow;
-        SurfaceControl.ScreenshotHardwareBuffer imeBuffer = null;
+        ScreenCapture.ScreenshotHardwareBuffer imeBuffer = null;
         if (imeWindow != null && imeWindow.isWinVisibleLw()) {
             final Rect bounds = imeWindow.getParentFrame();
             bounds.offsetTo(0, 0);
-            imeBuffer = SurfaceControl.captureLayersExcluding(imeWindow.getSurfaceControl(),
+            imeBuffer = ScreenCapture.captureLayersExcluding(imeWindow.getSurfaceControl(),
                     bounds, 1.0f, pixelFormat, null);
         }
         return imeBuffer;
@@ -425,7 +426,7 @@
      * task to keep IME visibility while app transitioning.
      */
     @Nullable
-    SurfaceControl.ScreenshotHardwareBuffer snapshotImeFromAttachedTask(@NonNull Task task) {
+    ScreenCapture.ScreenshotHardwareBuffer snapshotImeFromAttachedTask(@NonNull Task task) {
         // Check if the IME targets task ready to take the corresponding IME snapshot, if not,
         // means the task is not yet visible for some reasons and no need to snapshot IME surface.
         if (checkIfReadyToSnapshot(task) == null) {
@@ -438,7 +439,7 @@
     }
 
     @Nullable
-    SurfaceControl.ScreenshotHardwareBuffer createTaskSnapshot(@NonNull Task task,
+    ScreenCapture.ScreenshotHardwareBuffer createTaskSnapshot(@NonNull Task task,
             float scaleFraction, int pixelFormat, Point outTaskSize, TaskSnapshot.Builder builder) {
         if (task.getSurfaceControl() == null) {
             if (DEBUG_SCREENSHOT) {
@@ -473,8 +474,8 @@
         }
         builder.setHasImeSurface(!excludeIme && imeWindow != null && imeWindow.isVisible());
 
-        final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                SurfaceControl.captureLayersExcluding(
+        final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                ScreenCapture.captureLayersExcluding(
                         task.getSurfaceControl(), mTmpRect, scaleFraction,
                         pixelFormat, excludeLayers);
         if (outTaskSize != null) {
@@ -508,7 +509,7 @@
             return null;
         }
 
-        final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
+        final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
                 createTaskSnapshot(task, builder);
 
         if (screenshotBuffer == null) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 32b7532..723aa19 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -40,8 +40,9 @@
 import static android.view.WindowManager.TransitionType;
 import static android.view.WindowManager.transitTypeToString;
 import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
+import static android.window.TransitionInfo.FLAG_FILLS_TASK;
+import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
-import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;
 import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD;
 import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
@@ -77,6 +78,7 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.window.RemoteTransition;
+import android.window.ScreenCapture;
 import android.window.TransitionInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -1838,8 +1840,10 @@
                     flags |= FLAG_WILL_IME_SHOWN;
                 }
             }
+            Task parentTask = null;
             final ActivityRecord record = wc.asActivityRecord();
             if (record != null) {
+                parentTask = record.getTask();
                 if (record.mUseTransferredAnimation) {
                     flags |= FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
                 }
@@ -1847,6 +1851,26 @@
                     flags |= FLAG_IS_VOICE_INTERACTION;
                 }
             }
+            final TaskFragment taskFragment = wc.asTaskFragment();
+            if (taskFragment != null && task == null) {
+                parentTask = taskFragment.getTask();
+            }
+            if (parentTask != null) {
+                if (parentTask.forAllLeafTaskFragments(TaskFragment::isEmbedded)) {
+                    // Whether this is in a Task with embedded activity.
+                    flags |= FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
+                }
+                final Rect taskBounds = parentTask.getBounds();
+                final Rect startBounds = mAbsoluteBounds;
+                final Rect endBounds = wc.getBounds();
+                if (taskBounds.width() == startBounds.width()
+                        && taskBounds.height() == startBounds.height()
+                        && taskBounds.width() == endBounds.width()
+                        && taskBounds.height() == endBounds.height()) {
+                    // Whether the container fills the Task bounds before and after the transition.
+                    flags |= FLAG_FILLS_TASK;
+                }
+            }
             final DisplayContent dc = wc.asDisplayContent();
             if (dc != null) {
                 flags |= FLAG_IS_DISPLAY;
@@ -1863,9 +1887,6 @@
             if (occludesKeyguard(wc)) {
                 flags |= FLAG_OCCLUDES_KEYGUARD;
             }
-            if (wc.isEmbedded()) {
-                flags |= FLAG_IS_EMBEDDED;
-            }
             return flags;
         }
     }
@@ -2105,14 +2126,14 @@
 
             Rect cropBounds = new Rect(bounds);
             cropBounds.offsetTo(0, 0);
-            SurfaceControl.LayerCaptureArgs captureArgs =
-                    new SurfaceControl.LayerCaptureArgs.Builder(wc.getSurfaceControl())
+            ScreenCapture.LayerCaptureArgs captureArgs =
+                    new ScreenCapture.LayerCaptureArgs.Builder(wc.getSurfaceControl())
                             .setSourceCrop(cropBounds)
                             .setCaptureSecureLayers(true)
                             .setAllowProtected(true)
                             .build();
-            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                    SurfaceControl.captureLayers(captureArgs);
+            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                    ScreenCapture.captureLayers(captureArgs);
             final HardwareBuffer buffer = screenshotBuffer == null ? null
                     : screenshotBuffer.getHardwareBuffer();
             if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index d652b8e..0fd3e9b 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -53,6 +53,7 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.view.animation.Animation;
+import android.window.ScreenCapture;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.ProtoLogImpl;
@@ -931,7 +932,7 @@
         final Rect bounds = wallpaperWindowState.getBounds();
         bounds.offsetTo(0, 0);
 
-        SurfaceControl.ScreenshotHardwareBuffer wallpaperBuffer = SurfaceControl.captureLayers(
+        ScreenCapture.ScreenshotHardwareBuffer wallpaperBuffer = ScreenCapture.captureLayers(
                 wallpaperWindowState.getSurfaceControl(), bounds, 1 /* frameScale */);
 
         if (wallpaperBuffer == null) {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index bc66852..8cc0d5d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -622,7 +622,7 @@
         setInitialSurfaceControlProperties(makeSurface());
     }
 
-    void setInitialSurfaceControlProperties(SurfaceControl.Builder b) {
+    void setInitialSurfaceControlProperties(Builder b) {
         setSurfaceControl(b.setCallsite("WindowContainer.setInitialSurfaceControlProperties").build());
         if (showSurfaceOnCreation()) {
             getSyncTransaction().show(mSurfaceControl);
@@ -652,7 +652,7 @@
         mLastSurfacePosition.set(0, 0);
         mLastDeltaRotation = Surface.ROTATION_0;
 
-        final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(null)
+        final Builder b = mWmService.makeSurfaceBuilder(null)
                 .setContainerLayer()
                 .setName(getName());
 
@@ -2437,7 +2437,7 @@
         } while (current != null);
     }
 
-    SurfaceControl.Builder makeSurface() {
+    Builder makeSurface() {
         final WindowContainer p = getParent();
         return p.makeChildSurface(this);
     }
@@ -2446,7 +2446,7 @@
      * @param child The WindowContainer this child surface is for, or null if the Surface
      *              is not assosciated with a WindowContainer (e.g. a surface used for Dimming).
      */
-    SurfaceControl.Builder makeChildSurface(WindowContainer child) {
+    Builder makeChildSurface(WindowContainer child) {
         final WindowContainer p = getParent();
         // Give the parent a chance to set properties. In hierarchy v1 we rely
         // on this to set full-screen dimensions on all our Surface-less Layers.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 5ad6fbd..9d11fc9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -123,7 +123,10 @@
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
@@ -289,6 +292,7 @@
 import android.view.displayhash.VerifiedDisplayHash;
 import android.window.ClientWindowFrames;
 import android.window.ITaskFpsCallback;
+import android.window.ScreenCapture;
 import android.window.TaskSnapshot;
 import android.window.WindowContainerToken;
 
@@ -2603,10 +2607,22 @@
         if (win.isWinVisibleLw() && win.mDisplayContent.okToAnimate()) {
             String reason = null;
             if (winAnimator.applyAnimationLocked(transit, false)) {
+                // This is a WMCore-driven window animation.
                 reason = "applyAnimation";
                 focusMayChange = true;
                 win.mAnimatingExit = true;
-            } else if (win.isExitAnimationRunningSelfOrParent()) {
+            } else if (
+                    // This is already animating via a WMCore-driven window animation
+                    win.isSelfAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION)
+                    // Or already animating as part of a legacy app-transition
+                    || win.isAnimating(PARENTS | TRANSITION,
+                            ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
+                    // Or already animating as part of a shell-transition.
+                    || (win.inTransition()
+                            // Filter out non-app windows since transitions don't animate those
+                            // (but may still "wait" on them for readiness)
+                            && (win.mActivityRecord != null || win.mIsWallpaper))) {
+                // TODO(b/247005789): set mAnimatingExit somewhere in shell-transitions setup.
                 reason = "animating";
                 win.mAnimatingExit = true;
             } else if (win.mDisplayContent.mWallpaperController.isWallpaperTarget(win)
@@ -3980,7 +3996,7 @@
      * Generates and returns an up-to-date {@link Bitmap} for the specified taskId.
      *
      * @param taskId                  The task ID of the task for which a Bitmap is requested.
-     * @param layerCaptureArgsBuilder A {@link SurfaceControl.LayerCaptureArgs.Builder} with
+     * @param layerCaptureArgsBuilder A {@link ScreenCapture.LayerCaptureArgs.Builder} with
      *                                arguments for how to capture the Bitmap. The caller can
      *                                specify any arguments, but this method will ensure that the
      *                                specified task's SurfaceControl is used and the crop is set to
@@ -3990,7 +4006,7 @@
      */
     @Nullable
     public Bitmap captureTaskBitmap(int taskId,
-            @NonNull SurfaceControl.LayerCaptureArgs.Builder layerCaptureArgsBuilder) {
+            @NonNull ScreenCapture.LayerCaptureArgs.Builder layerCaptureArgsBuilder) {
         if (mTaskSnapshotController.shouldDisableSnapshots()) {
             return null;
         }
@@ -4009,7 +4025,7 @@
             mTmpRect.offsetTo(0, 0);
 
             final SurfaceControl sc = task.getSurfaceControl();
-            final SurfaceControl.ScreenshotHardwareBuffer buffer = SurfaceControl.captureLayers(
+            final ScreenCapture.ScreenshotHardwareBuffer buffer = ScreenCapture.captureLayers(
                     layerCaptureArgsBuilder.setLayer(sc).setSourceCrop(mTmpRect).build());
             if (buffer == null) {
                 Slog.w(TAG, "Could not get screenshot buffer for taskId: " + taskId);
@@ -5810,6 +5826,21 @@
         return -1;
     }
 
+    /**
+     * Return the display Id that has the given uniqueId. Unique ID is defined in
+     * {@link DisplayInfo#uniqueId}.
+     */
+    @Override
+    public int getDisplayIdByUniqueId(String uniqueId) {
+        synchronized (mGlobalLock) {
+            final DisplayContent displayContent = mRoot.getDisplayContent(uniqueId);
+            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
+                return displayContent.mDisplayId;
+            }
+        }
+        return -1;
+    }
+
     @Override
     public void setForcedDisplayDensityForUser(int displayId, int density, int userId) {
         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
@@ -9085,8 +9116,8 @@
         // be covering it with the same uid. We want to make sure we include content that's
         // covering to ensure we get as close as possible to what the user sees
         final int uid = session.mUid;
-        SurfaceControl.LayerCaptureArgs.Builder args =
-                new SurfaceControl.LayerCaptureArgs.Builder(displaySurfaceControl)
+        ScreenCapture.LayerCaptureArgs.Builder args =
+                new ScreenCapture.LayerCaptureArgs.Builder(displaySurfaceControl)
                         .setUid(uid)
                         .setSourceCrop(boundsInDisplay);
 
@@ -9261,4 +9292,46 @@
                         "Unexpected letterbox background type: " + letterboxBackgroundType);
         }
     }
+
+    @Override
+    public void captureDisplay(int displayId, @Nullable ScreenCapture.CaptureArgs captureArgs,
+            ScreenCapture.ScreenCaptureListener listener) {
+        Slog.d(TAG, "captureDisplay");
+        if (!checkCallingPermission(READ_FRAME_BUFFER, "captureDisplay()")) {
+            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
+        }
+
+        ScreenCapture.captureLayers(getCaptureArgs(displayId, captureArgs), listener);
+    }
+
+    @VisibleForTesting
+    ScreenCapture.LayerCaptureArgs getCaptureArgs(int displayId,
+            @Nullable ScreenCapture.CaptureArgs captureArgs) {
+        final SurfaceControl displaySurfaceControl;
+        synchronized (mGlobalLock) {
+            DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+            if (displayContent == null) {
+                throw new IllegalArgumentException("Trying to screenshot and invalid display: "
+                        + displayId);
+            }
+
+            displaySurfaceControl = displayContent.getSurfaceControl();
+
+            if (captureArgs == null) {
+                captureArgs = new ScreenCapture.CaptureArgs.Builder<>()
+                        .build();
+            }
+
+            if (captureArgs.mSourceCrop.isEmpty()) {
+                displayContent.getBounds(mTmpRect);
+                mTmpRect.offsetTo(0, 0);
+            } else {
+                mTmpRect.set(captureArgs.mSourceCrop);
+            }
+        }
+
+        return new ScreenCapture.LayerCaptureArgs.Builder(displaySurfaceControl, captureArgs)
+                        .setSourceCrop(mTmpRect)
+                        .build();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index c22091b..2838304 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -264,8 +264,23 @@
 
     private int runDisplayDensity(PrintWriter pw) throws RemoteException {
         String densityStr = getNextArg();
+        String option = getNextOption();
+        String arg = getNextArg();
         int density;
-        final int displayId = getDisplayId(densityStr);
+        int displayId = Display.DEFAULT_DISPLAY;
+        if ("-d".equals(option) && arg != null) {
+            try {
+                displayId = Integer.parseInt(arg);
+            } catch (NumberFormatException e) {
+                getErrPrintWriter().println("Error: bad number " + e);
+            }
+        } else if ("-u".equals(option) && arg != null) {
+            displayId = mInterface.getDisplayIdByUniqueId(arg);
+            if (displayId == Display.INVALID_DISPLAY) {
+                getErrPrintWriter().println("Error: the uniqueId is invalid ");
+                return -1;
+            }
+        }
 
         if (densityStr == null) {
             printInitialDisplayDensity(pw, displayId);
@@ -1312,7 +1327,7 @@
         pw.println("  size [reset|WxH|WdpxHdp] [-d DISPLAY_ID]");
         pw.println("    Return or override display size.");
         pw.println("    width and height in pixels unless suffixed with 'dp'.");
-        pw.println("  density [reset|DENSITY] [-d DISPLAY_ID]");
+        pw.println("  density [reset|DENSITY] [-d DISPLAY_ID] [-u UNIQUE_ID]");
         pw.println("    Return or override display density.");
         pw.println("  folded-area [reset|LEFT,TOP,RIGHT,BOTTOM]");
         pw.println("    Return or override folded area.");
diff --git a/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java b/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java
index 261dda7..b93b8d8 100644
--- a/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java
+++ b/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java
@@ -30,6 +30,7 @@
 import android.view.Display;
 import android.view.Surface;
 import android.view.SurfaceControl;
+import android.window.ScreenCapture;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
@@ -118,8 +119,8 @@
         Point size = new Point();
         display.getSize(size);
         Rect crop = new Rect(0, 0, size.x, size.y);
-        SurfaceControl.ScreenshotHardwareBuffer buffer =
-                SurfaceControl.captureLayers(surfaceControl, crop, 1);
+        ScreenCapture.ScreenshotHardwareBuffer buffer =
+                ScreenCapture.captureLayers(surfaceControl, crop, 1);
         if (buffer == null) {
             return 0;
         }
diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
index daca153..b7a4fd1 100644
--- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp
+++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
@@ -37,6 +37,7 @@
     KEYBOARD,
     MOUSE,
     TOUCHSCREEN,
+    DPAD,
 };
 
 enum class UinputAction {
@@ -76,6 +77,13 @@
         {AMOTION_EVENT_TOOL_TYPE_PALM, MT_TOOL_PALM},
 };
 
+// Dpad keycode mapping from https://source.android.com/devices/input/keyboard-devices
+static std::map<int, int> DPAD_KEY_CODE_MAPPING = {
+        {AKEYCODE_DPAD_DOWN, KEY_DOWN},     {AKEYCODE_DPAD_UP, KEY_UP},
+        {AKEYCODE_DPAD_LEFT, KEY_LEFT},     {AKEYCODE_DPAD_RIGHT, KEY_RIGHT},
+        {AKEYCODE_DPAD_CENTER, KEY_SELECT},
+};
+
 // Keycode mapping from https://source.android.com/devices/input/keyboard-devices
 static std::map<int, int> KEY_CODE_MAPPING = {
         {AKEYCODE_0, KEY_0},
@@ -200,8 +208,13 @@
     ioctl(fd, UI_SET_EVBIT, EV_KEY);
     ioctl(fd, UI_SET_EVBIT, EV_SYN);
     switch (deviceType) {
+        case DeviceType::DPAD:
+            for (const auto& [_, keyCode] : DPAD_KEY_CODE_MAPPING) {
+                ioctl(fd, UI_SET_KEYBIT, keyCode);
+            }
+            break;
         case DeviceType::KEYBOARD:
-            for (const auto& [ignored, keyCode] : KEY_CODE_MAPPING) {
+            for (const auto& [_, keyCode] : KEY_CODE_MAPPING) {
                 ioctl(fd, UI_SET_KEYBIT, keyCode);
             }
             break;
@@ -327,6 +340,12 @@
                       screenHeight, screenWidth);
 }
 
+static int nativeOpenUinputDpad(JNIEnv* env, jobject thiz, jstring name, jint vendorId,
+                                jint productId, jstring phys) {
+    return openUinputJni(env, name, vendorId, productId, phys, DeviceType::DPAD,
+                         /* screenHeight */ 0, /* screenWidth */ 0);
+}
+
 static int nativeOpenUinputKeyboard(JNIEnv* env, jobject thiz, jstring name, jint vendorId,
                                     jint productId, jstring phys) {
     return openUinputJni(env, name, vendorId, productId, phys, DeviceType::KEYBOARD,
@@ -355,10 +374,10 @@
     return TEMP_FAILURE_RETRY(write(fd, &ev, sizeof(struct input_event))) == sizeof(ev);
 }
 
-static bool nativeWriteKeyEvent(JNIEnv* env, jobject thiz, jint fd, jint androidKeyCode,
-                                jint action) {
-    auto keyCodeIterator = KEY_CODE_MAPPING.find(androidKeyCode);
-    if (keyCodeIterator == KEY_CODE_MAPPING.end()) {
+static bool writeKeyEvent(jint fd, jint androidKeyCode, jint action,
+                          const std::map<int, int>& keyCodeMapping) {
+    auto keyCodeIterator = keyCodeMapping.find(androidKeyCode);
+    if (keyCodeIterator == keyCodeMapping.end()) {
         ALOGE("No supportive native keycode for androidKeyCode %d", androidKeyCode);
         return false;
     }
@@ -376,6 +395,16 @@
     return true;
 }
 
+static bool nativeWriteDpadKeyEvent(JNIEnv* env, jobject thiz, jint fd, jint androidKeyCode,
+                                    jint action) {
+    return writeKeyEvent(fd, androidKeyCode, action, DPAD_KEY_CODE_MAPPING);
+}
+
+static bool nativeWriteKeyEvent(JNIEnv* env, jobject thiz, jint fd, jint androidKeyCode,
+                                jint action) {
+    return writeKeyEvent(fd, androidKeyCode, action, KEY_CODE_MAPPING);
+}
+
 static bool nativeWriteButtonEvent(JNIEnv* env, jobject thiz, jint fd, jint buttonCode,
                                    jint action) {
     auto buttonCodeIterator = BUTTON_CODE_MAPPING.find(buttonCode);
@@ -461,6 +490,8 @@
 }
 
 static JNINativeMethod methods[] = {
+        {"nativeOpenUinputDpad", "(Ljava/lang/String;IILjava/lang/String;)I",
+         (void*)nativeOpenUinputDpad},
         {"nativeOpenUinputKeyboard", "(Ljava/lang/String;IILjava/lang/String;)I",
          (void*)nativeOpenUinputKeyboard},
         {"nativeOpenUinputMouse", "(Ljava/lang/String;IILjava/lang/String;)I",
@@ -468,6 +499,7 @@
         {"nativeOpenUinputTouchscreen", "(Ljava/lang/String;IILjava/lang/String;II)I",
          (void*)nativeOpenUinputTouchscreen},
         {"nativeCloseUinput", "(I)Z", (void*)nativeCloseUinput},
+        {"nativeWriteDpadKeyEvent", "(III)Z", (void*)nativeWriteDpadKeyEvent},
         {"nativeWriteKeyEvent", "(III)Z", (void*)nativeWriteKeyEvent},
         {"nativeWriteButtonEvent", "(III)Z", (void*)nativeWriteButtonEvent},
         {"nativeWriteTouchEvent", "(IIIIFFFF)Z", (void*)nativeWriteTouchEvent},
diff --git a/services/core/jni/gnss/Utils.cpp b/services/core/jni/gnss/Utils.cpp
index 8f32c47..571534f 100644
--- a/services/core/jni/gnss/Utils.cpp
+++ b/services/core/jni/gnss/Utils.cpp
@@ -195,6 +195,8 @@
     flags = static_cast<uint32_t>(location.elapsedRealtime.flags);
     if (flags & android::hardware::gnss::ElapsedRealtime::HAS_TIMESTAMP_NS) {
         SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
+    } else {
+        SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());
     }
     if (flags & android::hardware::gnss::ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS) {
         SET(ElapsedRealtimeUncertaintyNanos,
diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml
index 07b763d..33ac735 100644
--- a/services/tests/mockingservicestests/AndroidManifest.xml
+++ b/services/tests/mockingservicestests/AndroidManifest.xml
@@ -34,10 +34,15 @@
     <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
     <uses-permission android:name="android.permission.MANAGE_GAME_ACTIVITY" />
     <uses-permission android:name="android.permission.SET_ALWAYS_FINISH" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+    <uses-permission android:name="android.permission.USE_BIOMETRIC_INTERNAL" />
 
     <!-- needed by MasterClearReceiverTest to display a system dialog -->
     <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
 
+    <!-- needed by TrustManagerServiceTest to access LockSettings' secure storage -->
+    <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
+
     <application android:testOnly="true"
                  android:debuggable="true">
         <uses-library android:name="android.test.runner" />
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index 9bdc93e..6bf102a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -16,7 +16,6 @@
 
 package com.android.server.am;
 
-import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -46,7 +45,6 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
@@ -92,7 +90,8 @@
     private final Impl mImpl;
 
     private enum Impl {
-        DEFAULT
+        DEFAULT,
+        MODERN,
     }
 
     private Context mContext;
@@ -116,7 +115,7 @@
 
     @Parameters(name = "impl={0}")
     public static Collection<Object[]> data() {
-        return Arrays.asList(new Object[][] { {Impl.DEFAULT} });
+        return Arrays.asList(new Object[][] { {Impl.DEFAULT}, {Impl.MODERN} });
     }
 
     public BroadcastQueueTest(Impl impl) {
@@ -152,7 +151,9 @@
             final ApplicationInfo ai = invocation.getArgument(1);
             final ProcessRecord res = makeActiveProcessRecord(ai, processName);
             mHandlerThread.getThreadHandler().post(() -> {
-                mQueue.onApplicationAttachedLocked(res);
+                synchronized (mAms) {
+                    mQueue.onApplicationAttachedLocked(res);
+                }
             });
             return res;
         }).when(mAms).startProcessLocked(any(), any(), anyBoolean(), anyInt(),
@@ -177,6 +178,9 @@
             mQueue = new BroadcastQueueImpl(mAms, mHandlerThread.getThreadHandler(), TAG,
                     constants, emptySkipPolicy, emptyHistory, false,
                     ProcessList.SCHED_GROUP_DEFAULT);
+        } else if (mImpl == Impl.MODERN) {
+            mQueue = new BroadcastQueueModernImpl(mAms, mHandlerThread.getThreadHandler(),
+                    constants, emptySkipPolicy, emptyHistory);
         } else {
             throw new UnsupportedOperationException();
         }
@@ -230,8 +234,10 @@
             Log.v(TAG, "Intercepting scheduleReceiver() for "
                     + Arrays.toString(invocation.getArguments()));
             mHandlerThread.getThreadHandler().post(() -> {
-                mQueue.finishReceiverLocked(r, Activity.RESULT_OK,
-                        null, null, false, false);
+                synchronized (mAms) {
+                    mQueue.finishReceiverLocked(r, Activity.RESULT_OK,
+                            null, null, false, false);
+                }
             });
             return null;
         }).when(thread).scheduleReceiver(any(), any(), any(), anyInt(), any(), any(), anyBoolean(),
@@ -240,10 +246,15 @@
         doAnswer((invocation) -> {
             Log.v(TAG, "Intercepting scheduleRegisteredReceiver() for "
                     + Arrays.toString(invocation.getArguments()));
-            mHandlerThread.getThreadHandler().post(() -> {
-                mQueue.finishReceiverLocked(r, Activity.RESULT_OK, null, null,
-                        false, false);
-            });
+            final boolean ordered = invocation.getArgument(5);
+            if (ordered) {
+                mHandlerThread.getThreadHandler().post(() -> {
+                    synchronized (mAms) {
+                        mQueue.finishReceiverLocked(r, Activity.RESULT_OK,
+                                null, null, false, false);
+                    }
+                });
+            }
             return null;
         }).when(thread).scheduleRegisteredReceiver(any(), any(), anyInt(), any(), any(),
                 anyBoolean(), anyBoolean(), anyInt(), anyInt());
@@ -302,6 +313,12 @@
         };
     }
 
+    private void enqueueBroadcast(BroadcastRecord r) {
+        synchronized (mAms) {
+            mQueue.enqueueBroadcastLocked(r);
+        }
+    }
+
     private void waitForIdle() throws Exception {
         mQueue.waitForIdle(null);
     }
@@ -349,7 +366,7 @@
         final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN);
 
         final Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(intent, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(intent, callerApp,
                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN))));
 
         waitForIdle();
@@ -368,12 +385,12 @@
         final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);
 
         final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(timezone, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(timezone, callerApp,
                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
                         makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE))));
 
         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(airplane, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp,
                 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE))));
 
         waitForIdle();
@@ -394,12 +411,12 @@
         // the second time it should already be running
 
         final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(timezone, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(timezone, callerApp,
                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
                         makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE))));
 
         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(airplane, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp,
                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN))));
 
         waitForIdle();
@@ -407,7 +424,6 @@
                 getUidForPackage(PACKAGE_GREEN));
         final ProcessRecord receiverBlueApp = mAms.getProcessRecordLocked(PACKAGE_BLUE,
                 getUidForPackage(PACKAGE_BLUE));
-        assertTrue(receiverBlueApp.getPid() > receiverGreenApp.getPid());
         verifyScheduleReceiver(receiverGreenApp, timezone);
         verifyScheduleReceiver(receiverGreenApp, airplane);
         verifyScheduleReceiver(receiverBlueApp, timezone);
@@ -423,7 +439,7 @@
         final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN);
 
         final Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(intent, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(intent, callerApp,
                 List.of(makeRegisteredReceiver(receiverApp))));
 
         waitForIdle();
@@ -442,12 +458,12 @@
         final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);
 
         final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(timezone, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(timezone, callerApp,
                 List.of(makeRegisteredReceiver(receiverGreenApp),
                         makeRegisteredReceiver(receiverBlueApp))));
 
         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(airplane, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp,
                 List.of(makeRegisteredReceiver(receiverBlueApp))));
 
         waitForIdle();
@@ -468,14 +484,14 @@
         final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW);
 
         final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(timezone, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(timezone, callerApp,
                 List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
                         makeRegisteredReceiver(receiverGreenApp),
                         makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE),
                         makeRegisteredReceiver(receiverYellowApp))));
 
         final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mQueue.enqueueBroadcastLocked(makeBroadcastRecord(airplane, callerApp,
+        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp,
                 List.of(makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW))));
 
         waitForIdle();
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index 9acc5b9..c0688d1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -15,10 +15,8 @@
  */
 package com.android.server.appop;
 
-import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_ERRORED;
-import static android.app.AppOpsManager.MODE_FOREGROUND;
 import static android.app.AppOpsManager.OP_COARSE_LOCATION;
 import static android.app.AppOpsManager.OP_FLAGS_ALL;
 import static android.app.AppOpsManager.OP_READ_SMS;
@@ -41,7 +39,6 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 
-import android.app.ActivityManager;
 import android.app.AppOpsManager.OpEntry;
 import android.app.AppOpsManager.PackageOps;
 import android.content.ContentResolver;
@@ -335,124 +332,6 @@
         assertThat(getLoggedOps()).isNull();
     }
 
-    private void setupProcStateTests() {
-        // For the location proc state tests
-        mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_FOREGROUND);
-        mAppOpsService.mConstants.FG_SERVICE_STATE_SETTLE_TIME = 0;
-        mAppOpsService.mConstants.TOP_STATE_SETTLE_TIME = 0;
-        mAppOpsService.mConstants.BG_STATE_SETTLE_TIME = 0;
-    }
-
-    @Test
-    public void testUidProcStateChange_cachedToTopToCached() throws Exception {
-        setupProcStateTests();
-
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
-                ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        // Second time to make sure that settle time is overcome
-        Thread.sleep(50);
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-    }
-
-    @Test
-    public void testUidProcStateChange_cachedToFgs() {
-        setupProcStateTests();
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-    }
-
-    @Test
-    public void testUidProcStateChange_cachedToFgsLocation() {
-        setupProcStateTests();
-
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
-                ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
-    }
-
-    @Test
-    public void testUidProcStateChange_topToFgs() throws Exception {
-        setupProcStateTests();
-
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
-                ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        // Second time to make sure that settle time is overcome
-        Thread.sleep(50);
-        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-    }
-
-    @Test
-    public void testUidProcStateChange_topToFgsLocationToFgs() throws Exception {
-        setupProcStateTests();
-
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
-                ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
-                ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
-        // Second time to make sure that settle time is overcome
-        Thread.sleep(50);
-        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
-                ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
-
-        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        // Second time to make sure that settle time is overcome
-        Thread.sleep(50);
-        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
-        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
-                false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
-    }
-
     private List<PackageOps> getLoggedOps() {
         return mAppOpsService.getOpsForPackage(mMyUid, sMyPackageName, null /* all ops */);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java
new file mode 100644
index 0000000..86e12647
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java
@@ -0,0 +1,910 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.appop;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_FOREGROUND;
+import static android.app.AppOpsManager.MODE_IGNORED;
+import static android.app.AppOpsManager.OP_CAMERA;
+import static android.app.AppOpsManager.OP_COARSE_LOCATION;
+import static android.app.AppOpsManager.OP_FINE_LOCATION;
+import static android.app.AppOpsManager.OP_RECORD_AUDIO;
+import static android.app.AppOpsManager.OP_WIFI_SCAN;
+import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
+import static android.app.AppOpsManager.UID_STATE_CACHED;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
+import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
+import static android.app.AppOpsManager.UID_STATE_TOP;
+
+import static com.android.server.appop.AppOpsUidStateTracker.processStateToUidState;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.AppOpsManager;
+import android.os.Handler;
+import android.os.Message;
+import android.util.SparseArray;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.internal.os.Clock;
+import com.android.server.appop.AppOpsUidStateTracker.UidStateChangedCallback;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.quality.Strictness;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class AppOpsUidStateTrackerTest {
+
+    private static final int UID = 10001;
+
+    // An op code that's not location/cam/mic so that we can test the code for evaluating mode
+    // without a specific capability associated with it.
+    public static final int OP_NO_CAPABILITIES = OP_WIFI_SCAN;
+
+    @Mock
+    ActivityManagerInternal mAmi;
+
+    @Mock
+    Handler mHandler;
+
+    @Mock
+    AppOpsService.Constants mConstants;
+
+    AppOpsUidStateTrackerTestClock mClock = new AppOpsUidStateTrackerTestClock();
+
+    AppOpsUidStateTracker mIntf;
+
+    StaticMockitoSession mSession;
+
+    @Before
+    public void setUp() {
+        mSession = ExtendedMockito.mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.LENIENT)
+                .startMocking();
+        mConstants.TOP_STATE_SETTLE_TIME = 10 * 1000L;
+        mConstants.FG_SERVICE_STATE_SETTLE_TIME = 5 * 1000L;
+        mConstants.BG_STATE_SETTLE_TIME = 1 * 1000L;
+        mIntf = new AppOpsUidStateTrackerImpl(mAmi, mHandler, mClock, mConstants);
+    }
+
+    @After
+    public void tearDown() {
+        mSession.finishMocking();
+    }
+
+    /**
+     * This class makes the assumption that all ops are restricted at the same state, this is likely
+     * to be the case forever or become obsolete with the capability mechanism. If this fails
+     * something in {@link AppOpsUidStateTrackerImpl} might break when reporting if foreground mode
+     * might change.
+     */
+    @Test
+    public void testConstantFirstUnrestrictedUidState() {
+        for (int i = 0; i < AppOpsManager.getNumOps(); i++) {
+            assertEquals(UID_STATE_MAX_LAST_NON_RESTRICTED,
+                    AppOpsManager.resolveFirstUnrestrictedUidState(i));
+        }
+    }
+
+    @Test
+    public void testNoCapability() {
+        procStateBuilder(UID)
+                .topState()
+                .update();
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testForegroundWithMicrophoneCapability() {
+        procStateBuilder(UID)
+                .topState()
+                .microphoneCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testBackgroundWithMicrophoneCapability() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .microphoneCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testForegroundWithCameraCapability() {
+        procStateBuilder(UID)
+                .topState()
+                .cameraCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testBackgroundWithCameraCapability() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .cameraCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testForegroundWithLocationCapability() {
+        procStateBuilder(UID)
+                .topState()
+                .locationCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testBackgroundWithLocationCapability() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .locationCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testForegroundNotCapabilitiesTracked() {
+        procStateBuilder(UID)
+                .topState()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_NO_CAPABILITIES, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testBackgroundNotCapabilitiesTracked() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_NO_CAPABILITIES, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testBackgroundToForegroundTransition() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+        assertBackground(UID);
+
+        procStateBuilder(UID)
+                .topState()
+                .update();
+        assertForeground(UID);
+    }
+
+    @Test
+    public void testForegroundToBackgroundTransition() {
+        procStateBuilder(UID)
+                .topState()
+                .update();
+        assertForeground(UID);
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+        // Still in foreground due to settle time
+        assertForeground(UID);
+
+        AtomicReference<Message> messageAtomicReference = new AtomicReference<>();
+        AtomicLong delayAtomicReference = new AtomicLong();
+
+        getPostDelayedMessageArguments(messageAtomicReference, delayAtomicReference);
+        Message message = messageAtomicReference.get();
+        long delay = delayAtomicReference.get();
+
+        assertNotNull(message);
+        assertEquals(mConstants.TOP_STATE_SETTLE_TIME + 1, delay);
+
+        mClock.advanceTime(mConstants.TOP_STATE_SETTLE_TIME + 1);
+        message.getCallback().run();
+        assertBackground(UID);
+    }
+
+    @Test
+    public void testForegroundServiceToBackgroundTransition() {
+        procStateBuilder(UID)
+                .foregroundServiceState()
+                .update();
+        assertForeground(UID);
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+        // Still in foreground due to settle time
+        assertForeground(UID);
+
+        AtomicReference<Message> messageAtomicReference = new AtomicReference<>();
+        AtomicLong delayAtomicReference = new AtomicLong();
+
+        getPostDelayedMessageArguments(messageAtomicReference, delayAtomicReference);
+        Message message = messageAtomicReference.get();
+        long delay = delayAtomicReference.get();
+
+        assertNotNull(message);
+        assertEquals(mConstants.FG_SERVICE_STATE_SETTLE_TIME + 1, delay);
+
+        mClock.advanceTime(mConstants.FG_SERVICE_STATE_SETTLE_TIME + 1);
+        message.getCallback().run();
+        assertBackground(UID);
+    }
+
+    @Test
+    public void testEarlyUpdateDoesntCommit() {
+        procStateBuilder(UID)
+                .foregroundServiceState()
+                .update();
+        assertForeground(UID);
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+        // Still in foreground due to settle time
+        assertForeground(UID);
+
+        AtomicReference<Message> messageAtomicReference = new AtomicReference<>();
+
+        getPostDelayedMessageArguments(messageAtomicReference, null);
+        Message message = messageAtomicReference.get();
+
+        // 1 ms short of settle time
+        mClock.advanceTime(mConstants.FG_SERVICE_STATE_SETTLE_TIME - 1);
+        message.getCallback().run();
+        assertForeground(UID);
+    }
+
+    @Test
+    public void testMicrophoneCapabilityAdded() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .microphoneCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testMicrophoneCapabilityRemoved() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .microphoneCapability()
+                .update();
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testCameraCapabilityAdded() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .cameraCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testCameraCapabilityRemoved() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .cameraCapability()
+                .update();
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testLocationCapabilityAdded() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .locationCapability()
+                .update();
+
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testLocationCapabilityRemoved() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .locationCapability()
+                .update();
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testVisibleAppWidget() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        SparseArray<String> appPackageNames = new SparseArray<>();
+        appPackageNames.put(UID, "");
+        mIntf.updateAppWidgetVisibility(appPackageNames, true);
+
+        assertForeground(UID);
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testPendingTop() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        doReturn(true).when(mAmi).isPendingTopUid(eq(UID));
+
+        assertForeground(UID);
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testTempAllowlist() {
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        doReturn(true).when(mAmi).isTempAllowlistedForFgsWhileInUse(eq(UID));
+
+        assertForeground(UID);
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+    }
+
+    @Test
+    public void testUidStateChangedCallbackNewProcessTop() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .topState()
+                .update();
+
+        getLatestPostMessageArgument().getCallback().run();
+
+        verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_TOP), eq(true));
+    }
+
+    @Test
+    public void testUidStateChangedCallbackNewProcessForegroundService() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .foregroundServiceState()
+                .update();
+
+        getLatestPostMessageArgument().getCallback().run();
+
+        verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_FOREGROUND_SERVICE), eq(true));
+    }
+
+    @Test
+    public void testUidStateChangedCallbackNewProcessForeground() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .foregroundState()
+                .update();
+
+        getLatestPostMessageArgument().getCallback().run();
+
+        verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_FOREGROUND), eq(true));
+    }
+
+    @Test
+    public void testUidStateChangedCallbackNewProcessBackground() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        getLatestPostMessageArgument().getCallback().run();
+
+        verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_BACKGROUND), eq(false));
+    }
+
+    @Test
+    public void testUidStateChangedCallbackNewProcessCached() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .cachedState()
+                .update();
+
+        // Cached is the default, no change in uid state.
+        verify(cb, times(0)).onUidStateChanged(anyInt(), anyInt(), anyBoolean());
+    }
+
+    @Test
+    public void testUidStateChangedCallbackCachedToBackground() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
+                ActivityManager.PROCESS_STATE_RECEIVER);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackCachedToForeground() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
+                ActivityManager.PROCESS_STATE_BOUND_TOP);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackCachedToForegroundService() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackCachedToTop() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
+                ActivityManager.PROCESS_STATE_TOP);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackBackgroundToCached() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_RECEIVER,
+                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackBackgroundToForeground() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_RECEIVER,
+                ActivityManager.PROCESS_STATE_BOUND_TOP);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackBackgroundToForegroundService() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_RECEIVER,
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackBackgroundToTop() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_RECEIVER,
+                ActivityManager.PROCESS_STATE_TOP);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundToCached() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_BOUND_TOP,
+                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundToBackground() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_BOUND_TOP,
+                ActivityManager.PROCESS_STATE_RECEIVER);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundToForegroundService() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_BOUND_TOP,
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundToTop() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_BOUND_TOP,
+                ActivityManager.PROCESS_STATE_TOP);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundServiceToCached() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundServiceToBackground() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+                ActivityManager.PROCESS_STATE_RECEIVER);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundServiceToForeground() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+                ActivityManager.PROCESS_STATE_BOUND_TOP);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundServiceToTop() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+                ActivityManager.PROCESS_STATE_TOP);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackTopToCached() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_TOP,
+                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackTopToBackground() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_TOP,
+                ActivityManager.PROCESS_STATE_RECEIVER);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackTopToForeground() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_TOP,
+                ActivityManager.PROCESS_STATE_BOUND_TOP);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackTopToForegroundService() {
+        testUidStateChangedCallback(
+                ActivityManager.PROCESS_STATE_TOP,
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+    }
+
+    @Test
+    public void testUidStateChangedCallbackCachedToNonexistent() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .cachedState()
+                .update();
+
+        procStateBuilder(UID)
+                .nonExistentState()
+                .update();
+
+        verify(mHandler, never()).post(any());
+        verify(cb, never()).onUidStateChanged(anyInt(), anyInt(), anyBoolean());
+    }
+
+    @Test
+    public void testUidStateChangedCallbackBackgroundToNonexistent() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .backgroundState()
+                .update();
+
+        procStateBuilder(UID)
+                .nonExistentState()
+                .update();
+
+        getLatestPostMessageArgument().getCallback().run();
+        verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(false));
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundToNonexistent() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .foregroundState()
+                .update();
+
+        procStateBuilder(UID)
+                .nonExistentState()
+                .update();
+
+        getLatestPostMessageArgument().getCallback().run();
+        verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true));
+    }
+
+    @Test
+    public void testUidStateChangedCallbackForegroundServiceToNonexistent() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .foregroundServiceState()
+                .update();
+
+        procStateBuilder(UID)
+                .nonExistentState()
+                .update();
+
+        getLatestPostMessageArgument().getCallback().run();
+        verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true));
+    }
+
+    @Test
+    public void testUidStateChangedCallbackTopToNonexistent() {
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .topState()
+                .update();
+
+        procStateBuilder(UID)
+                .nonExistentState()
+                .update();
+
+        getLatestPostMessageArgument().getCallback().run();
+        verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true));
+    }
+
+    public void testUidStateChangedCallback(int initialState, int finalState) {
+        int initialUidState = processStateToUidState(initialState);
+        int finalUidState = processStateToUidState(finalState);
+        boolean foregroundChange = initialUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED
+                        != finalUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED;
+        boolean finalUidStateIsBackgroundAndLessImportant =
+                finalUidState > UID_STATE_MAX_LAST_NON_RESTRICTED
+                        && finalUidState > initialUidState;
+
+        UidStateChangedCallback cb = addUidStateChangeCallback();
+
+        procStateBuilder(UID)
+                .setState(initialState)
+                .update();
+
+        procStateBuilder(UID)
+                .setState(finalState)
+                .update();
+
+        if (finalUidStateIsBackgroundAndLessImportant) {
+            AtomicReference<Message> delayedMessage = new AtomicReference<>();
+            getPostDelayedMessageArguments(delayedMessage, new AtomicLong());
+            mClock.advanceTime(mConstants.TOP_STATE_SETTLE_TIME + 1);
+            delayedMessage.get().getCallback().run();
+        }
+
+        getLatestPostMessageArgument().getCallback().run();
+        verify(cb, atLeastOnce())
+                .onUidStateChanged(eq(UID), eq(finalUidState), eq(foregroundChange));
+    }
+
+    private UidStateChangedCallback addUidStateChangeCallback() {
+        UidStateChangedCallback cb =
+                Mockito.mock(UidStateChangedCallback.class);
+        mIntf.addUidStateChangedCallback(mHandler, cb);
+        return cb;
+    }
+
+    /* If testForegroundNotCapabilitiesTracked fails, this assertion is probably incorrect */
+    private void assertForeground(int uid) {
+        assertEquals(MODE_ALLOWED, mIntf.evalMode(uid, OP_NO_CAPABILITIES, MODE_FOREGROUND));
+    }
+
+    /* If testBackgroundNotCapabilitiesTracked fails, this assertion is probably incorrect */
+    private void assertBackground(int uid) {
+        assertEquals(MODE_IGNORED, mIntf.evalMode(uid, OP_NO_CAPABILITIES, MODE_FOREGROUND));
+    }
+
+    private void getPostDelayedMessageArguments(AtomicReference<Message> message,
+            AtomicLong delay) {
+
+        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+        ArgumentCaptor<Long> delayCaptor = ArgumentCaptor.forClass(Long.class);
+
+        verify(mHandler).sendMessageDelayed(messageCaptor.capture(), delayCaptor.capture());
+
+        if (message != null) {
+            message.set(messageCaptor.getValue());
+        }
+        if (delay != null) {
+            delay.set(delayCaptor.getValue());
+        }
+    }
+
+    private Message getLatestPostMessageArgument() {
+        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+
+        verify(mHandler, atLeast(1)).sendMessage(messageCaptor.capture());
+
+        return messageCaptor.getValue();
+    }
+
+    private UidProcStateUpdateBuilder procStateBuilder(int uid) {
+        return new UidProcStateUpdateBuilder(mIntf, uid);
+    }
+
+    private static class UidProcStateUpdateBuilder {
+        private AppOpsUidStateTracker mIntf;
+        private int mUid;
+        private int mProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
+        private int mCapability = 0;
+
+        private UidProcStateUpdateBuilder(AppOpsUidStateTracker intf, int uid) {
+            mUid = uid;
+            mIntf = intf;
+        }
+
+        public void update() {
+            mIntf.updateUidProcState(mUid, mProcState, mCapability);
+        }
+
+        public UidProcStateUpdateBuilder persistentState() {
+            mProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder setState(int procState) {
+            mProcState = procState;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder topState() {
+            mProcState = ActivityManager.PROCESS_STATE_TOP;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder foregroundServiceState() {
+            mProcState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder foregroundState() {
+            mProcState = ActivityManager.PROCESS_STATE_BOUND_TOP;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder backgroundState() {
+            mProcState = ActivityManager.PROCESS_STATE_SERVICE;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder cachedState() {
+            mProcState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder nonExistentState() {
+            mProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder locationCapability() {
+            mCapability |= ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder cameraCapability() {
+            mCapability |= ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
+            return this;
+        }
+
+        public UidProcStateUpdateBuilder microphoneCapability() {
+            mCapability |= ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+            return this;
+        }
+    }
+
+    private static class AppOpsUidStateTrackerTestClock extends Clock {
+
+        long mElapsedRealTime = 0x5f3759df;
+
+        @Override
+        public long elapsedRealtime() {
+            return mElapsedRealTime;
+        }
+
+        void advanceTime(long time) {
+            mElapsedRealTime += time;
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
index bc9e9bb..941a3a4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
@@ -16,14 +16,18 @@
 
 package com.android.server.display.color;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assert.assertArrayEquals;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.hardware.display.DisplayManagerInternal;
 import android.os.Binder;
 import android.os.IBinder;
 import android.view.SurfaceControl;
@@ -50,6 +54,8 @@
     private Context mMockedContext;
     @Mock
     private Resources mMockedResources;
+    @Mock
+    private DisplayManagerInternal mDisplayManagerInternal;
 
     private MockitoSession mSession;
     private Resources mResources;
@@ -81,7 +87,6 @@
         doReturn(mMockedResources).when(mMockedContext).getResources();
 
         mDisplayToken = new Binder();
-        doReturn(mDisplayToken).when(() -> SurfaceControl.getInternalDisplayToken());
     }
 
     @After
@@ -114,8 +119,8 @@
         displayPrimaries.white.X = 0.950456f;
         displayPrimaries.white.Y = 1.000000f;
         displayPrimaries.white.Z = 1.089058f;
-        doReturn(displayPrimaries)
-            .when(() -> SurfaceControl.getDisplayNativePrimaries(mDisplayToken));
+        when(mDisplayManagerInternal.getDisplayNativePrimaries(DEFAULT_DISPLAY))
+                .thenReturn(displayPrimaries);
 
         setUpTintController();
         assertWithMessage("Setup with valid SurfaceControl failed")
@@ -134,8 +139,8 @@
         displayPrimaries.green = new CieXyz();
         displayPrimaries.blue = new CieXyz();
         displayPrimaries.white = new CieXyz();
-        doReturn(displayPrimaries)
-            .when(() -> SurfaceControl.getDisplayNativePrimaries(mDisplayToken));
+        when(mDisplayManagerInternal.getDisplayNativePrimaries(DEFAULT_DISPLAY))
+                .thenReturn(displayPrimaries);
 
         setUpTintController();
         assertWithMessage("Setup with invalid SurfaceControl succeeded")
@@ -154,7 +159,7 @@
             .when(mMockedResources)
             .getStringArray(R.array.config_displayWhiteBalanceDisplayPrimaries);
         // Make SurfaceControl setup fail
-        doReturn(null).when(() -> SurfaceControl.getDisplayNativePrimaries(mDisplayToken));
+        when(mDisplayManagerInternal.getDisplayNativePrimaries(DEFAULT_DISPLAY)).thenReturn(null);
 
         setUpTintController();
         assertWithMessage("Setup with valid Resources failed")
@@ -178,7 +183,7 @@
             .when(mMockedResources)
             .getStringArray(R.array.config_displayWhiteBalanceDisplayPrimaries);
         // Make SurfaceControl setup fail
-        doReturn(null).when(() -> SurfaceControl.getDisplayNativePrimaries(mDisplayToken));
+        when(mDisplayManagerInternal.getDisplayNativePrimaries(DEFAULT_DISPLAY)).thenReturn(null);
 
         setUpTintController();
         assertWithMessage("Setup with invalid Resources succeeded")
@@ -208,8 +213,8 @@
         displayPrimaries.white.X = 0.950456f;
         displayPrimaries.white.Y = 1.000000f;
         displayPrimaries.white.Z = 1.089058f;
-        doReturn(displayPrimaries)
-                .when(() -> SurfaceControl.getDisplayNativePrimaries(mDisplayToken));
+        when(mDisplayManagerInternal.getDisplayNativePrimaries(DEFAULT_DISPLAY))
+                .thenReturn(displayPrimaries);
 
         setUpTintController();
         assertWithMessage("Setup with valid SurfaceControl failed")
@@ -234,7 +239,8 @@
     }
 
     private void setUpTintController() {
-        mDisplayWhiteBalanceTintController = new DisplayWhiteBalanceTintController();
+        mDisplayWhiteBalanceTintController = new DisplayWhiteBalanceTintController(
+                mDisplayManagerInternal);
         mDisplayWhiteBalanceTintController.setUp(mMockedContext, true);
         mDisplayWhiteBalanceTintController.setActivated(true);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerInternalTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerInternalTest.java
index 574bab2..245b4dc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerInternalTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerInternalTest.java
@@ -163,6 +163,23 @@
     }
 
     @Test
+    public void testAssignUserToDisplay_userAlreadyAssigned() {
+        enableUsersOnSecondaryDisplays();
+
+        mUmi.assignUserToDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+
+        IllegalStateException e = assertThrows(IllegalStateException.class,
+                () -> mUmi.assignUserToDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID));
+
+        Log.v(TAG, "Exception: " + e);
+        assertWithMessage("exception (%s) message", e).that(e).hasMessageThat()
+                .matches("Cannot.*" + USER_ID + ".*" + OTHER_SECONDARY_DISPLAY_ID + ".*already.*"
+                        + SECONDARY_DISPLAY_ID + ".*");
+
+        assertUserAssignedToDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+    }
+
+    @Test
     public void testAssignUserToDisplay_profileOnSameDisplayAsParent() {
         enableUsersOnSecondaryDisplays();
         addDefaultProfileAndParent();
diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
new file mode 100644
index 0000000..33870f1
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.trust;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.argThat;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.test.TestLooper;
+import android.provider.Settings;
+import android.service.trust.TrustAgentService;
+import android.testing.TestableContext;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.SystemServiceManager;
+
+import com.google.android.collect.Lists;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class TrustManagerServiceTest {
+
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule
+    public final MockContext mMockContext = new MockContext(
+            ApplicationProvider.getApplicationContext());
+
+    private static final String URI_SCHEME_PACKAGE = "package";
+    private static final int TEST_USER_ID = UserHandle.USER_SYSTEM;
+
+    private final TestLooper mLooper = new TestLooper();
+    private final ArrayList<ResolveInfo> mTrustAgentResolveInfoList = new ArrayList<>();
+    private final LockPatternUtils mLockPatternUtils = new LockPatternUtils(mMockContext);
+    private final TrustManagerService mService = new TrustManagerService(mMockContext);
+
+    @Mock
+    private PackageManager mPackageManagerMock;
+
+    @Before
+    public void setUp() {
+        resetTrustAgentLockSettings();
+        LocalServices.addService(SystemServiceManager.class, mock(SystemServiceManager.class));
+
+        ArgumentMatcher<Intent> trustAgentIntentMatcher = new ArgumentMatcher<Intent>() {
+            @Override
+            public boolean matches(Intent argument) {
+                return TrustAgentService.SERVICE_INTERFACE.equals(argument.getAction());
+            }
+        };
+        when(mPackageManagerMock.queryIntentServicesAsUser(argThat(trustAgentIntentMatcher),
+                anyInt(), anyInt())).thenReturn(mTrustAgentResolveInfoList);
+        when(mPackageManagerMock.checkPermission(any(), any())).thenReturn(
+                PackageManager.PERMISSION_GRANTED);
+        mMockContext.setMockPackageManager(mPackageManagerMock);
+    }
+
+    @After
+    public void tearDown() {
+        resetTrustAgentLockSettings();
+        LocalServices.removeServiceForTest(SystemServiceManager.class);
+    }
+
+    @Test
+    public void firstBootCompleted_systemTrustAgentsEnabled() {
+        ComponentName systemTrustAgent1 = ComponentName.unflattenFromString(
+                "com.android/.SystemTrustAgent");
+        ComponentName systemTrustAgent2 = ComponentName.unflattenFromString(
+                "com.android/.AnotherSystemTrustAgent");
+        ComponentName userTrustAgent1 = ComponentName.unflattenFromString(
+                "com.user/.UserTrustAgent");
+        ComponentName userTrustAgent2 = ComponentName.unflattenFromString(
+                "com.user/.AnotherUserTrustAgent");
+        addTrustAgent(systemTrustAgent1, /* isSystemApp= */ true);
+        addTrustAgent(systemTrustAgent2, /* isSystemApp= */ true);
+        addTrustAgent(userTrustAgent1, /* isSystemApp= */ false);
+        addTrustAgent(userTrustAgent2, /* isSystemApp= */ false);
+
+        bootService();
+
+        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
+                systemTrustAgent1, systemTrustAgent2);
+        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
+                systemTrustAgent1, systemTrustAgent2, userTrustAgent1, userTrustAgent2);
+    }
+
+    @Test
+    public void firstBootCompleted_defaultTrustAgentEnabled() {
+        ComponentName systemTrustAgent = ComponentName.unflattenFromString(
+                "com.android/.SystemTrustAgent");
+        ComponentName defaultTrustAgent = ComponentName.unflattenFromString(
+                "com.user/.DefaultTrustAgent");
+        addTrustAgent(systemTrustAgent, /* isSystemApp= */ true);
+        addTrustAgent(defaultTrustAgent, /* isSystemApp= */ false);
+        mMockContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.string.config_defaultTrustAgent,
+                defaultTrustAgent.flattenToString());
+
+        bootService();
+
+        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
+                defaultTrustAgent);
+        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
+                systemTrustAgent, defaultTrustAgent);
+    }
+
+    @Test
+    public void serviceBooted_knownAgentsNotSet_enabledAgentsNotUpdated() {
+        ComponentName trustAgent1 = ComponentName.unflattenFromString(
+                "com.android/.SystemTrustAgent");
+        ComponentName trustAgent2 = ComponentName.unflattenFromString(
+                "com.android/.AnotherSystemTrustAgent");
+        initializeEnabledAgents(trustAgent1);
+        addTrustAgent(trustAgent1, /* isSystemApp= */ true);
+        addTrustAgent(trustAgent2, /* isSystemApp= */ true);
+
+        bootService();
+
+        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
+                trustAgent1);
+        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
+                trustAgent1, trustAgent2);
+    }
+
+    @Test
+    public void serviceBooted_knownAgentsSet_enabledAgentsUpdated() {
+        ComponentName trustAgent1 = ComponentName.unflattenFromString(
+                "com.android/.SystemTrustAgent");
+        ComponentName trustAgent2 = ComponentName.unflattenFromString(
+                "com.android/.AnotherSystemTrustAgent");
+        initializeEnabledAgents(trustAgent1);
+        initializeKnownAgents(trustAgent1);
+        addTrustAgent(trustAgent1, /* isSystemApp= */ true);
+        addTrustAgent(trustAgent2, /* isSystemApp= */ true);
+
+        bootService();
+
+        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
+                trustAgent1, trustAgent2);
+        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
+                trustAgent1, trustAgent2);
+    }
+
+    @Test
+    public void newSystemTrustAgent_setToEnabledAndKnown() {
+        bootService();
+        ComponentName newAgentComponentName = ComponentName.unflattenFromString(
+                "com.android/.SystemTrustAgent");
+        addTrustAgent(newAgentComponentName, /* isSystemApp= */ true);
+
+        mMockContext.sendPackageChangedBroadcast(newAgentComponentName);
+
+        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
+                newAgentComponentName);
+        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
+                newAgentComponentName);
+    }
+
+    @Test
+    public void newSystemTrustAgent_notEnabledWhenDefaultAgentIsSet() {
+        ComponentName defaultTrustAgent = ComponentName.unflattenFromString(
+                "com.user/.DefaultTrustAgent");
+        addTrustAgent(defaultTrustAgent, /* isSystemApp= */ false);
+        mMockContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.string.config_defaultTrustAgent,
+                defaultTrustAgent.flattenToString());
+        bootService();
+        ComponentName newAgentComponentName = ComponentName.unflattenFromString(
+                "com.android/.SystemTrustAgent");
+        addTrustAgent(newAgentComponentName, /* isSystemApp= */ true);
+
+        mMockContext.sendPackageChangedBroadcast(newAgentComponentName);
+
+        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
+                defaultTrustAgent);
+        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
+                defaultTrustAgent, newAgentComponentName);
+    }
+
+    @Test
+    public void newNonSystemTrustAgent_notEnabledButMarkedAsKnown() {
+        bootService();
+        ComponentName newAgentComponentName = ComponentName.unflattenFromString(
+                "com.user/.UserTrustAgent");
+        addTrustAgent(newAgentComponentName, /* isSystemApp= */ false);
+
+        mMockContext.sendPackageChangedBroadcast(newAgentComponentName);
+
+        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).isEmpty();
+        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
+                newAgentComponentName);
+    }
+
+    @Test
+    public void existingTrustAgentChanged_notEnabled() {
+        ComponentName systemTrustAgent1 = ComponentName.unflattenFromString(
+                "com.android/.SystemTrustAgent");
+        ComponentName systemTrustAgent2 = ComponentName.unflattenFromString(
+                "com.android/.AnotherSystemTrustAgent");
+        addTrustAgent(systemTrustAgent1, /* isSystemApp= */ true);
+        addTrustAgent(systemTrustAgent2, /* isSystemApp= */ true);
+        bootService();
+        // Simulate user turning off systemTrustAgent2
+        mLockPatternUtils.setEnabledTrustAgents(Collections.singletonList(systemTrustAgent1),
+                TEST_USER_ID);
+
+        mMockContext.sendPackageChangedBroadcast(systemTrustAgent2);
+
+        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
+                systemTrustAgent1);
+    }
+
+    private void addTrustAgent(ComponentName agentComponentName, boolean isSystemApp) {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        if (isSystemApp) {
+            applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+        }
+
+        ServiceInfo serviceInfo = new ServiceInfo();
+        serviceInfo.packageName = agentComponentName.getPackageName();
+        serviceInfo.name = agentComponentName.getClassName();
+        serviceInfo.applicationInfo = applicationInfo;
+
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.serviceInfo = serviceInfo;
+        mTrustAgentResolveInfoList.add(resolveInfo);
+    }
+
+    private void initializeEnabledAgents(ComponentName... enabledAgents) {
+        mLockPatternUtils.setEnabledTrustAgents(Lists.newArrayList(enabledAgents), TEST_USER_ID);
+        Settings.Secure.putIntForUser(mMockContext.getContentResolver(),
+                Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID);
+    }
+
+    private void initializeKnownAgents(ComponentName... knownAgents) {
+        mLockPatternUtils.setKnownTrustAgents(Lists.newArrayList(knownAgents), TEST_USER_ID);
+        Settings.Secure.putIntForUser(mMockContext.getContentResolver(),
+                Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID);
+    }
+
+    private void bootService() {
+        mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+        mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
+        mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+    }
+
+    private void resetTrustAgentLockSettings() {
+        mLockPatternUtils.setEnabledTrustAgents(Collections.emptyList(), TEST_USER_ID);
+        mLockPatternUtils.setKnownTrustAgents(Collections.emptyList(), TEST_USER_ID);
+    }
+
+    /** A mock Context that allows the test process to send protected broadcasts. */
+    private static final class MockContext extends TestableContext {
+
+        private final ArrayList<BroadcastReceiver> mPackageChangedBroadcastReceivers =
+                new ArrayList<>();
+
+        MockContext(Context base) {
+            super(base);
+        }
+
+        @Override
+        @Nullable
+        public Intent registerReceiverAsUser(BroadcastReceiver receiver,
+                UserHandle user, IntentFilter filter, @Nullable String broadcastPermission,
+                @Nullable Handler scheduler) {
+
+            if (filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)) {
+                mPackageChangedBroadcastReceivers.add(receiver);
+            }
+            return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
+                    scheduler);
+        }
+
+        void sendPackageChangedBroadcast(ComponentName changedComponent) {
+            Intent intent = new Intent(
+                    Intent.ACTION_PACKAGE_CHANGED,
+                    Uri.fromParts(URI_SCHEME_PACKAGE,
+                            changedComponent.getPackageName(), /* fragment= */ null))
+                    .putExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST,
+                            new String[]{changedComponent.getClassName()})
+                    .putExtra(Intent.EXTRA_USER_HANDLE, TEST_USER_ID)
+                    .putExtra(Intent.EXTRA_UID, UserHandle.of(TEST_USER_ID).getUid(1234));
+            for (BroadcastReceiver receiver : mPackageChangedBroadcastReceivers) {
+                receiver.onReceive(this, intent);
+            }
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/utils/AlarmQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/utils/AlarmQueueTest.java
index 849e673..00d7541 100644
--- a/services/tests/mockingservicestests/src/com/android/server/utils/AlarmQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/utils/AlarmQueueTest.java
@@ -155,6 +155,27 @@
                 anyInt(), eq(nowElapsed + HOUR_IN_MILLIS), eq(ALARM_TAG), any(), any());
     }
 
+    @Test
+    public void testAddingLargeAlarmTimes() {
+        final AlarmQueue<String> alarmQueue = createAlarmQueue(true, 0);
+        final long nowElapsed = mInjector.getElapsedRealtime();
+
+        InOrder inOrder = inOrder(mAlarmManager);
+
+        alarmQueue.addAlarm("com.android.test.1", Long.MAX_VALUE - 5);
+        inOrder.verify(mAlarmManager, timeout(1000).times(1))
+                .setExact(anyInt(), eq(Long.MAX_VALUE - 5), eq(ALARM_TAG), any(), any());
+        alarmQueue.addAlarm("com.android.test.2", Long.MAX_VALUE - 4);
+        inOrder.verify(mAlarmManager, never())
+                .setExact(anyInt(), anyLong(), eq(ALARM_TAG), any(), any());
+        alarmQueue.addAlarm("com.android.test.3", nowElapsed + 5);
+        inOrder.verify(mAlarmManager, timeout(1000).times(1))
+                .setExact(anyInt(), eq(nowElapsed + 5), eq(ALARM_TAG), any(), any());
+        alarmQueue.addAlarm("com.android.test.4", nowElapsed + 6);
+        inOrder.verify(mAlarmManager, never())
+                .setExact(anyInt(), anyLong(), eq(ALARM_TAG), any(), any());
+    }
+
     /**
      * Verify that updating the alarm time for a key will result in the AlarmManager alarm changing,
      * if needed.
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/InputManagerMockHelper.java b/services/tests/servicestests/src/com/android/server/companion/virtual/InputManagerMockHelper.java
index cc5ed92..51bd5b0f 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/InputManagerMockHelper.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/InputManagerMockHelper.java
@@ -57,6 +57,8 @@
 
         doAnswer(this::handleNativeOpenInputDevice).when(mNativeWrapperMock).openUinputMouse(
                 anyString(), anyInt(), anyInt(), anyString());
+        doAnswer(this::handleNativeOpenInputDevice).when(mNativeWrapperMock).openUinputDpad(
+                anyString(), anyInt(), anyInt(), anyString());
         doAnswer(this::handleNativeOpenInputDevice).when(mNativeWrapperMock).openUinputKeyboard(
                 anyString(), anyInt(), anyInt(), anyString());
         doAnswer(this::handleNativeOpenInputDevice).when(mNativeWrapperMock).openUinputTouchscreen(
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index cc2cdba..ef203d0 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -387,6 +387,14 @@
     }
 
     @Test
+    public void createVirtualDpad_noDisplay_failsSecurityException() {
+        assertThrows(
+                SecurityException.class,
+                () -> mDeviceImpl.createVirtualDpad(DISPLAY_ID, DEVICE_NAME, VENDOR_ID,
+                        PRODUCT_ID, BINDER));
+    }
+
+    @Test
     public void createVirtualKeyboard_noDisplay_failsSecurityException() {
         assertThrows(
                 SecurityException.class,
@@ -418,6 +426,17 @@
     }
 
     @Test
+    public void createVirtualDpad_noPermission_failsSecurityException() {
+        mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
+        doCallRealMethod().when(mContext).enforceCallingOrSelfPermission(
+                eq(Manifest.permission.CREATE_VIRTUAL_DEVICE), anyString());
+        assertThrows(
+                SecurityException.class,
+                () -> mDeviceImpl.createVirtualDpad(DISPLAY_ID, DEVICE_NAME, VENDOR_ID,
+                        PRODUCT_ID, BINDER));
+    }
+
+    @Test
     public void createVirtualKeyboard_noPermission_failsSecurityException() {
         mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
         doCallRealMethod().when(mContext).enforceCallingOrSelfPermission(
@@ -468,6 +487,17 @@
     }
 
     @Test
+    public void createVirtualDpad_hasDisplay_obtainFileDescriptor() {
+        mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
+        mDeviceImpl.createVirtualDpad(DISPLAY_ID, DEVICE_NAME, VENDOR_ID, PRODUCT_ID,
+                BINDER);
+        assertWithMessage("Virtual dpad should register fd when the display matches")
+          	.that(mInputController.mInputDeviceDescriptors).isNotEmpty();
+        verify(mNativeWrapperMock).openUinputDpad(eq(DEVICE_NAME), eq(VENDOR_ID),
+                eq(PRODUCT_ID), anyString());
+    }
+
+    @Test
     public void createVirtualKeyboard_hasDisplay_obtainFileDescriptor() {
         mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
         mDeviceImpl.createVirtualKeyboard(DISPLAY_ID, DEVICE_NAME, VENDOR_ID, PRODUCT_ID,
@@ -483,7 +513,7 @@
         mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
         mDeviceImpl.createVirtualMouse(DISPLAY_ID, DEVICE_NAME, VENDOR_ID, PRODUCT_ID,
                 BINDER);
-        assertWithMessage("Virtual keyboard should register fd when the display matches")
+        assertWithMessage("Virtual mouse should register fd when the display matches")
                 .that(mInputController.mInputDeviceDescriptors).isNotEmpty();
         verify(mNativeWrapperMock).openUinputMouse(eq(DEVICE_NAME), eq(VENDOR_ID), eq(PRODUCT_ID),
                 anyString());
@@ -494,7 +524,7 @@
         mDeviceImpl.mVirtualDisplayIds.add(DISPLAY_ID);
         mDeviceImpl.createVirtualTouchscreen(DISPLAY_ID, DEVICE_NAME, VENDOR_ID, PRODUCT_ID,
                 BINDER, new Point(WIDTH, HEIGHT));
-        assertWithMessage("Virtual keyboard should register fd when the display matches")
+        assertWithMessage("Virtual touchscreen should register fd when the display matches")
                 .that(mInputController.mInputDeviceDescriptors).isNotEmpty();
         verify(mNativeWrapperMock).openUinputTouchscreen(eq(DEVICE_NAME), eq(VENDOR_ID),
                 eq(PRODUCT_ID), anyString(), eq(HEIGHT), eq(WIDTH));
diff --git a/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java b/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
index 4ef156e..e0bef1a 100644
--- a/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
@@ -18,21 +18,26 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import androidx.test.InstrumentationRegistry;
+import static org.mockito.Mockito.mock;
 
-import java.lang.System;
-import java.util.Arrays;
+import android.hardware.display.DisplayManagerInternal;
+
+import androidx.test.InstrumentationRegistry;
 
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.Arrays;
+
 public class DisplayWhiteBalanceTintControllerTest {
 
     private DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController;
 
     @Before
     public void setUp() {
-        mDisplayWhiteBalanceTintController = new DisplayWhiteBalanceTintController();
+        DisplayManagerInternal displayManagerInternal = mock(DisplayManagerInternal.class);
+        mDisplayWhiteBalanceTintController =
+                new DisplayWhiteBalanceTintController(displayManagerInternal);
         mDisplayWhiteBalanceTintController.setUp(InstrumentationRegistry.getContext(), true);
         mDisplayWhiteBalanceTintController.setActivated(true);
     }
diff --git a/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt b/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt
index 6e422fa..d118661 100644
--- a/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt
@@ -20,16 +20,20 @@
 import android.content.ContextWrapper
 import android.hardware.BatteryState.STATUS_CHARGING
 import android.hardware.BatteryState.STATUS_FULL
+import android.hardware.BatteryState.STATUS_UNKNOWN
 import android.hardware.input.IInputDeviceBatteryListener
+import android.hardware.input.IInputDevicesChangedListener
 import android.hardware.input.IInputManager
-import android.hardware.input.InputDeviceCountryCode
 import android.hardware.input.InputManager
 import android.os.Binder
 import android.os.IBinder
+import android.os.test.TestLooper
 import android.platform.test.annotations.Presubmit
 import android.view.InputDevice
 import androidx.test.InstrumentationRegistry
+import com.android.server.input.BatteryController.UEventManager
 import org.junit.After
+import org.junit.Assert.assertEquals
 import org.junit.Assert.fail
 import org.junit.Before
 import org.junit.Rule
@@ -39,15 +43,27 @@
 import org.mockito.Mock
 import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.anyLong
+import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.eq
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.Mockito.`when`
 import org.mockito.junit.MockitoJUnit
 
+private fun createInputDevice(deviceId: Int, hasBattery: Boolean = true): InputDevice =
+    InputDevice.Builder()
+        .setId(deviceId)
+        .setName("Device $deviceId")
+        .setDescriptor("descriptor $deviceId")
+        .setExternal(true)
+        .setHasBattery(hasBattery)
+        .setGeneration(0)
+        .build()
+
 /**
  * Tests for {@link InputDeviceBatteryController}.
  *
@@ -60,6 +76,7 @@
         const val PID = 42
         const val DEVICE_ID = 13
         const val SECOND_DEVICE_ID = 11
+        const val TIMESTAMP = 123456789L
     }
 
     @get:Rule
@@ -69,13 +86,19 @@
     private lateinit var native: NativeInputManagerService
     @Mock
     private lateinit var iInputManager: IInputManager
+    @Mock
+    private lateinit var uEventManager: UEventManager
 
     private lateinit var batteryController: BatteryController
     private lateinit var context: Context
+    private lateinit var testLooper: TestLooper
+    private lateinit var devicesChangedListener: IInputDevicesChangedListener
+    private val deviceGenerationMap = mutableMapOf<Int /*deviceId*/, Int /*generation*/>()
 
     @Before
     fun setup() {
         context = spy(ContextWrapper(InstrumentationRegistry.getContext()))
+        testLooper = TestLooper()
         val inputManager = InputManager.resetInstance(iInputManager)
         `when`(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager)
         `when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID, SECOND_DEVICE_ID))
@@ -83,17 +106,18 @@
         `when`(iInputManager.getInputDevice(SECOND_DEVICE_ID))
             .thenReturn(createInputDevice(SECOND_DEVICE_ID))
 
-        batteryController = BatteryController(context, native)
+        batteryController = BatteryController(context, native, testLooper.looper, uEventManager)
+        batteryController.systemRunning()
+        val listenerCaptor = ArgumentCaptor.forClass(IInputDevicesChangedListener::class.java)
+        verify(iInputManager).registerInputDevicesChangedListener(listenerCaptor.capture())
+        devicesChangedListener = listenerCaptor.value
     }
 
-    private fun createInputDevice(deviceId: Int): InputDevice =
-        InputDevice.Builder()
-            .setId(deviceId)
-            .setName("Device $deviceId")
-            .setDescriptor("descriptor $deviceId")
-            .setExternal(true)
-            .setHasBattery(true)
-            .build()
+    private fun notifyDeviceChanged(deviceId: Int) {
+        deviceGenerationMap[deviceId] = deviceGenerationMap[deviceId]?.plus(1) ?: 1
+        val list = deviceGenerationMap.flatMap { listOf(it.key, it.value) }
+        devicesChangedListener.onInputDevicesChanged(list.toIntArray())
+    }
 
     @After
     fun tearDown() {
@@ -169,4 +193,68 @@
         verify(listener).onBatteryStateChanged(eq(SECOND_DEVICE_ID), eq(true /*isPresent*/),
             eq(STATUS_CHARGING), eq(0.78f), anyLong())
     }
+
+    @Test
+    fun testListenersNotifiedOnUEventNotification() {
+        `when`(native.getBatteryDevicePath(DEVICE_ID)).thenReturn("/test/device1")
+        `when`(native.getBatteryStatus(DEVICE_ID)).thenReturn(STATUS_CHARGING)
+        `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(78)
+        val listener = createMockListener()
+        val uEventListener = ArgumentCaptor.forClass(UEventManager.UEventListener::class.java)
+        batteryController.registerBatteryListener(DEVICE_ID, listener, PID)
+        verify(uEventManager).addListener(uEventListener.capture(), eq("DEVPATH=/test/device1"))
+        verify(listener).onBatteryStateChanged(eq(DEVICE_ID), eq(true /*isPresent*/),
+            eq(STATUS_CHARGING), eq(0.78f), anyLong())
+
+        // If the battery state has changed when an UEvent is sent, the listeners are notified.
+        `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(80)
+        uEventListener.value!!.onUEvent(TIMESTAMP)
+        verify(listener).onBatteryStateChanged(DEVICE_ID, true /*isPresent*/, STATUS_CHARGING,
+            0.80f, TIMESTAMP)
+
+        // If the battery state has not changed when an UEvent is sent, the listeners are not
+        // notified.
+        clearInvocations(listener)
+        uEventListener.value!!.onUEvent(TIMESTAMP + 1)
+        verifyNoMoreInteractions(listener)
+
+        batteryController.unregisterBatteryListener(DEVICE_ID, listener, PID)
+        verify(uEventManager).removeListener(uEventListener.capture())
+        assertEquals("The same observer must be registered and unregistered",
+            uEventListener.allValues[0], uEventListener.allValues[1])
+    }
+
+    @Test
+    fun testBatteryPresenceChanged() {
+        `when`(native.getBatteryDevicePath(DEVICE_ID)).thenReturn("/test/device1")
+        `when`(native.getBatteryStatus(DEVICE_ID)).thenReturn(STATUS_CHARGING)
+        `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(78)
+        val listener = createMockListener()
+        val uEventListener = ArgumentCaptor.forClass(UEventManager.UEventListener::class.java)
+        batteryController.registerBatteryListener(DEVICE_ID, listener, PID)
+        verify(uEventManager).addListener(uEventListener.capture(), eq("DEVPATH=/test/device1"))
+        verify(listener).onBatteryStateChanged(eq(DEVICE_ID), eq(true /*isPresent*/),
+            eq(STATUS_CHARGING), eq(0.78f), anyLong())
+
+        // If the battery presence for the InputDevice changes, the listener is notified.
+        `when`(iInputManager.getInputDevice(DEVICE_ID))
+            .thenReturn(createInputDevice(DEVICE_ID, hasBattery = false))
+        notifyDeviceChanged(DEVICE_ID)
+        testLooper.dispatchNext()
+        verify(listener).onBatteryStateChanged(eq(DEVICE_ID), eq(false /*isPresent*/),
+            eq(STATUS_UNKNOWN), eq(Float.NaN), anyLong())
+        // Since the battery is no longer present, the UEventListener should be removed.
+        verify(uEventManager).removeListener(uEventListener.value)
+
+        // If the battery becomes present again, the listener is notified.
+        `when`(iInputManager.getInputDevice(DEVICE_ID))
+            .thenReturn(createInputDevice(DEVICE_ID, hasBattery = true))
+        notifyDeviceChanged(DEVICE_ID)
+        testLooper.dispatchNext()
+        verify(listener, times(2)).onBatteryStateChanged(eq(DEVICE_ID), eq(true /*isPresent*/),
+            eq(STATUS_CHARGING), eq(0.78f), anyLong())
+        // Ensure that a new UEventListener was added.
+        verify(uEventManager, times(2))
+            .addListener(uEventListener.capture(), eq("DEVPATH=/test/device1"))
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/ConcurrentLinkedEvictingDequeTest.java b/services/tests/servicestests/src/com/android/server/location/contexthub/ConcurrentLinkedEvictingDequeTest.java
new file mode 100644
index 0000000..9169a0d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/location/contexthub/ConcurrentLinkedEvictingDequeTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location.contexthub;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+public class ConcurrentLinkedEvictingDequeTest {
+    @Test
+    public void testMaxSize() {
+        int maxSize = 20;
+        ConcurrentLinkedEvictingDeque<Integer> deque =
+                new ConcurrentLinkedEvictingDeque<Integer>(maxSize);
+
+        // add items to the queue
+        for (int i = 0; i < maxSize; i++) {
+            deque.add(i);
+        }
+
+        // test the max size
+        deque.add(maxSize);
+        assertThat(deque.peek() == 0).isFalse();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEventLoggerTest.java b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEventLoggerTest.java
new file mode 100644
index 0000000..8863d27
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEventLoggerTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location.contexthub;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.hardware.location.NanoAppMessage;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+public class ContextHubEventLoggerTest {
+    private static final ContextHubEventLogger sInstance = ContextHubEventLogger.getInstance();
+
+    @Test
+    public void testLogNanoappLoad() {
+        ContextHubEventLogger.NanoappLoadEvent[] events =
+                new ContextHubEventLogger.NanoappLoadEvent[] {
+                    new ContextHubEventLogger.NanoappLoadEvent(0, -1, 42, -34, 100, false),
+                    new ContextHubEventLogger.NanoappLoadEvent(0, 0, 123, 321, 001, true)
+                };
+        String[] eventStrings = generateEventDumpStrings(events);
+
+        // log events and test sInstance.toString() contains event details
+        sInstance.clear();
+        sInstance.logNanoappLoad(-1, 42, -34, 100, false);
+        sInstance.logNanoappLoad(0, 123, 321, 001, true);
+        String sInstanceDump = sInstance.toString();
+        for (String eventString: eventStrings) {
+            assertThat(eventString.length() > 0).isTrue();
+            assertThat(sInstanceDump.contains(eventString)).isTrue();
+        }
+    }
+
+    @Test
+    public void testLogNanoappUnload() {
+        ContextHubEventLogger.NanoappUnloadEvent[] events =
+                new ContextHubEventLogger.NanoappUnloadEvent[] {
+                    new ContextHubEventLogger.NanoappUnloadEvent(0, -1, 47, false),
+                    new ContextHubEventLogger.NanoappUnloadEvent(0, 1, 0xFFFFFFFF, true)
+                };
+        String[] eventStrings = generateEventDumpStrings(events);
+
+        // log events and test sInstance.toString() contains event details
+        sInstance.clear();
+        sInstance.logNanoappUnload(-1, 47, false);
+        sInstance.logNanoappUnload(1, 0xFFFFFFFF, true);
+        String sInstanceDump = sInstance.toString();
+        for (String eventString: eventStrings) {
+            assertThat(eventString.length() > 0).isTrue();
+            assertThat(sInstanceDump.contains(eventString)).isTrue();
+        }
+    }
+
+    @Test
+    public void testLogMessageFromNanoapp() {
+        NanoAppMessage message1 = NanoAppMessage.createMessageFromNanoApp(1, 0,
+                new byte[] {0x00, 0x11, 0x22, 0x33}, false);
+        NanoAppMessage message2 = NanoAppMessage.createMessageFromNanoApp(0, 1,
+                new byte[] {(byte) 0xDE, (byte) 0xAD, (byte) 0xBE, (byte) 0xEF}, true);
+        ContextHubEventLogger.NanoappMessageEvent[] events =
+                new ContextHubEventLogger.NanoappMessageEvent[] {
+                    new ContextHubEventLogger.NanoappMessageEvent(8, -123, message1, false),
+                    new ContextHubEventLogger.NanoappMessageEvent(9, 321, message2, true)
+                };
+        String[] eventStrings = generateEventDumpStrings(events);
+
+        // log events and test sInstance.toString() contains event details
+        sInstance.clear();
+        sInstance.logMessageFromNanoapp(-123, message1, false);
+        sInstance.logMessageFromNanoapp(321, message2, true);
+        String sInstanceDump = sInstance.toString();
+        for (String eventString: eventStrings) {
+            assertThat(eventString.length() > 0).isTrue();
+            assertThat(sInstanceDump.contains(eventString)).isTrue();
+        }
+    }
+
+    @Test
+    public void testLogMessageToNanoapp() {
+        NanoAppMessage message1 = NanoAppMessage.createMessageToNanoApp(1, 0,
+                new byte[] {0x00, 0x11, 0x22, 0x33});
+        NanoAppMessage message2 = NanoAppMessage.createMessageToNanoApp(0, 1,
+                new byte[] {(byte) 0xDE, (byte) 0xAD, (byte) 0xBE, (byte) 0xEF});
+        ContextHubEventLogger.NanoappMessageEvent[] events =
+                new ContextHubEventLogger.NanoappMessageEvent[] {
+                    new ContextHubEventLogger.NanoappMessageEvent(23, 888, message1, true),
+                    new ContextHubEventLogger.NanoappMessageEvent(34, 999, message2, false)
+                };
+        String[] eventStrings = generateEventDumpStrings(events);
+
+        // log events and test sInstance.toString() contains event details
+        sInstance.clear();
+        sInstance.logMessageToNanoapp(888, message1, true);
+        sInstance.logMessageToNanoapp(999, message2, false);
+        String sInstanceDump = sInstance.toString();
+        for (String eventString: eventStrings) {
+            assertThat(eventString.length() > 0).isTrue();
+            assertThat(sInstanceDump.contains(eventString)).isTrue();
+        }
+    }
+
+    @Test
+    public void testLogContextHubRestart() {
+        ContextHubEventLogger.ContextHubRestartEvent[] events =
+                new ContextHubEventLogger.ContextHubRestartEvent[] {
+                    new ContextHubEventLogger.ContextHubRestartEvent(0, 1),
+                    new ContextHubEventLogger.ContextHubRestartEvent(1, 2)
+                };
+        String[] eventStrings = generateEventDumpStrings(events);
+
+        // log events and test sInstance.toString() contains event details
+        sInstance.clear();
+        sInstance.logContextHubRestart(1);
+        sInstance.logContextHubRestart(2);
+        String sInstanceDump = sInstance.toString();
+        for (String eventString: eventStrings) {
+            assertThat(eventString.length() > 0).isTrue();
+            assertThat(sInstanceDump.contains(eventString)).isTrue();
+        }
+    }
+
+    /**
+     * Generates the part of the event's toString() method that should be contained in the dump
+     * output (everything without the timestamp).
+     *
+     * @param events        the events
+     * @return              the string representation of the events
+     */
+    private String[] generateEventDumpStrings(ContextHubEventLogger.ContextHubEventBase[] events) {
+        return (String[]) Arrays.stream(events)
+                .map(event -> event.toString().split(event.getClass().getSimpleName(), 2)[1])
+                .toArray(String[]::new);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
index e04edc6..96707fd 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -216,6 +216,25 @@
         assertThat(mUserManagerService.isUserSwitcherEnabled(userId)).isTrue();
     }
 
+    @Test
+    public void assertIsUserSwitcherEnabled()  throws Exception {
+        int userId = ActivityManager.getCurrentUser();
+        setMaxSupportedUsers(8);
+        assertThat(mUserManagerService.isUserSwitcherEnabled(true, userId)).isTrue();
+
+        setUserSwitch(false);
+        assertThat(mUserManagerService.isUserSwitcherEnabled(true, userId)).isFalse();
+
+        setUserSwitch(true);
+        assertThat(mUserManagerService.isUserSwitcherEnabled(false, userId)).isTrue();
+
+        mUserManagerService.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, userId);
+        assertThat(mUserManagerService.isUserSwitcherEnabled(false, userId)).isFalse();
+
+        mUserManagerService.setUserRestriction(UserManager.DISALLOW_ADD_USER, false, userId);
+        setMaxSupportedUsers(1);
+        assertThat(mUserManagerService.isUserSwitcherEnabled(true, userId)).isFalse();
+    }
 
     @Test
     public void assertIsUserSwitcherEnabledOnShowMultiuserUI()  throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
index d5b923a..4100ff1 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
@@ -148,6 +148,25 @@
     }
 
     @Test
+    public void testAtraceInstantEvent() {
+        mHistory.forceRecordAllHistory();
+
+        InOrder inOrder = Mockito.inOrder(mTracer);
+        Mockito.when(mTracer.tracingEnabled()).thenReturn(true);
+
+        mHistory.recordEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(),
+                HistoryItem.EVENT_WAKEUP_AP, "", 1234);
+        mHistory.recordEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(),
+                HistoryItem.EVENT_JOB_START, "jobname", 2468);
+        mHistory.recordEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(),
+                HistoryItem.EVENT_JOB_FINISH, "jobname", 2468);
+
+        inOrder.verify(mTracer).traceInstantEvent("battery_stats.wakeupap", "wakeupap=1234:\"\"");
+        inOrder.verify(mTracer).traceInstantEvent("battery_stats.job", "+job=2468:\"jobname\"");
+        inOrder.verify(mTracer).traceInstantEvent("battery_stats.job", "-job=2468:\"jobname\"");
+    }
+
+    @Test
     public void testConstruct() {
         createActiveFile(mHistory);
         verifyFileNumbers(mHistory, Arrays.asList(0));
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
index 99a12c2..508e7b0f 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -161,13 +161,8 @@
             return null;
         }).when(mVirtualDeviceManagerInternalMock).registerAppsOnVirtualDeviceListener(any());
 
-        LocalServices.removeServiceForTest(PowerManagerInternal.class);
-        LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
-        LocalServices.removeServiceForTest(PackageManagerInternal.class);
-        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
-        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
-        LocalServices.addService(VirtualDeviceManagerInternal.class,
-                mVirtualDeviceManagerInternalMock);
+        removeServicesForTest();
+        addServicesForTest();
 
         setDefaultIntensity(VIBRATION_INTENSITY_MEDIUM);
         mAudioManager = mContextSpy.getSystemService(AudioManager.class);
@@ -185,9 +180,34 @@
         mVibrationSettings.onSystemReady();
     }
 
+    private void removeServicesForTest() {
+        LocalServices.removeServiceForTest(PowerManagerInternal.class);
+        LocalServices.removeServiceForTest(PackageManagerInternal.class);
+        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
+    }
+
+    private void addServicesForTest() {
+        LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
+        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
+        LocalServices.addService(VirtualDeviceManagerInternal.class,
+                mVirtualDeviceManagerInternalMock);
+    }
+
     @After
     public void tearDown() throws Exception {
-        LocalServices.removeServiceForTest(PowerManagerInternal.class);
+        removeServicesForTest();
+    }
+
+    @Test
+    public void create_withOnlyRequiredSystemServices() {
+        // The only core services that we depend on are PowerManager and PackageManager
+        removeServicesForTest();
+        LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
+        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
+
+        VibrationSettings minimalVibrationSettings = new VibrationSettings(mContextSpy,
+                new Handler(mTestLooper.getLooper()), mVibrationConfigMock);
+        minimalVibrationSettings.onSystemReady();
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 49879efe..7986043 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -1704,8 +1704,8 @@
     }
 
     @Test
-    public void testInfoIsPermittedForProfile_notAllowed() {
-        when(mUserProfiles.canProfileUseBoundServices(anyInt())).thenReturn(false);
+    public void testInfoIsPermittedForProfile_notProfile() {
+        when(mUserProfiles.isProfileUser(anyInt())).thenReturn(false);
 
         IInterface service = mock(IInterface.class);
         when(service.asBinder()).thenReturn(mock(IBinder.class));
@@ -1714,12 +1714,12 @@
         services.registerSystemService(service, null, 10, 1000);
         ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
 
-        assertFalse(info.isPermittedForProfile(0));
+        assertTrue(info.isPermittedForProfile(0));
     }
 
     @Test
-    public void testInfoIsPermittedForProfile_allows() {
-        when(mUserProfiles.canProfileUseBoundServices(anyInt())).thenReturn(true);
+    public void testInfoIsPermittedForProfile_profileAndDpmAllows() {
+        when(mUserProfiles.isProfileUser(anyInt())).thenReturn(true);
         when(mDpm.isNotificationListenerServicePermitted(anyString(), anyInt())).thenReturn(true);
 
         IInterface service = mock(IInterface.class);
@@ -1734,6 +1734,22 @@
     }
 
     @Test
+    public void testInfoIsPermittedForProfile_profileAndDpmDenies() {
+        when(mUserProfiles.isProfileUser(anyInt())).thenReturn(true);
+        when(mDpm.isNotificationListenerServicePermitted(anyString(), anyInt())).thenReturn(false);
+
+        IInterface service = mock(IInterface.class);
+        when(service.asBinder()).thenReturn(mock(IBinder.class));
+        ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
+                mIpm, APPROVAL_BY_PACKAGE);
+        services.registerSystemService(service, null, 10, 1000);
+        ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
+        info.component = new ComponentName("a","b");
+
+        assertFalse(info.isPermittedForProfile(0));
+    }
+
+    @Test
     public void testUserProfiles_canProfileUseBoundServices_managedProfile() {
         List<UserInfo> users = new ArrayList<>();
         UserInfo profile = new UserInfo(ActivityManager.getCurrentUser(), "current", 0);
@@ -1750,9 +1766,9 @@
         ManagedServices.UserProfiles profiles = new ManagedServices.UserProfiles();
         profiles.updateCache(mContext);
 
-        assertTrue(profiles.canProfileUseBoundServices(ActivityManager.getCurrentUser()));
-        assertFalse(profiles.canProfileUseBoundServices(12));
-        assertFalse(profiles.canProfileUseBoundServices(13));
+        assertFalse(profiles.isProfileUser(ActivityManager.getCurrentUser()));
+        assertTrue(profiles.isProfileUser(12));
+        assertTrue(profiles.isProfileUser(13));
     }
 
     private void resetComponentsAndPackages() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
index 68551d9..1e94577 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -45,19 +45,16 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.content.pm.VersionedPackage;
 import android.os.Bundle;
-import android.os.IBinder;
-import android.os.IInterface;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerFilter;
 import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationStats;
 import android.service.notification.NotificationRankingUpdate;
+import android.service.notification.NotificationStats;
 import android.service.notification.StatusBarNotification;
 import android.testing.TestableContext;
 import android.util.ArraySet;
@@ -408,64 +405,113 @@
 
     @Test
     public void testNotifyPostedLockedInLockdownMode() {
-        NotificationRecord r = mock(NotificationRecord.class);
-        NotificationRecord old = mock(NotificationRecord.class);
+        NotificationRecord r0 = mock(NotificationRecord.class);
+        NotificationRecord old0 = mock(NotificationRecord.class);
+        UserHandle uh0 = mock(UserHandle.class);
 
-        // before the lockdown mode
-        when(mNm.isInLockDownMode()).thenReturn(false);
-        mListeners.notifyPostedLocked(r, old, true);
-        mListeners.notifyPostedLocked(r, old, false);
-        verify(r, atLeast(2)).getSbn();
+        NotificationRecord r1 = mock(NotificationRecord.class);
+        NotificationRecord old1 = mock(NotificationRecord.class);
+        UserHandle uh1 = mock(UserHandle.class);
 
-        // in the lockdown mode
-        reset(r);
-        reset(old);
-        when(mNm.isInLockDownMode()).thenReturn(true);
-        mListeners.notifyPostedLocked(r, old, true);
-        mListeners.notifyPostedLocked(r, old, false);
-        verify(r, never()).getSbn();
-    }
+        // Neither user0 and user1 is in the lockdown mode
+        when(r0.getUser()).thenReturn(uh0);
+        when(uh0.getIdentifier()).thenReturn(0);
+        when(mNm.isInLockDownMode(0)).thenReturn(false);
 
-    @Test
-    public void testnotifyRankingUpdateLockedInLockdownMode() {
-        List chn = mock(List.class);
+        when(r1.getUser()).thenReturn(uh1);
+        when(uh1.getIdentifier()).thenReturn(1);
+        when(mNm.isInLockDownMode(1)).thenReturn(false);
 
-        // before the lockdown mode
-        when(mNm.isInLockDownMode()).thenReturn(false);
-        mListeners.notifyRankingUpdateLocked(chn);
-        verify(chn, atLeast(1)).size();
+        mListeners.notifyPostedLocked(r0, old0, true);
+        mListeners.notifyPostedLocked(r0, old0, false);
+        verify(r0, atLeast(2)).getSbn();
 
-        // in the lockdown mode
-        reset(chn);
-        when(mNm.isInLockDownMode()).thenReturn(true);
-        mListeners.notifyRankingUpdateLocked(chn);
-        verify(chn, never()).size();
+        mListeners.notifyPostedLocked(r1, old1, true);
+        mListeners.notifyPostedLocked(r1, old1, false);
+        verify(r1, atLeast(2)).getSbn();
+
+        // Reset
+        reset(r0);
+        reset(old0);
+        reset(r1);
+        reset(old1);
+
+        // Only user 0 is in the lockdown mode
+        when(r0.getUser()).thenReturn(uh0);
+        when(uh0.getIdentifier()).thenReturn(0);
+        when(mNm.isInLockDownMode(0)).thenReturn(true);
+
+        when(r1.getUser()).thenReturn(uh1);
+        when(uh1.getIdentifier()).thenReturn(1);
+        when(mNm.isInLockDownMode(1)).thenReturn(false);
+
+        mListeners.notifyPostedLocked(r0, old0, true);
+        mListeners.notifyPostedLocked(r0, old0, false);
+        verify(r0, never()).getSbn();
+
+        mListeners.notifyPostedLocked(r1, old1, true);
+        mListeners.notifyPostedLocked(r1, old1, false);
+        verify(r1, atLeast(2)).getSbn();
     }
 
     @Test
     public void testNotifyRemovedLockedInLockdownMode() throws NoSuchFieldException {
-        NotificationRecord r = mock(NotificationRecord.class);
-        NotificationStats rs = mock(NotificationStats.class);
+        NotificationRecord r0 = mock(NotificationRecord.class);
+        NotificationStats rs0 = mock(NotificationStats.class);
+        UserHandle uh0 = mock(UserHandle.class);
+
+        NotificationRecord r1 = mock(NotificationRecord.class);
+        NotificationStats rs1 = mock(NotificationStats.class);
+        UserHandle uh1 = mock(UserHandle.class);
+
         StatusBarNotification sbn = mock(StatusBarNotification.class);
         FieldSetter.setField(mNm,
                 NotificationManagerService.class.getDeclaredField("mHandler"),
                 mock(NotificationManagerService.WorkerHandler.class));
 
-        // before the lockdown mode
-        when(mNm.isInLockDownMode()).thenReturn(false);
-        when(r.getSbn()).thenReturn(sbn);
-        mListeners.notifyRemovedLocked(r, 0, rs);
-        mListeners.notifyRemovedLocked(r, 0, rs);
-        verify(r, atLeast(2)).getSbn();
+        // Neither user0 and user1 is in the lockdown mode
+        when(r0.getUser()).thenReturn(uh0);
+        when(uh0.getIdentifier()).thenReturn(0);
+        when(mNm.isInLockDownMode(0)).thenReturn(false);
+        when(r0.getSbn()).thenReturn(sbn);
 
-        // in the lockdown mode
-        reset(r);
-        reset(rs);
-        when(mNm.isInLockDownMode()).thenReturn(true);
-        when(r.getSbn()).thenReturn(sbn);
-        mListeners.notifyRemovedLocked(r, 0, rs);
-        mListeners.notifyRemovedLocked(r, 0, rs);
-        verify(r, never()).getSbn();
+        when(r1.getUser()).thenReturn(uh1);
+        when(uh1.getIdentifier()).thenReturn(1);
+        when(mNm.isInLockDownMode(1)).thenReturn(false);
+        when(r1.getSbn()).thenReturn(sbn);
+
+        mListeners.notifyRemovedLocked(r0, 0, rs0);
+        mListeners.notifyRemovedLocked(r0, 0, rs0);
+        verify(r0, atLeast(2)).getSbn();
+
+        mListeners.notifyRemovedLocked(r1, 0, rs1);
+        mListeners.notifyRemovedLocked(r1, 0, rs1);
+        verify(r1, atLeast(2)).getSbn();
+
+        // Reset
+        reset(r0);
+        reset(rs0);
+        reset(r1);
+        reset(rs1);
+
+        // Only user 0 is in the lockdown mode
+        when(r0.getUser()).thenReturn(uh0);
+        when(uh0.getIdentifier()).thenReturn(0);
+        when(mNm.isInLockDownMode(0)).thenReturn(true);
+        when(r0.getSbn()).thenReturn(sbn);
+
+        when(r1.getUser()).thenReturn(uh1);
+        when(uh1.getIdentifier()).thenReturn(1);
+        when(mNm.isInLockDownMode(1)).thenReturn(false);
+        when(r1.getSbn()).thenReturn(sbn);
+
+        mListeners.notifyRemovedLocked(r0, 0, rs0);
+        mListeners.notifyRemovedLocked(r0, 0, rs0);
+        verify(r0, never()).getSbn();
+
+        mListeners.notifyRemovedLocked(r1, 0, rs1);
+        mListeners.notifyRemovedLocked(r1, 0, rs1);
+        verify(r1, atLeast(2)).getSbn();
     }
 
     @Test
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 cae8fd9..92761427 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -174,6 +174,7 @@
 import android.service.notification.ConversationChannelWrapper;
 import android.service.notification.NotificationListenerFilter;
 import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationRankingUpdate;
 import android.service.notification.NotificationStats;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenPolicy;
@@ -9837,10 +9838,10 @@
         mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
                 STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
         mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
-        assertTrue(mStrongAuthTracker.isInLockDownMode());
-        mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
+        assertTrue(mStrongAuthTracker.isInLockDownMode(mContext.getUserId()));
+        mStrongAuthTracker.setGetStrongAuthForUserReturnValue(mContext.getUserId());
         mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
-        assertFalse(mStrongAuthTracker.isInLockDownMode());
+        assertFalse(mStrongAuthTracker.isInLockDownMode(mContext.getUserId()));
     }
 
     @Test
@@ -9856,8 +9857,8 @@
         // when entering the lockdown mode, cancel the 2 notifications.
         mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
                 STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
-        mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
-        assertTrue(mStrongAuthTracker.isInLockDownMode());
+        mStrongAuthTracker.onStrongAuthRequiredChanged(0);
+        assertTrue(mStrongAuthTracker.isInLockDownMode(0));
 
         // the notifyRemovedLocked function is called twice due to REASON_LOCKDOWN.
         ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
@@ -9866,10 +9867,46 @@
 
         // exit lockdown mode.
         mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
-        mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
+        mStrongAuthTracker.onStrongAuthRequiredChanged(0);
+        assertFalse(mStrongAuthTracker.isInLockDownMode(0));
 
         // the notifyPostedLocked function is called twice.
-        verify(mListeners, times(2)).notifyPostedLocked(any(), any());
+        verify(mWorkerHandler, times(2)).postDelayed(any(Runnable.class), anyLong());
+        //verify(mListeners, times(2)).notifyPostedLocked(any(), any());
+    }
+
+    @Test
+    public void testMakeRankingUpdateLockedInLockDownMode() {
+        // post 2 notifications from a same package
+        NotificationRecord pkgA = new NotificationRecord(mContext,
+                generateSbn("a", 1000, 9, 0), mTestNotificationChannel);
+        mService.addNotification(pkgA);
+        NotificationRecord pkgB = new NotificationRecord(mContext,
+                generateSbn("a", 1000, 9, 1), mTestNotificationChannel);
+        mService.addNotification(pkgB);
+
+        mService.setIsVisibleToListenerReturnValue(true);
+        NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(null);
+        assertEquals(2, nru.getRankingMap().getOrderedKeys().length);
+
+        // when only user 0 entering the lockdown mode, its notification will be suppressed.
+        mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+        mStrongAuthTracker.onStrongAuthRequiredChanged(0);
+        assertTrue(mStrongAuthTracker.isInLockDownMode(0));
+        assertFalse(mStrongAuthTracker.isInLockDownMode(1));
+
+        nru = mService.makeRankingUpdateLocked(null);
+        assertEquals(1, nru.getRankingMap().getOrderedKeys().length);
+
+        // User 0 exits lockdown mode. Its notification will be resumed.
+        mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
+        mStrongAuthTracker.onStrongAuthRequiredChanged(0);
+        assertFalse(mStrongAuthTracker.isInLockDownMode(0));
+        assertFalse(mStrongAuthTracker.isInLockDownMode(1));
+
+        nru = mService.makeRankingUpdateLocked(null);
+        assertEquals(2, nru.getRankingMap().getOrderedKeys().length);
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
index b49e5cb..8cf74fb 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
@@ -19,10 +19,12 @@
 import android.companion.ICompanionDeviceManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.service.notification.StatusBarNotification;
 
 import androidx.annotation.Nullable;
 
 import com.android.internal.logging.InstanceIdSequence;
+import com.android.server.notification.ManagedServices.ManagedServiceInfo;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -37,6 +39,9 @@
     @Nullable
     NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback;
 
+    @Nullable
+    Boolean mIsVisibleToListenerReturnValue = null;
+
     TestableNotificationManagerService(Context context, NotificationRecordLogger logger,
             InstanceIdSequence notificationInstanceIdSequence) {
         super(context, logger, notificationInstanceIdSequence);
@@ -119,6 +124,19 @@
         mShowReviewPermissionsNotification = setting;
     }
 
+    protected void setIsVisibleToListenerReturnValue(boolean value) {
+        mIsVisibleToListenerReturnValue = value;
+    }
+
+    @Override
+    boolean isVisibleToListener(StatusBarNotification sbn, int notificationType,
+            ManagedServiceInfo listener) {
+        if (mIsVisibleToListenerReturnValue != null) {
+            return mIsVisibleToListenerReturnValue;
+        }
+        return super.isVisibleToListener(sbn, notificationType, listener);
+    }
+
     public class StrongAuthTrackerFake extends NotificationManagerService.StrongAuthTracker {
         private int mGetStrongAuthForUserReturnValue = 0;
         StrongAuthTrackerFake(Context context) {
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 2918365..107bbe1 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -79,7 +79,10 @@
         <activity android:name="com.android.server.wm.ActivityOptionsTest$MainActivity"
                   android:turnScreenOn="true"
                   android:showWhenLocked="true" />
-        <activity android:name="com.android.server.wm.ScreenshotTests$ScreenshotActivity" />
+        <activity android:name="com.android.server.wm.ScreenshotTests$ScreenshotActivity"
+                  android:theme="@style/WhiteBackgroundTheme"
+                  android:turnScreenOn="true"
+                  android:showWhenLocked="true"/>
         <activity android:name="android.view.cts.surfacevalidator.CapturedActivity"/>
 
         <service android:name="android.view.cts.surfacevalidator.LocalMediaProjectionService"
diff --git a/services/tests/wmtests/res/values/styles.xml b/services/tests/wmtests/res/values/styles.xml
new file mode 100644
index 0000000..6857ff99
--- /dev/null
+++ b/services/tests/wmtests/res/values/styles.xml
@@ -0,0 +1,24 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources>
+    <style name="WhiteBackgroundTheme" parent="@android:style/Theme.DeviceDefault">
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
+    </style>
+</resources>
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 1d52b7f..376399a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -384,7 +384,7 @@
     }
 
     private ActivityMetricsLogger.TransitionInfoSnapshot notifyWindowsDrawn(ActivityRecord r) {
-        return mActivityMetricsLogger.notifyWindowsDrawn(r, SystemClock.elapsedRealtimeNanos());
+        return mActivityMetricsLogger.notifyWindowsDrawn(r);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 85e5bfd..2b0e76c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -379,6 +379,8 @@
         doReturn(false).when(mMockPackageManager).isInstantAppInstallerComponent(any());
         doReturn(null).when(mMockPackageManager).resolveIntent(any(), any(), anyLong(), anyLong(),
                 anyInt(), anyBoolean(), anyInt());
+        doReturn(null).when(mMockPackageManager).resolveIntentExported(any(), any(),
+                anyLong(), anyLong(), anyInt(), anyBoolean(), anyInt());
         doReturn(new ComponentName("", "")).when(mMockPackageManager).getSystemUiServiceComponent();
 
         // Never review permissions
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 44471f4..11ae5d4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -139,6 +139,7 @@
 import android.view.WindowManager;
 import android.window.DisplayAreaInfo;
 import android.window.IDisplayAreaOrganizer;
+import android.window.ScreenCapture;
 import android.window.WindowContainerToken;
 
 import androidx.test.filters.SmallTest;
@@ -2109,8 +2110,8 @@
 
         // Preparation: Simulate snapshot IME surface.
         spyOn(mWm.mTaskSnapshotController);
-        SurfaceControl.ScreenshotHardwareBuffer mockHwBuffer = mock(
-                SurfaceControl.ScreenshotHardwareBuffer.class);
+        ScreenCapture.ScreenshotHardwareBuffer mockHwBuffer = mock(
+                ScreenCapture.ScreenshotHardwareBuffer.class);
         doReturn(mock(HardwareBuffer.class)).when(mockHwBuffer).getHardwareBuffer();
         doReturn(mockHwBuffer).when(mWm.mTaskSnapshotController).snapshotImeFromAttachedTask(any());
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ScreenshotTests.java b/services/tests/wmtests/src/com/android/server/wm/ScreenshotTests.java
index f542e29..8cd8e9b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ScreenshotTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ScreenshotTests.java
@@ -16,6 +16,10 @@
 
 package com.android.server.wm;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.statusBars;
+
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertNotNull;
@@ -23,19 +27,31 @@
 
 import android.app.Activity;
 import android.app.Instrumentation;
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.ColorSpace;
 import android.graphics.GraphicBuffer;
+import android.graphics.Insets;
 import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.DataSpace;
+import android.hardware.HardwareBuffer;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.platform.test.annotations.Presubmit;
+import android.view.IWindowManager;
 import android.view.PointerIcon;
 import android.view.SurfaceControl;
-import android.view.WindowManager;
+import android.view.cts.surfacevalidator.BitmapPixelChecker;
+import android.view.cts.surfacevalidator.PixelColor;
+import android.view.cts.surfacevalidator.SaveBitmapHelper;
+import android.window.ScreenCapture;
+import android.window.ScreenCapture.SyncScreenCaptureListener;
 
 import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
@@ -44,6 +60,7 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestName;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -59,6 +76,8 @@
     private static final int BUFFER_HEIGHT = 100;
 
     private final Instrumentation mInstrumentation = getInstrumentation();
+    @Rule
+    public TestName mTestName = new TestName();
 
     @Rule
     public ActivityTestRule<ScreenshotActivity> mActivityRule =
@@ -94,15 +113,15 @@
         buffer.unlockCanvasAndPost(canvas);
 
         t.show(secureSC)
-                .setBuffer(secureSC, buffer)
-                .setColorSpace(secureSC, ColorSpace.get(ColorSpace.Named.SRGB))
+                .setBuffer(secureSC, HardwareBuffer.createFromGraphicBuffer(buffer))
+                .setDataSpace(secureSC, DataSpace.DATASPACE_SRGB)
                 .apply(true);
 
-        SurfaceControl.LayerCaptureArgs args = new SurfaceControl.LayerCaptureArgs.Builder(secureSC)
+        ScreenCapture.LayerCaptureArgs args = new ScreenCapture.LayerCaptureArgs.Builder(secureSC)
                 .setCaptureSecureLayers(true)
                 .setChildrenOnly(false)
                 .build();
-        SurfaceControl.ScreenshotHardwareBuffer hardwareBuffer = SurfaceControl.captureLayers(args);
+        ScreenCapture.ScreenshotHardwareBuffer hardwareBuffer = ScreenCapture.captureLayers(args);
         assertNotNull(hardwareBuffer);
 
         Bitmap screenshot = hardwareBuffer.asBitmap();
@@ -111,15 +130,69 @@
         Bitmap swBitmap = screenshot.copy(Bitmap.Config.ARGB_8888, false);
         screenshot.recycle();
 
-        int numMatchingPixels = PixelChecker.getNumMatchingPixels(swBitmap,
-                new PixelColor(PixelColor.RED));
-        long sizeOfBitmap = swBitmap.getWidth() * swBitmap.getHeight();
+        BitmapPixelChecker bitmapPixelChecker = new BitmapPixelChecker(PixelColor.RED);
+        Rect bounds = new Rect(0, 0, swBitmap.getWidth(), swBitmap.getHeight());
+        int numMatchingPixels = bitmapPixelChecker.getNumMatchingPixels(swBitmap, bounds);
+        int sizeOfBitmap = bounds.width() * bounds.height();
         boolean success = numMatchingPixels == sizeOfBitmap;
         swBitmap.recycle();
 
         assertTrue(success);
     }
 
+    @Test
+    public void testCaptureDisplay() throws RemoteException {
+        IWindowManager windowManager = IWindowManager.Stub.asInterface(
+                ServiceManager.getService(Context.WINDOW_SERVICE));
+        SurfaceControl sc = new SurfaceControl.Builder()
+                .setName("Layer")
+                .setCallsite("testCaptureDisplay")
+                .build();
+
+        SurfaceControl.Transaction t = mActivity.addChildSc(sc);
+        mInstrumentation.waitForIdleSync();
+
+        GraphicBuffer buffer = GraphicBuffer.create(BUFFER_WIDTH, BUFFER_HEIGHT,
+                PixelFormat.RGBA_8888,
+                GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_HW_COMPOSER
+                        | GraphicBuffer.USAGE_SW_WRITE_RARELY);
+
+        Canvas canvas = buffer.lockCanvas();
+        canvas.drawColor(Color.RED);
+        buffer.unlockCanvasAndPost(canvas);
+
+        Point point = mActivity.getPositionBelowStatusBar();
+        t.show(sc)
+                .setBuffer(sc, HardwareBuffer.createFromGraphicBuffer(buffer))
+                .setDataSpace(sc, DataSpace.DATASPACE_SRGB)
+                .setPosition(sc, point.x, point.y)
+                .apply(true);
+
+        SyncScreenCaptureListener listener = new SyncScreenCaptureListener();
+        windowManager.captureDisplay(DEFAULT_DISPLAY, null, listener.getScreenCaptureListener());
+        ScreenCapture.ScreenshotHardwareBuffer hardwareBuffer = listener.waitForScreenshot();
+        assertNotNull(hardwareBuffer);
+
+        Bitmap screenshot = hardwareBuffer.asBitmap();
+        assertNotNull(screenshot);
+
+        Bitmap swBitmap = screenshot.copy(Bitmap.Config.ARGB_8888, false);
+        screenshot.recycle();
+
+        BitmapPixelChecker bitmapPixelChecker = new BitmapPixelChecker(PixelColor.RED);
+        Rect bounds = new Rect(point.x, point.y, BUFFER_WIDTH + point.x, BUFFER_HEIGHT + point.y);
+        int numMatchingPixels = bitmapPixelChecker.getNumMatchingPixels(swBitmap, bounds);
+        int pixelMatchSize = bounds.width() * bounds.height();
+        boolean success = numMatchingPixels == pixelMatchSize;
+
+        if (!success) {
+            SaveBitmapHelper.saveBitmap(swBitmap, getClass(), mTestName, "failedImage");
+        }
+        swBitmap.recycle();
+        assertTrue("numMatchingPixels=" + numMatchingPixels + " pixelMatchSize=" + pixelMatchSize,
+                success);
+    }
+
     public static class ScreenshotActivity extends Activity {
         private static final long WAIT_TIMEOUT_S = 5;
         private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -129,7 +202,6 @@
             super.onCreate(savedInstanceState);
             getWindow().getDecorView().setPointerIcon(
                     PointerIcon.getSystemIcon(this, PointerIcon.TYPE_NULL));
-            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
         }
 
         SurfaceControl.Transaction addChildSc(SurfaceControl surfaceControl) {
@@ -147,88 +219,14 @@
             }
             return t;
         }
-    }
 
-    public abstract static class PixelChecker {
-        static int getNumMatchingPixels(Bitmap bitmap, PixelColor pixelColor) {
-            int numMatchingPixels = 0;
-            for (int x = 0; x < bitmap.getWidth(); x++) {
-                for (int y = 0; y < bitmap.getHeight(); y++) {
-                    int color = bitmap.getPixel(x, y);
-                    if (matchesColor(pixelColor, color)) {
-                        numMatchingPixels++;
-                    }
-                }
-            }
-            return numMatchingPixels;
-        }
+        public Point getPositionBelowStatusBar() {
+            Insets statusBarInsets = getWindow()
+                    .getDecorView()
+                    .getRootWindowInsets()
+                    .getInsets(statusBars() | displayCutout());
 
-        static boolean matchesColor(PixelColor expectedColor, int color) {
-            final float red = Color.red(color);
-            final float green = Color.green(color);
-            final float blue = Color.blue(color);
-            final float alpha = Color.alpha(color);
-
-            return alpha <= expectedColor.mMaxAlpha
-                    && alpha >= expectedColor.mMinAlpha
-                    && red <= expectedColor.mMaxRed
-                    && red >= expectedColor.mMinRed
-                    && green <= expectedColor.mMaxGreen
-                    && green >= expectedColor.mMinGreen
-                    && blue <= expectedColor.mMaxBlue
-                    && blue >= expectedColor.mMinBlue;
-        }
-    }
-
-    public static class PixelColor {
-        public static final int BLACK = 0xFF000000;
-        public static final int RED = 0xFF0000FF;
-        public static final int GREEN = 0xFF00FF00;
-        public static final int BLUE = 0xFFFF0000;
-        public static final int YELLOW = 0xFF00FFFF;
-        public static final int MAGENTA = 0xFFFF00FF;
-        public static final int WHITE = 0xFFFFFFFF;
-
-        public static final int TRANSPARENT_RED = 0x7F0000FF;
-        public static final int TRANSPARENT_BLUE = 0x7FFF0000;
-        public static final int TRANSPARENT = 0x00000000;
-
-        // Default to black
-        public short mMinAlpha;
-        public short mMaxAlpha;
-        public short mMinRed;
-        public short mMaxRed;
-        public short mMinBlue;
-        public short mMaxBlue;
-        public short mMinGreen;
-        public short mMaxGreen;
-
-        public PixelColor(int color) {
-            short alpha = (short) ((color >> 24) & 0xFF);
-            short blue = (short) ((color >> 16) & 0xFF);
-            short green = (short) ((color >> 8) & 0xFF);
-            short red = (short) (color & 0xFF);
-
-            mMinAlpha = (short) getMinValue(alpha);
-            mMaxAlpha = (short) getMaxValue(alpha);
-            mMinRed = (short) getMinValue(red);
-            mMaxRed = (short) getMaxValue(red);
-            mMinBlue = (short) getMinValue(blue);
-            mMaxBlue = (short) getMaxValue(blue);
-            mMinGreen = (short) getMinValue(green);
-            mMaxGreen = (short) getMaxValue(green);
-        }
-
-        public PixelColor() {
-            this(BLACK);
-        }
-
-        private int getMinValue(short color) {
-            return Math.max(color - 4, 0);
-        }
-
-        private int getMaxValue(short color) {
-            return Math.min(color + 4, 0xFF);
+            return new Point(statusBarInsets.left, statusBarInsets.top);
         }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 9f7f341..54b33e97 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -210,10 +210,8 @@
         assertFitted();
 
         // After the orientation of activity is changed, the display is rotated, the aspect
-        // ratio should be the same (bounds=[100, 0 - 800, 583], appBounds=[100, 0 - 800, 583]).
+        // ratio should be the same (bounds=[0, 0 - 800, 583], appBounds=[100, 0 - 800, 583]).
         assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
-        // The notch is no longer on top.
-        assertEquals(appBounds, mActivity.getBounds());
         // Activity max bounds are sandboxed.
         assertActivityMaxBoundsSandboxed();
 
@@ -467,8 +465,6 @@
         assertEquals(ROTATION_270, mTask.getWindowConfiguration().getRotation());
 
         assertEquals(origBounds.width(), currentBounds.width());
-        // The notch is on horizontal side, so current height changes from 1460 to 1400.
-        assertEquals(origBounds.height() - notchHeight, currentBounds.height());
         // Make sure the app size is the same
         assertEquals(origAppBounds.width(), appBounds.width());
         assertEquals(origAppBounds.height(), appBounds.height());
@@ -2271,7 +2267,7 @@
         prepareUnresizable(mActivity, /* maxAspect */ 1.1f, SCREEN_ORIENTATION_UNSPECIFIED);
 
         // Bounds are letterboxed to respect the provided max aspect ratio.
-        assertEquals(mActivity.getBounds(), new Rect(0, 850, 1000, 1950));
+        assertEquals(mActivity.getBounds(), new Rect(0, 0, 1000, 1100));
 
         // Move activity to split screen which has landscape size.
         mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents */ false, "test");
@@ -2338,6 +2334,8 @@
 
     @Test
     public void testLetterboxDetailsForStatusBar_letterboxNotOverlappingStatusBar() {
+        // Align to center so that we don't overlap with the status bar
+        mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f);
         final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2800)
                 .setNotch(100)
                 .build();
@@ -2354,7 +2352,7 @@
         mActivity.mRootWindowContainer.performSurfacePlacement();
 
         Rect mBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
-        assertEquals(mBounds, new Rect(0, 750, 1000, 1950));
+        assertEquals(mBounds, new Rect(0, 900, 1000, 2000));
 
         DisplayPolicy displayPolicy = mActivity.getDisplayContent().getDisplayPolicy();
         LetterboxDetails[] expectedLetterboxDetails = {new LetterboxDetails(
@@ -2454,7 +2452,7 @@
                 // At launch.
                 /* fixedOrientationLetterbox */ new Rect(0, 0, 700, 1400),
                 // After 90 degree rotation.
-                /* sizeCompatUnscaled */ new Rect(0, 700, 700, 2100),
+                /* sizeCompatUnscaled */ new Rect(0, 0, 700, 1400),
                 // After the display is resized to (700, 1400).
                 /* sizeCompatScaled */ new Rect(0, 0, 350, 700));
     }
@@ -2467,7 +2465,7 @@
                 // At launch.
                 /* fixedOrientationLetterbox */ new Rect(1050, 0, 1750, 1400),
                 // After 90 degree rotation.
-                /* sizeCompatUnscaled */ new Rect(350, 700, 1050, 2100),
+                /* sizeCompatUnscaled */ new Rect(350, 0, 1050, 1400),
                 // After the display is resized to (700, 1400).
                 /* sizeCompatScaled */ new Rect(525, 0, 875, 700));
     }
@@ -2482,7 +2480,7 @@
                 // At launch.
                 /* fixedOrientationLetterbox */ new Rect(1050, 0, 1750, 1400),
                 // After 90 degree rotation.
-                /* sizeCompatUnscaled */ new Rect(350, 700, 1050, 2100),
+                /* sizeCompatUnscaled */ new Rect(350, 0, 1050, 1400),
                 // After the display is resized to (700, 1400).
                 /* sizeCompatScaled */ new Rect(525, 0, 875, 700));
 
@@ -2492,7 +2490,7 @@
                 // At launch.
                 /* fixedOrientationLetterbox */ new Rect(1050, 0, 1750, 1400),
                 // After 90 degree rotation.
-                /* sizeCompatUnscaled */ new Rect(350, 700, 1050, 2100),
+                /* sizeCompatUnscaled */ new Rect(350, 0, 1050, 1400),
                 // After the display is resized to (700, 1400).
                 /* sizeCompatScaled */ new Rect(525, 0, 875, 700));
     }
@@ -2505,7 +2503,7 @@
                 // At launch.
                 /* fixedOrientationLetterbox */ new Rect(2100, 0, 2800, 1400),
                 // After 90 degree rotation.
-                /* sizeCompatUnscaled */ new Rect(700, 700, 1400, 2100),
+                /* sizeCompatUnscaled */ new Rect(700, 0, 1400, 1400),
                 // After the display is resized to (700, 1400).
                 /* sizeCompatScaled */ new Rect(1050, 0, 1400, 700));
     }
@@ -2534,6 +2532,64 @@
     }
 
     @Test
+    public void testApplyAspectRatio_activityAlignWithParentAppVertical() {
+        // The display's app bounds will be (0, 100, 1000, 2350)
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500)
+                .setCanRotate(false)
+                .setCutout(0, 100, 0, 150)
+                .build();
+
+        setUpApp(display);
+        prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+        // The activity height is 2100 and the display's app bounds height is 2250, so the activity
+        // can be aligned inside parentAppBounds
+        assertEquals(mActivity.getBounds(), new Rect(0, 0, 1000, 2200));
+    }
+    @Test
+    public void testApplyAspectRatio_activityCannotAlignWithParentAppVertical() {
+        // The display's app bounds will be (0, 100, 1000, 2150)
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2300)
+                .setCanRotate(false)
+                .setCutout(0, 100, 0, 150)
+                .build();
+
+        setUpApp(display);
+        prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+        // The activity height is 2100 and the display's app bounds height is 2050, so the activity
+        // cannot be aligned inside parentAppBounds and it will fill the parentBounds of the display
+        assertEquals(mActivity.getBounds(), display.getBounds());
+    }
+
+    @Test
+    public void testApplyAspectRatio_activityAlignWithParentAppHorizontal() {
+        // The display's app bounds will be (100, 0, 2350, 1000)
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2500, 1000)
+                .setCanRotate(false)
+                .setCutout(100, 0, 150, 0)
+                .build();
+
+        setUpApp(display);
+        prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+        // The activity width is 2100 and the display's app bounds width is 2250, so the activity
+        // can be aligned inside parentAppBounds
+        assertEquals(mActivity.getBounds(), new Rect(175, 0, 2275, 1000));
+    }
+    @Test
+    public void testApplyAspectRatio_activityCannotAlignWithParentAppHorizontal() {
+        // The display's app bounds will be (100, 0, 2150, 1000)
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2300, 1000)
+                .setCanRotate(false)
+                .setCutout(100, 0, 150, 0)
+                .build();
+
+        setUpApp(display);
+        prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+        // The activity width is 2100 and the display's app bounds width is 2050, so the activity
+        // cannot be aligned inside parentAppBounds and it will fill the parentBounds of the display
+        assertEquals(mActivity.getBounds(), display.getBounds());
+    }
+
+    @Test
     public void testUpdateResolvedBoundsHorizontalPosition_activityFillParentWidth() {
         // When activity width equals parent width, multiplier shouldn't have any effect.
         assertHorizontalPositionForDifferentDisplayConfigsForLandscapeActivity(
@@ -2608,6 +2664,25 @@
                 /* sizeCompatScaled */ new Rect(0, 1050, 700, 1400));
     }
 
+    @Test
+    public void testUpdateResolvedBoundsPosition_alignToTop() {
+        final int notchHeight = 100;
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2800)
+                .setNotch(notchHeight)
+                .build();
+        setUpApp(display);
+
+        // Prepare unresizable activity with max aspect ratio
+        prepareUnresizable(mActivity, /* maxAspect */ 1.1f, SCREEN_ORIENTATION_UNSPECIFIED);
+
+        Rect mBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
+        Rect appBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
+        // The insets should be cut for aspect ratio and then added back because the appBounds
+        // are aligned to the top of the parentAppBounds
+        assertEquals(mBounds, new Rect(0, 0, 1000, 1200));
+        assertEquals(appBounds, new Rect(0, notchHeight, 1000, 1200));
+    }
+
     private void assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
             float letterboxVerticalPositionMultiplier, Rect fixedOrientationLetterbox,
             Rect sizeCompatUnscaled, Rect sizeCompatScaled) {
@@ -2955,7 +3030,7 @@
         rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
         assertTrue(mActivity.inSizeCompatMode());
         // Activity is in size compat mode but not scaled.
-        assertEquals(new Rect(0, 1050, 1400, 1750), mActivity.getBounds());
+        assertEquals(new Rect(0, 0, 1400, 700), mActivity.getBounds());
     }
 
     private void assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index ff0063c..6c8a7ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -361,7 +361,7 @@
 
         @Override
         public Builder makeAnimationLeash() {
-            return new SurfaceControl.Builder(mSession) {
+            return new Builder(mSession) {
 
                 @Override
                 public SurfaceControl build() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index aa3ca18..bf1d1fa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -143,11 +143,24 @@
             mInfo.ownerUid = ownerUid;
             return this;
         }
-        Builder setNotch(int height) {
+        Builder setCutout(int left, int top, int right, int bottom) {
+            final int cutoutFillerSize = 80;
+            Rect boundLeft = left != 0 ? new Rect(0, 0, left, cutoutFillerSize) : null;
+            Rect boundTop = top != 0 ? new Rect(0, 0, cutoutFillerSize, top) : null;
+            Rect boundRight = right != 0 ? new Rect(mInfo.logicalWidth - right, 0,
+                    mInfo.logicalWidth, cutoutFillerSize) : null;
+            Rect boundBottom = bottom != 0
+                    ? new Rect(0, mInfo.logicalHeight - bottom, cutoutFillerSize,
+                    mInfo.logicalHeight) : null;
+
             mInfo.displayCutout = new DisplayCutout(
-                    Insets.of(0, height, 0, 0), null, new Rect(20, 0, 80, height), null, null);
+                    Insets.of(left, top, right, bottom),
+                    boundLeft, boundTop, boundRight, boundBottom);
             return this;
         }
+        Builder setNotch(int height) {
+            return setCutout(0, height, 0, 0);
+        }
         Builder setStatusBarHeight(int height) {
             mStatusBarHeight = height;
             return this;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 048cd7c..e2dff96 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
@@ -31,7 +32,8 @@
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
-import static android.window.TransitionInfo.FLAG_IS_EMBEDDED;
+import static android.window.TransitionInfo.FLAG_FILLS_TASK;
+import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
@@ -730,7 +732,7 @@
         assertTrue(ime.mToken.inTransition());
         assertTrue(task.inTransition());
         assertTrue(asyncRotationController.isTargetToken(decorToken));
-        assertTrue(asyncRotationController.shouldFreezeInsetsPosition(navBar));
+        assertShouldFreezeInsetsPosition(asyncRotationController, statusBar, true);
 
         screenDecor.setOrientationChanging(false);
         // Status bar finishes drawing before the start transaction. Its fade-in animation will be
@@ -745,6 +747,7 @@
         // The transaction is committed, so fade-in animation for status bar is consumed.
         transactionCommittedListener.onTransactionCommitted();
         assertFalse(asyncRotationController.isTargetToken(statusBar.mToken));
+        assertShouldFreezeInsetsPosition(asyncRotationController, navBar, false);
 
         // Navigation bar finishes drawing after the start transaction, so its fade-in animation
         // can execute directly.
@@ -780,7 +783,7 @@
         final AsyncRotationController asyncRotationController =
                 mDisplayContent.getAsyncRotationController();
         assertNotNull(asyncRotationController);
-        assertTrue(asyncRotationController.shouldFreezeInsetsPosition(statusBar));
+        assertShouldFreezeInsetsPosition(asyncRotationController, statusBar, true);
 
         statusBar.setOrientationChanging(true);
         player.startTransition();
@@ -826,7 +829,7 @@
         final AsyncRotationController asyncRotationController =
                 mDisplayContent.getAsyncRotationController();
         assertNotNull(asyncRotationController);
-        assertTrue(asyncRotationController.shouldFreezeInsetsPosition(statusBar));
+        assertShouldFreezeInsetsPosition(asyncRotationController, statusBar, true);
         assertTrue(app.getTask().inTransition());
 
         player.start();
@@ -861,6 +864,15 @@
         assertNull(mDisplayContent.getAsyncRotationController());
     }
 
+    private static void assertShouldFreezeInsetsPosition(AsyncRotationController controller,
+            WindowState w, boolean freeze) {
+        if (TransitionController.SYNC_METHOD != BLASTSyncEngine.METHOD_BLAST) {
+            // Non blast sync should never freeze insets position.
+            freeze = false;
+        }
+        assertEquals(freeze, controller.shouldFreezeInsetsPosition(w));
+    }
+
     @Test
     public void testDeferRotationForTransientLaunch() {
         final TestTransitionPlayer player = registerTestTransitionPlayer();
@@ -1065,12 +1077,14 @@
     }
 
     @Test
-    public void testIsEmbeddedChange() {
+    public void testFlagInTaskWithEmbeddedActivity() {
         final Transition transition = createTestTransition(TRANSIT_OPEN);
         final ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
         final ArraySet<WindowContainer> participants = transition.mParticipants;
 
         final Task task = createTask(mDisplayContent);
+        final ActivityRecord nonEmbeddedActivity = createActivityRecord(task);
+        assertFalse(nonEmbeddedActivity.isEmbedded());
         final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
         mAtm.mTaskFragmentOrganizerController.registerOrganizer(
                 ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder()));
@@ -1085,20 +1099,72 @@
         changes.put(embeddedTf, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
         changes.put(closingActivity, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
         changes.put(openingActivity, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+        changes.put(nonEmbeddedActivity, new Transition.ChangeInfo(true /* vis */,
+                false /* exChg */));
         // End states.
         closingActivity.mVisibleRequested = false;
         openingActivity.mVisibleRequested = true;
+        nonEmbeddedActivity.mVisibleRequested = false;
 
         participants.add(closingActivity);
         participants.add(openingActivity);
+        participants.add(nonEmbeddedActivity);
         final ArrayList<WindowContainer> targets = Transition.calculateTargets(
                 participants, changes);
         final TransitionInfo info = Transition.calculateTransitionInfo(
                 transition.mType, 0 /* flags */, targets, changes, mMockT);
 
+        // All windows in the Task should have FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY because the Task
+        // contains embedded activity.
+        assertEquals(3, info.getChanges().size());
+        assertTrue(info.getChanges().get(0).hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY));
+        assertTrue(info.getChanges().get(1).hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY));
+        assertTrue(info.getChanges().get(2).hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY));
+    }
+
+    @Test
+    public void testFlagFillsTask() {
+        final Transition transition = createTestTransition(TRANSIT_OPEN);
+        final ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges;
+        final ArraySet<WindowContainer> participants = transition.mParticipants;
+
+        final Task task = createTask(mDisplayContent);
+        // Set to multi-windowing mode in order to set bounds.
+        task.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        final Rect taskBounds = new Rect(0, 0, 500, 1000);
+        task.setBounds(taskBounds);
+        final ActivityRecord nonEmbeddedActivity = createActivityRecord(task);
+        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+        mAtm.mTaskFragmentOrganizerController.registerOrganizer(
+                ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder()));
+        final TaskFragment embeddedTf = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .createActivityCount(1)
+                .setOrganizer(organizer)
+                .build();
+        final ActivityRecord embeddedActivity = embeddedTf.getTopMostActivity();
+        // Start states.
+        changes.put(task, new Transition.ChangeInfo(true /* vis */, false /* exChg */));
+        changes.put(nonEmbeddedActivity, new Transition.ChangeInfo(true /* vis */,
+                false /* exChg */));
+        changes.put(embeddedTf, new Transition.ChangeInfo(false /* vis */, true /* exChg */));
+        // End states.
+        nonEmbeddedActivity.mVisibleRequested = false;
+        embeddedActivity.mVisibleRequested = true;
+        embeddedTf.setBounds(new Rect(0, 0, 500, 500));
+
+        participants.add(nonEmbeddedActivity);
+        participants.add(embeddedTf);
+        final ArrayList<WindowContainer> targets = Transition.calculateTargets(
+                participants, changes);
+        final TransitionInfo info = Transition.calculateTransitionInfo(
+                transition.mType, 0 /* flags */, targets, changes, mMockT);
+
+        // The embedded with bounds overridden should not have the flag.
         assertEquals(2, info.getChanges().size());
-        assertTrue((info.getChanges().get(0).getFlags() & FLAG_IS_EMBEDDED) != 0);
-        assertTrue((info.getChanges().get(1).getFlags() & FLAG_IS_EMBEDDED) != 0);
+        assertFalse(info.getChanges().get(0).hasFlags(FLAG_FILLS_TASK));
+        assertEquals(embeddedTf.getBounds(), info.getChanges().get(0).getEndAbsBounds());
+        assertFalse(info.getChanges().get(1).hasFlags(FLAG_FILLS_TASK));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 46b4b76..8b63904 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -41,6 +41,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
@@ -68,6 +69,7 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.window.ClientWindowFrames;
+import android.window.ScreenCapture;
 import android.window.WindowContainerToken;
 
 import androidx.test.filters.SmallTest;
@@ -423,6 +425,45 @@
                 LETTERBOX_BACKGROUND_SOLID_COLOR)).isFalse();
     }
 
+    @Test
+    public void testCaptureDisplay() {
+        Rect displayBounds = new Rect(0, 0, 100, 200);
+        spyOn(mDisplayContent);
+        when(mDisplayContent.getBounds()).thenReturn(displayBounds);
+
+        // Null captureArgs
+        ScreenCapture.LayerCaptureArgs resultingArgs =
+                mWm.getCaptureArgs(DEFAULT_DISPLAY, null /* captureArgs */);
+        assertEquals(displayBounds, resultingArgs.mSourceCrop);
+
+        // Non null captureArgs, didn't set rect
+        ScreenCapture.CaptureArgs captureArgs = new ScreenCapture.CaptureArgs.Builder<>().build();
+        resultingArgs = mWm.getCaptureArgs(DEFAULT_DISPLAY, captureArgs);
+        assertEquals(displayBounds, resultingArgs.mSourceCrop);
+
+        // Non null captureArgs, invalid rect
+        captureArgs = new ScreenCapture.CaptureArgs.Builder<>()
+                .setSourceCrop(new Rect(0, 0, -1, -1))
+                .build();
+        resultingArgs = mWm.getCaptureArgs(DEFAULT_DISPLAY, captureArgs);
+        assertEquals(displayBounds, resultingArgs.mSourceCrop);
+
+        // Non null captureArgs, null rect
+        captureArgs = new ScreenCapture.CaptureArgs.Builder<>()
+                .setSourceCrop(null)
+                .build();
+        resultingArgs = mWm.getCaptureArgs(DEFAULT_DISPLAY, captureArgs);
+        assertEquals(displayBounds, resultingArgs.mSourceCrop);
+
+        // Non null captureArgs, valid rect
+        Rect validRect = new Rect(0, 0, 10, 50);
+        captureArgs = new ScreenCapture.CaptureArgs.Builder<>()
+                .setSourceCrop(validRect)
+                .build();
+        resultingArgs = mWm.getCaptureArgs(DEFAULT_DISPLAY, captureArgs);
+        assertEquals(validRect, resultingArgs.mSourceCrop);
+    }
+
     private void setupActivityWithLaunchCookie(IBinder launchCookie, WindowContainerToken wct) {
         final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class);
         when(remoteToken.toWindowContainerToken()).thenReturn(wct);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 353b757..9c9f5db 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -97,6 +97,7 @@
 import android.view.WindowManager;
 import android.view.WindowManager.DisplayImePolicy;
 import android.window.ITransitionPlayer;
+import android.window.ScreenCapture;
 import android.window.StartingWindowInfo;
 import android.window.StartingWindowRemovalInfo;
 import android.window.TaskFragmentOrganizer;
@@ -241,7 +242,7 @@
         // Ensure letterbox vertical position multiplier is not overridden on any device target.
         // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
         // may be set on some device form factors.
-        mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f);
+        mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.0f);
         // Ensure letterbox horizontal reachability treatment isn't overridden on any device target.
         // {@link com.android.internal.R.bool.config_letterboxIsHorizontalReachabilityEnabled},
         // may be set on some device form factors.
@@ -946,8 +947,8 @@
 
     /** Mocks the behavior of taking a snapshot. */
     void mockSurfaceFreezerSnapshot(SurfaceFreezer surfaceFreezer) {
-        final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                mock(SurfaceControl.ScreenshotHardwareBuffer.class);
+        final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
+                mock(ScreenCapture.ScreenshotHardwareBuffer.class);
         final HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
         spyOn(surfaceFreezer);
         doReturn(screenshotBuffer).when(surfaceFreezer)
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 77fca45..a95fa5a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -147,7 +147,7 @@
     }
 
     private static class HierarchyRecordingBuilderFactory implements Function<SurfaceSession,
-                SurfaceControl.Builder> {
+            SurfaceControl.Builder> {
         private LayerRecordingTransaction mTransaction;
 
         HierarchyRecordingBuilderFactory(LayerRecordingTransaction transaction) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 046ff66..7f5beb1 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -233,6 +233,7 @@
     final SparseArray<ActivityData> mVisibleActivities = new SparseArray();
     @GuardedBy("mLock")
     private final SparseArray<LaunchTimeAlarmQueue> mLaunchTimeAlarmQueues = new SparseArray<>();
+    @GuardedBy("mUsageEventListeners") // Don't hold the main lock when calling out
     private final ArraySet<UsageStatsManagerInternal.UsageEventListener> mUsageEventListeners =
             new ArraySet<>();
     private final CopyOnWriteArraySet<UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener>
@@ -1189,9 +1190,11 @@
             service.reportEvent(event);
         }
 
-        final int size = mUsageEventListeners.size();
-        for (int i = 0; i < size; ++i) {
-            mUsageEventListeners.valueAt(i).onUsageEvent(userId, event);
+        synchronized (mUsageEventListeners) {
+            final int size = mUsageEventListeners.size();
+            for (int i = 0; i < size; ++i) {
+                mUsageEventListeners.valueAt(i).onUsageEvent(userId, event);
+            }
         }
     }
 
@@ -1682,7 +1685,7 @@
      * Called via the local interface.
      */
     private void registerListener(@NonNull UsageStatsManagerInternal.UsageEventListener listener) {
-        synchronized (mLock) {
+        synchronized (mUsageEventListeners) {
             mUsageEventListeners.add(listener);
         }
     }
@@ -1692,7 +1695,7 @@
      */
     private void unregisterListener(
             @NonNull UsageStatsManagerInternal.UsageEventListener listener) {
-        synchronized (mLock) {
+        synchronized (mUsageEventListeners) {
             mUsageEventListeners.remove(listener);
         }
     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 4b9b4a9..4ee066c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1284,12 +1284,13 @@
             }
         }
 
-        @android.annotation.EnforcePermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD})
         @Override
         public void startListeningFromMic(
                 AudioFormat audioFormat,
                 IMicrophoneHotwordDetectionVoiceInteractionCallback callback)
                 throws RemoteException {
+            enforceCallingPermission(Manifest.permission.RECORD_AUDIO);
+            enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
             synchronized (this) {
                 enforceIsCurrentVoiceInteractionService();
 
@@ -1349,12 +1350,13 @@
             }
         }
 
-        @android.annotation.EnforcePermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD})
         @Override
         public void triggerHardwareRecognitionEventForTest(
                 SoundTrigger.KeyphraseRecognitionEvent event,
                 IHotwordRecognitionStatusCallback callback)
                 throws RemoteException {
+            enforceCallingPermission(Manifest.permission.RECORD_AUDIO);
+            enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
             synchronized (this) {
                 enforceIsCurrentVoiceInteractionService();
 
diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java
index e7d95e4..061b71b 100644
--- a/telephony/java/android/telephony/AnomalyReporter.java
+++ b/telephony/java/android/telephony/AnomalyReporter.java
@@ -27,6 +27,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.ParcelUuid;
+import android.provider.DeviceConfig;
 
 import com.android.internal.telephony.TelephonyStatsLog;
 import com.android.internal.util.IndentingPrintWriter;
@@ -57,6 +58,9 @@
 public final class AnomalyReporter {
     private static final String TAG = "AnomalyReporter";
 
+    private static final String KEY_IS_TELEPHONY_ANOMALY_REPORT_ENABLED =
+            "is_telephony_anomaly_report_enabled";
+
     private static Context sContext = null;
 
     private static Map<UUID, Integer> sEvents = new ConcurrentHashMap<>();
@@ -106,6 +110,18 @@
             return;
         }
 
+        // Don't report if the server-side flag isn't loaded, as it implies other anomaly report
+        // related config hasn't loaded.
+        try {
+            boolean isAnomalyReportEnabledFromServer = DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_TELEPHONY, KEY_IS_TELEPHONY_ANOMALY_REPORT_ENABLED,
+                    false);
+            if (!isAnomalyReportEnabledFromServer) return;
+        } catch (Exception e) {
+            Rlog.w(TAG, "Unable to read device config, dropping event=" + eventId);
+            return;
+        }
+
         TelephonyStatsLog.write(
                 TELEPHONY_ANOMALY_DETECTED,
                 carrierId,
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 16f8fd9..b6944eb 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -489,7 +489,10 @@
     /**
      * Control whether users receive a simplified network settings UI and improved network
      * selection.
+     *
+     * @deprecated Never implemented. Has no behavior impact when override. DO NOT USE.
      */
+    @Deprecated
     public static final String
             KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL = "simplified_network_settings_bool";
 
@@ -8666,7 +8669,7 @@
      *     or EIMS-->
      *     <item value="source=EUTRAN, target=IWLAN, type=disallowed, capabilities=IMS|EIMS"/>
      *     <!-- Handover is always allowed in any condition. -->
-     *     <item value="source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN,
+     *     <item value="source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN|UNKNOWN,
      *         target=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed"/>
      * </string-array>
      *
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 4fb6587..c608507 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1071,6 +1071,13 @@
     public static final String ALLOWED_NETWORK_TYPES =
             SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS;
 
+    /**
+     * TelephonyProvider column name for user handle associated with a sim.
+     * <P>Type: INTEGER (int)</P>
+     * @hide
+     */
+    public static final String USER_HANDLE = SimInfo.COLUMN_USER_HANDLE;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"USAGE_SETTING_"},
@@ -3456,10 +3463,20 @@
      * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
      * See {@link #createSubscriptionGroup(List)} for more details.
      *
-     * Caller will either have {@link android.Manifest.permission#READ_PHONE_STATE}
-     * permission or had carrier privilege permission on the subscription.
+     * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE}
+     * or carrier privilege permission on the subscription.
      * {@link TelephonyManager#hasCarrierPrivileges()}
      *
+     * <p>Starting with API level 33, the caller also needs permission to access device identifiers
+     * to get the list of subscriptions associated with a group UUID.
+     * This method can be invoked if one of the following requirements is met:
+     * <ul>
+     *     <li>If the app has carrier privilege permission.
+     *     {@link TelephonyManager#hasCarrierPrivileges()}
+     *     <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} permission and
+     *     access to device identifiers.
+     * </ul>
+     *
      * @throws IllegalStateException if Telephony service is in bad state.
      * @throws SecurityException if the caller doesn't meet the requirements
      *             outlined above.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b4244dd..12b4114 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -191,6 +191,9 @@
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
     private static final long CALLBACK_ON_MORE_ERROR_CODE_CHANGE = 130595455L;
 
+    // Null IMEI anomaly uuid
+    private static final UUID IMEI_ANOMALY_UUID = UUID.fromString(
+            "83905f14-6455-450c-be29-8206f0427fe9");
     /**
      * The key to use when placing the result of {@link #requestModemActivityInfo(ResultReceiver)}
      * into the ResultReceiver Bundle.
@@ -2181,7 +2184,11 @@
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_GSM)
     public String getImei() {
-        return getImei(getSlotIndex());
+        String imei = getImei(getSlotIndex());
+        if (imei == null) {
+            AnomalyReporter.reportAnomaly(IMEI_ANOMALY_UUID, "getImei: IMEI is null.");
+        }
+        return imei;
     }
 
     /**
@@ -2224,7 +2231,10 @@
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_GSM)
     public String getImei(int slotIndex) {
         ITelephony telephony = getITelephony();
-        if (telephony == null) return null;
+        if (telephony == null) {
+            AnomalyReporter.reportAnomaly(IMEI_ANOMALY_UUID, "getImei: telephony is null");
+            return null;
+        }
 
         try {
             return telephony.getImeiForSlot(slotIndex, getOpPackageName(), getAttributionTag());
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index 54662ef..725963b 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -214,5 +214,34 @@
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
+        <service
+            android:name=".AssistantInteractionSessionService"
+            android:exported="true"
+            android:permission="android.permission.BIND_VOICE_INTERACTION" />
+        <service
+            android:name=".AssistantRecognitionService"
+            android:exported="true"
+            android:label="Test Voice Interaction Service">
+            <intent-filter>
+                <action android:name="android.speech.RecognitionService" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data
+                android:name="android.speech"
+                android:resource="@xml/recognition_service" />
+        </service>
+        <service
+            android:name=".AssistantInteractionService"
+            android:exported="true"
+            android:label="Test Voice Interaction Service"
+            android:permission="android.permission.BIND_VOICE_INTERACTION">
+            <intent-filter>
+                <action android:name="android.service.voice.VoiceInteractionService" />
+            </intent-filter>
+            <meta-data
+                android:name="android.voice_interaction"
+                android:resource="@xml/interaction_service" />
+        </service>
     </application>
+    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
 </manifest>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/assistant_session.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/assistant_session.xml
new file mode 100644
index 0000000..eb7f307
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/assistant_session.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <FrameLayout
+        android:id="@+id/vis_frame"
+        android:layout_width="match_parent"
+        android:layout_height="300dp"
+        android:layout_gravity="bottom"
+        android:background="#37474F"/>
+</FrameLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/xml/interaction_service.xml b/tests/FlickerTests/test-apps/flickerapp/res/xml/interaction_service.xml
new file mode 100644
index 0000000..2e661fb
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/res/xml/interaction_service.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:recognitionService="com.android.server.wm.flicker.testapp.AssistantRecognitionService"
+    android:sessionService="com.android.server.wm.flicker.testapp.AssistantInteractionSessionService"
+    android:supportsAssist="true" />
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/xml/recognition_service.xml b/tests/FlickerTests/test-apps/flickerapp/res/xml/recognition_service.xml
new file mode 100644
index 0000000..2e12498
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/res/xml/recognition_service.xml
@@ -0,0 +1,17 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<recognition-service xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionService.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionService.java
new file mode 100644
index 0000000..d60143c
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionService.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.testapp;
+
+import android.service.voice.VoiceInteractionService;
+
+public class AssistantInteractionService extends VoiceInteractionService {
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionSession.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionSession.java
new file mode 100644
index 0000000..d2c9b37
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionSession.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.testapp;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.view.View;
+import android.view.Window;
+
+public class AssistantInteractionSession extends VoiceInteractionSession {
+
+    public AssistantInteractionSession(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onCreate() {
+        Window window = getWindow().getWindow();
+        if (window != null) {
+            window.getDecorView().setBackgroundColor(Color.TRANSPARENT);
+
+        }
+        View rootView = getLayoutInflater().inflate(R.layout.assistant_session, null);
+        setContentView(rootView);
+        setUiEnabled(false);
+    }
+
+    @Override
+    public void onShow(Bundle args, int showFlags) {
+        setUiEnabled(true);
+    }
+
+    @Override
+    public void onHide() {
+        setUiEnabled(false);
+    }
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionSessionService.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionSessionService.java
new file mode 100644
index 0000000..4d6125c
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantInteractionSessionService.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.testapp;
+
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.service.voice.VoiceInteractionSessionService;
+
+public class AssistantInteractionSessionService extends VoiceInteractionSessionService {
+    @Override
+    public VoiceInteractionSession onNewSession(Bundle args) {
+        return new AssistantInteractionSession(this);
+    }
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantRecognitionService.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantRecognitionService.java
new file mode 100644
index 0000000..68aae45
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/AssistantRecognitionService.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.testapp;
+
+import android.content.Intent;
+import android.speech.RecognitionService;
+
+public class AssistantRecognitionService extends RecognitionService {
+    @Override
+    protected void onStartListening(Intent recognizerIntent, Callback listener) {
+
+    }
+
+    @Override
+    protected void onCancel(Callback listener) {
+
+    }
+
+    @Override
+    protected void onStopListening(Callback listener) {
+
+    }
+}
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index b0ccbd1..939c7de 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -436,6 +436,15 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="SurfaceViewAlphaActivity"
+             android:label="SurfaceView/SurfaceView with Alpha"
+             android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="com.android.test.hwui.TEST"/>
+            </intent-filter>
+        </activity>
+
         <activity android:name=".PenStylusActivity"
                   android:label="Pen/Draw"
                   android:exported="true">
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/SurfaceViewAlphaActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/SurfaceViewAlphaActivity.java
new file mode 100644
index 0000000..01fe6ae0
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/SurfaceViewAlphaActivity.java
@@ -0,0 +1,168 @@
+/*
+ * 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
+ *
+ *      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.test.hwui;
+
+import android.app.Activity;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.SurfaceHolder;
+import android.view.SurfaceHolder.Callback;
+import android.view.SurfaceView;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+public class SurfaceViewAlphaActivity extends Activity implements Callback {
+    SurfaceView mSurfaceView;
+
+    private enum ZOrder {
+        ABOVE,
+        BELOW
+    }
+
+    private float mAlpha = 127f / 255f;
+    private ZOrder mZOrder = ZOrder.BELOW;
+
+
+    private String getAlphaText() {
+        return "Alpha: " + mAlpha;
+    }
+
+    private void toggleZOrder() {
+        if (ZOrder.ABOVE.equals(mZOrder)) {
+            mZOrder = ZOrder.BELOW;
+        } else {
+            mZOrder = ZOrder.ABOVE;
+        }
+    }
+
+    // Overlaps a blue view on the left, then the SurfaceView in the center, then a blue view on the
+    // right.
+    private void overlapViews(SurfaceView view, LinearLayout parent) {
+        float density = getResources().getDisplayMetrics().density;
+        int surfaceViewSize = (int) (200 * density);
+        int blueViewSize = (int) (surfaceViewSize * 2 / 3f);
+        int totalSize = (int) (surfaceViewSize * 5 / 3f);
+
+        RelativeLayout overlapLayout = new RelativeLayout(this);
+
+        RelativeLayout.LayoutParams leftViewLayoutParams = new RelativeLayout.LayoutParams(
+                blueViewSize, surfaceViewSize);
+        leftViewLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
+
+        View leftBlueView = new View(this);
+        leftBlueView.setBackgroundColor(Color.BLUE);
+        overlapLayout.addView(leftBlueView, leftViewLayoutParams);
+
+        RelativeLayout.LayoutParams sVLayoutParams = new RelativeLayout.LayoutParams(
+                surfaceViewSize, surfaceViewSize);
+        sVLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
+        overlapLayout.addView(view, sVLayoutParams);
+
+        RelativeLayout.LayoutParams rightViewLayoutParams = new RelativeLayout.LayoutParams(
+                blueViewSize, surfaceViewSize);
+        rightViewLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+
+        View rightBlueView = new View(this);
+        rightBlueView.setBackgroundColor(Color.BLUE);
+        overlapLayout.addView(rightBlueView, rightViewLayoutParams);
+
+        parent.addView(overlapLayout, new LinearLayout.LayoutParams(
+                totalSize, surfaceViewSize));
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mSurfaceView = new SurfaceView(this);
+        mSurfaceView.getHolder().addCallback(this);
+        mSurfaceView.setAlpha(mAlpha);
+
+        LinearLayout content = new LinearLayout(this);
+        content.setOrientation(LinearLayout.VERTICAL);
+
+        TextView alphaText = new TextView(this);
+        alphaText.setText(getAlphaText());
+
+        SeekBar alphaToggle = new SeekBar(this);
+        alphaToggle.setMin(0);
+        alphaToggle.setMax(255);
+        alphaToggle.setProgress(Math.round(mAlpha * 255));
+        alphaToggle.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                mAlpha = progress / 255f;
+                alphaText.setText(getAlphaText());
+                mSurfaceView.setAlpha(mAlpha);
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+
+            }
+        });
+
+        content.addView(alphaText, new LinearLayout.LayoutParams(
+                LinearLayout.LayoutParams.WRAP_CONTENT,
+                LinearLayout.LayoutParams.WRAP_CONTENT));
+
+        content.addView(alphaToggle, new LinearLayout.LayoutParams(
+                LinearLayout.LayoutParams.MATCH_PARENT,
+                LinearLayout.LayoutParams.WRAP_CONTENT));
+
+        Button button = new Button(this);
+        button.setText("Z " + mZOrder.toString());
+        button.setOnClickListener(v -> {
+            toggleZOrder();
+            mSurfaceView.setZOrderOnTop(ZOrder.ABOVE.equals(mZOrder));
+            button.setText("Z " + mZOrder.toString());
+        });
+
+        content.addView(button, new LinearLayout.LayoutParams(
+                LinearLayout.LayoutParams.WRAP_CONTENT,
+                LinearLayout.LayoutParams.WRAP_CONTENT));
+
+        overlapViews(mSurfaceView, content);
+
+        setContentView(content);
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+        Canvas canvas = holder.lockCanvas();
+        canvas.drawColor(Color.RED);
+        holder.unlockCanvasAndPost(canvas);
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+    }
+}
diff --git a/tools/fonts/Android.bp b/tools/fonts/Android.bp
index eeb9e3c..f8629f9 100644
--- a/tools/fonts/Android.bp
+++ b/tools/fonts/Android.bp
@@ -24,12 +24,7 @@
 python_defaults {
     name: "fonts_python_defaults",
     version: {
-        py2: {
-            enabled: false,
-            embedded_launcher: false,
-        },
         py3: {
-            enabled: true,
             embedded_launcher: true,
         },
     },
diff --git a/tools/processors/immutability/Android.bp b/tools/processors/immutability/Android.bp
new file mode 100644
index 0000000..985874b
--- /dev/null
+++ b/tools/processors/immutability/Android.bp
@@ -0,0 +1,67 @@
+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"],
+}
+
+java_library_host {
+    name: "ImmutabilityAnnotationProcessorHostLibrary",
+    srcs: [
+        "src/**/*.kt",
+        "src/**/*.java",
+    ],
+    use_tools_jar: true,
+    // The --add-modules/exports flags below don't work for kotlinc yet, so pin this module to Java
+    // language level 8 (see b/139342589):
+    java_version: "1.8",
+    openjdk9: {
+        javacflags: [
+            "--add-modules=jdk.compiler",
+            "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
+            "--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
+            "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+            "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+        ],
+    },
+}
+
+java_plugin {
+    name: "ImmutabilityAnnotationProcessor",
+    processor_class: "android.processor.immutability.ImmutabilityProcessor",
+    static_libs: ["ImmutabilityAnnotationProcessorHostLibrary"],
+}
+
+java_library {
+    name: "ImmutabilityAnnotation",
+    srcs: ["src/**/Immutable.java"],
+    sdk_version: "core_current",
+    host_supported: true,
+}
+
+java_test_host {
+    name: "ImmutabilityAnnotationProcessorUnitTests",
+
+    srcs: ["test/**/*.kt"],
+
+    static_libs: [
+        "compile-testing-prebuilt",
+        "truth-prebuilt",
+        "junit",
+        "kotlin-reflect",
+        "ImmutabilityAnnotationProcessorHostLibrary",
+    ],
+
+    // Bundle the source file so it can be loaded into the test compiler
+    java_resources: [":ImmutabilityAnnotationJavaSource"],
+
+    test_suites: ["general-tests"],
+}
+
+filegroup {
+    name: "ImmutabilityAnnotationJavaSource",
+    srcs: ["src/android/processor/immutability/Immutable.java"],
+    path: "src/android/processor/immutability/",
+}
diff --git a/tools/processors/immutability/OWNERS b/tools/processors/immutability/OWNERS
new file mode 100644
index 0000000..86ae581
--- /dev/null
+++ b/tools/processors/immutability/OWNERS
@@ -0,0 +1 @@
+include /PACKAGE_MANAGER_OWNERS
diff --git a/tools/processors/immutability/TEST_MAPPING b/tools/processors/immutability/TEST_MAPPING
new file mode 100644
index 0000000..4e8e238
--- /dev/null
+++ b/tools/processors/immutability/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+    "presubmit": [
+        {
+            "name": "ImmutabilityAnnotationProcessorUnitTests"
+        }
+    ]
+}
diff --git a/tools/processors/immutability/src/android/processor/immutability/ImmutabilityProcessor.kt b/tools/processors/immutability/src/android/processor/immutability/ImmutabilityProcessor.kt
new file mode 100644
index 0000000..43fc3a7
--- /dev/null
+++ b/tools/processors/immutability/src/android/processor/immutability/ImmutabilityProcessor.kt
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.processor.immutability
+
+import com.sun.tools.javac.code.Symbol
+import com.sun.tools.javac.code.Type
+import javax.annotation.processing.AbstractProcessor
+import javax.annotation.processing.ProcessingEnvironment
+import javax.annotation.processing.RoundEnvironment
+import javax.lang.model.SourceVersion
+import javax.lang.model.element.Element
+import javax.lang.model.element.ElementKind
+import javax.lang.model.element.Modifier
+import javax.lang.model.element.TypeElement
+import javax.lang.model.type.TypeKind
+import javax.lang.model.type.TypeMirror
+import javax.tools.Diagnostic
+
+val IMMUTABLE_ANNOTATION_NAME = Immutable::class.qualifiedName
+
+class ImmutabilityProcessor : AbstractProcessor() {
+
+    companion object {
+        /**
+         * Types that are already immutable.
+         */
+        private val IGNORED_TYPES = listOf(
+            "java.io.File",
+            "java.lang.Boolean",
+            "java.lang.Byte",
+            "java.lang.CharSequence",
+            "java.lang.Character",
+            "java.lang.Double",
+            "java.lang.Float",
+            "java.lang.Integer",
+            "java.lang.Long",
+            "java.lang.Short",
+            "java.lang.String",
+            "java.lang.Void",
+            "android.os.Parcelable.Creator",
+        )
+
+        private val IGNORED_METHODS = listOf(
+            "writeToParcel",
+        )
+    }
+
+    private lateinit var collectionType: TypeMirror
+    private lateinit var mapType: TypeMirror
+
+    private lateinit var ignoredTypes: List<TypeMirror>
+
+    private val seenTypesByPolicy = mutableMapOf<Set<Immutable.Policy.Exception>, Set<Type>>()
+
+    override fun getSupportedSourceVersion() = SourceVersion.latest()!!
+
+    override fun getSupportedAnnotationTypes() = setOf(Immutable::class.qualifiedName)
+
+    override fun init(processingEnv: ProcessingEnvironment) {
+        super.init(processingEnv)
+        collectionType = processingEnv.erasedType("java.util.Collection")!!
+        mapType = processingEnv.erasedType("java.util.Map")!!
+        ignoredTypes = IGNORED_TYPES.mapNotNull { processingEnv.erasedType(it) }
+    }
+
+    override fun process(
+        annotations: MutableSet<out TypeElement>,
+        roundEnvironment: RoundEnvironment
+    ): Boolean {
+        annotations.find {
+            it.qualifiedName.toString() == IMMUTABLE_ANNOTATION_NAME
+        } ?: return false
+        roundEnvironment.getElementsAnnotatedWith(Immutable::class.java)
+            .forEach {
+                visitClass(
+                    parentChain = emptyList(),
+                    seenTypesByPolicy = seenTypesByPolicy,
+                    elementToPrint = it,
+                    classType = it as Symbol.TypeSymbol,
+                    parentPolicyExceptions = emptySet()
+                )
+            }
+        return true
+    }
+
+    /**
+     * @return true if any error was encountered at this level or any child level
+     */
+    private fun visitClass(
+        parentChain: List<String>,
+        seenTypesByPolicy: MutableMap<Set<Immutable.Policy.Exception>, Set<Type>>,
+        elementToPrint: Element,
+        classType: Symbol.TypeSymbol,
+        parentPolicyExceptions: Set<Immutable.Policy.Exception>,
+    ): Boolean {
+        if (classType.getAnnotation(Immutable.Ignore::class.java) != null) return false
+
+        val policyAnnotation = classType.getAnnotation(Immutable.Policy::class.java)
+        val newPolicyExceptions = parentPolicyExceptions + policyAnnotation?.exceptions.orEmpty()
+
+        // If already seen this type with the same policies applied, skip it
+        val seenTypes = seenTypesByPolicy[newPolicyExceptions]
+        val type = classType.asType()
+        if (seenTypes?.contains(type) == true) return false
+        seenTypesByPolicy[newPolicyExceptions] = seenTypes.orEmpty() + type
+
+        val allowFinalClassesFinalFields =
+            newPolicyExceptions.contains(Immutable.Policy.Exception.FINAL_CLASSES_WITH_FINAL_FIELDS)
+
+        val filteredElements = classType.enclosedElements
+            .filterNot(::isIgnored)
+
+        val hasFieldError = filteredElements
+            .filter { it.getKind() == ElementKind.FIELD }
+            .fold(false) { anyError, field ->
+                if (field.isStatic) {
+                    if (!field.isPrivate) {
+                        var finalityError = !field.modifiers.contains(Modifier.FINAL)
+                        if (finalityError) {
+                            printError(parentChain, field, MessageUtils.staticNonFinalFailure())
+                        }
+
+                        // Must call visitType first so it doesn't get short circuited by the ||
+                        visitType(
+                            parentChain = parentChain,
+                            seenTypesByPolicy = seenTypesByPolicy,
+                            symbol = field,
+                            type = field.type,
+                            parentPolicyExceptions = parentPolicyExceptions
+                        ) || anyError || finalityError
+                    }
+                    return@fold anyError
+                } else {
+                    val isFinal = field.modifiers.contains(Modifier.FINAL)
+                    if (!isFinal || !allowFinalClassesFinalFields) {
+                        printError(parentChain, field, MessageUtils.memberNotMethodFailure())
+                        return@fold true
+                    }
+
+                    return@fold anyError
+                }
+            }
+
+        // Scan inner classes before methods so that any violations isolated to the file prints
+        // the error on the class declaration rather than on the method that returns the type.
+        // Although it doesn't matter too much either way.
+        val hasClassError = filteredElements
+            .filter { it.getKind() == ElementKind.CLASS }
+            .map { it as Symbol.ClassSymbol }
+            .fold(false) { anyError, innerClass ->
+                // Must call visitClass first so it doesn't get short circuited by the ||
+                visitClass(
+                    parentChain,
+                    seenTypesByPolicy,
+                    innerClass,
+                    innerClass,
+                    newPolicyExceptions
+                ) || anyError
+            }
+
+        val newChain = parentChain + "$classType"
+
+        val hasMethodError = filteredElements
+            .filter { it.getKind() == ElementKind.METHOD }
+            .map { it as Symbol.MethodSymbol }
+            .filterNot { IGNORED_METHODS.contains(it.name.toString()) }
+            .fold(false) { anyError, method ->
+                // Must call visitMethod first so it doesn't get short circuited by the ||
+                visitMethod(newChain, seenTypesByPolicy, method, newPolicyExceptions) || anyError
+            }
+
+        val className = classType.simpleName.toString()
+        val isRegularClass = classType.getKind() == ElementKind.CLASS
+
+        var anyError = hasFieldError || hasClassError || hasMethodError
+
+        // If final classes are not considered OR there's a non-field failure, also check for
+        // interface/@Immutable, assuming the class is malformed
+        if ((isRegularClass && !allowFinalClassesFinalFields) || hasMethodError || hasClassError) {
+            if (classType.getAnnotation(Immutable::class.java) == null) {
+                printError(
+                    parentChain,
+                    elementToPrint,
+                    MessageUtils.classNotImmutableFailure(className)
+                )
+                anyError = true
+            }
+
+            if (classType.getKind() != ElementKind.INTERFACE) {
+                printError(parentChain, elementToPrint, MessageUtils.nonInterfaceClassFailure())
+                anyError = true
+            }
+        }
+
+        if (isRegularClass && !anyError && allowFinalClassesFinalFields
+            && !classType.modifiers.contains(Modifier.FINAL)
+        ) {
+            printError(parentChain, elementToPrint, MessageUtils.classNotFinalFailure(className))
+            return true
+        }
+
+        return anyError
+    }
+
+    /**
+     * @return true if any error was encountered at this level or any child level
+     */
+    private fun visitMethod(
+        parentChain: List<String>,
+        seenTypesByPolicy: MutableMap<Set<Immutable.Policy.Exception>, Set<Type>>,
+        method: Symbol.MethodSymbol,
+        parentPolicyExceptions: Set<Immutable.Policy.Exception>,
+    ): Boolean {
+        val returnType = method.returnType
+        val typeName = returnType.toString()
+        when (returnType.kind) {
+            TypeKind.BOOLEAN,
+            TypeKind.BYTE,
+            TypeKind.SHORT,
+            TypeKind.INT,
+            TypeKind.LONG,
+            TypeKind.CHAR,
+            TypeKind.FLOAT,
+            TypeKind.DOUBLE,
+            TypeKind.NONE,
+            TypeKind.NULL -> {
+                // Do nothing
+            }
+            TypeKind.VOID -> {
+                if (!method.isConstructor) {
+                    printError(parentChain, method, MessageUtils.voidReturnFailure())
+                    return true
+                }
+            }
+            TypeKind.ARRAY -> {
+                printError(parentChain, method, MessageUtils.arrayFailure())
+                return true
+            }
+            TypeKind.DECLARED -> {
+                return visitType(
+                    parentChain,
+                    seenTypesByPolicy,
+                    method,
+                    method.returnType,
+                    parentPolicyExceptions
+                )
+            }
+            TypeKind.ERROR,
+            TypeKind.TYPEVAR,
+            TypeKind.WILDCARD,
+            TypeKind.PACKAGE,
+            TypeKind.EXECUTABLE,
+            TypeKind.OTHER,
+            TypeKind.UNION,
+            TypeKind.INTERSECTION,
+                // Java 9+
+                // TypeKind.MODULE,
+            null -> {
+                printError(
+                    parentChain, method,
+                    MessageUtils.genericTypeKindFailure(typeName = typeName)
+                )
+                return true
+            }
+            else -> {
+                printError(
+                    parentChain, method,
+                    MessageUtils.genericTypeKindFailure(typeName = typeName)
+                )
+                return true
+            }
+        }
+
+        return false
+    }
+
+    /**
+     * @return true if any error was encountered at this level or any child level
+     */
+    private fun visitType(
+        parentChain: List<String>,
+        seenTypesByPolicy: MutableMap<Set<Immutable.Policy.Exception>, Set<Type>>,
+        symbol: Symbol,
+        type: Type,
+        parentPolicyExceptions: Set<Immutable.Policy.Exception>,
+        nonInterfaceClassFailure: () -> String = { MessageUtils.nonInterfaceReturnFailure() },
+    ): Boolean {
+        if (type.isPrimitive) return false
+        if (type.isPrimitiveOrVoid) {
+            printError(parentChain, symbol, MessageUtils.voidReturnFailure())
+            return true
+        }
+
+        if (ignoredTypes.any { processingEnv.typeUtils.isAssignable(type, it) }) {
+            return false
+        }
+
+        val policyAnnotation = symbol.getAnnotation(Immutable.Policy::class.java)
+        val newPolicyExceptions = parentPolicyExceptions + policyAnnotation?.exceptions.orEmpty()
+
+        // Collection (and Map) types are ignored for the interface check as they have immutability
+        // enforced through a runtime exception which must be verified in a separate runtime test
+        val isMap = processingEnv.typeUtils.isAssignable(type, mapType)
+        if (!processingEnv.typeUtils.isAssignable(type, collectionType) && !isMap) {
+            if (!type.isInterface && !newPolicyExceptions
+                    .contains(Immutable.Policy.Exception.FINAL_CLASSES_WITH_FINAL_FIELDS)
+            ) {
+                printError(parentChain, symbol, nonInterfaceClassFailure())
+                return true
+            } else {
+                return visitClass(
+                    parentChain, seenTypesByPolicy, symbol,
+                    processingEnv.typeUtils.asElement(type) as Symbol.TypeSymbol,
+                    newPolicyExceptions,
+                )
+            }
+        }
+
+        var anyError = false
+
+        type.typeArguments.forEachIndexed { index, typeArg ->
+            val argError =
+                visitType(parentChain, seenTypesByPolicy, symbol, typeArg, newPolicyExceptions) {
+                    MessageUtils.nonInterfaceReturnFailure(
+                        prefix = when {
+                            !isMap -> ""
+                            index == 0 -> "Key " + typeArg.asElement().simpleName
+                            else -> "Value " + typeArg.asElement().simpleName
+                        }, index = index
+                    )
+                }
+            anyError = anyError || argError
+        }
+
+        return anyError
+    }
+
+    private fun printError(
+        parentChain: List<String>,
+        element: Element,
+        message: String,
+    ) = processingEnv.messager.printMessage(
+        Diagnostic.Kind.ERROR,
+        // Drop one from the parent chain so that the directly enclosing class isn't logged.
+        // It exists in the list at this point in the traversal so that further children can
+        // include the right reference.
+        parentChain.dropLast(1).joinToString() + "\n\t" + message,
+        element,
+    )
+
+    private fun ProcessingEnvironment.erasedType(typeName: String) =
+        elementUtils.getTypeElement(typeName)?.asType()?.let(typeUtils::erasure)
+
+    private fun isIgnored(symbol: Symbol) =
+        symbol.getAnnotation(Immutable.Ignore::class.java) != null
+}
\ No newline at end of file
diff --git a/tools/processors/immutability/src/android/processor/immutability/Immutable.java b/tools/processors/immutability/src/android/processor/immutability/Immutable.java
new file mode 100644
index 0000000..ba822ba
--- /dev/null
+++ b/tools/processors/immutability/src/android/processor/immutability/Immutable.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.processor.immutability;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Marks a class as immutable. When used with the Immutability processor, verifies at compile that
+ * the class is truly immutable. Immutable is defined as:
+ * <ul>
+ *     <li>Only exposes methods and/or static final constants</li>
+ *     <li>Every exposed type is an @Immutable interface or otherwise immutable class</li>
+ *     <ul>
+ *         <li>Implicitly immutable types like {@link String} are ignored</li>
+ *         <li>{@link Collection} and {@link Map} and their subclasses where immutability is
+ *         enforced at runtime are ignored</li>
+ *     </ul>
+ *     <li>Every method must return a type (no void methods allowed)</li>
+ *     <li>All inner classes must be @Immutable interfaces</li>
+ * </ul>
+ */
+public @interface Immutable {
+
+    /**
+     * Marks a specific class, field, or method as ignored for immutability validation.
+     */
+    @Retention(RetentionPolicy.CLASS) // Not SOURCE as that isn't retained for some reason
+    @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
+    @interface Ignore {
+        String reason() default "";
+    }
+
+    /**
+     * Marks an element and its reachable children with a specific policy.
+     */
+    @Retention(RetentionPolicy.CLASS)
+    @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
+    @interface Policy {
+        Exception[] exceptions() default {};
+
+        enum Exception {
+            /**
+             * Allow final classes with only final fields. By default these are not allowed because
+             * direct field access disallows hard removal of APIs (by having their getters return
+             * mocks/stubs) and also prevents field compaction, which can occur with booleans
+             * stuffed into a number as flags.
+             *
+             * This exception is allowed though because several framework classes are built around
+             * the final field access model and it would be unnecessarily difficult to migrate or
+             * wrap each type.
+             */
+            FINAL_CLASSES_WITH_FINAL_FIELDS,
+        }
+    }
+}
diff --git a/tools/processors/immutability/src/android/processor/immutability/MessageUtils.kt b/tools/processors/immutability/src/android/processor/immutability/MessageUtils.kt
new file mode 100644
index 0000000..7fa2fb5
--- /dev/null
+++ b/tools/processors/immutability/src/android/processor/immutability/MessageUtils.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.processor.immutability
+
+object MessageUtils {
+
+    fun classNotImmutableFailure(className: String) = "$className should be marked @Immutable"
+
+    fun classNotFinalFailure(className: String) = "$className should be marked final"
+
+    fun memberNotMethodFailure() = "Member must be a method"
+
+    fun nonInterfaceClassFailure() = "Class was not an interface"
+
+    fun nonInterfaceReturnFailure(prefix: String, index: Int = -1) =
+        if (prefix.isEmpty()) {
+            "Type at index $index was not an interface"
+        } else {
+            "$prefix was not an interface"
+        }
+
+    fun genericTypeKindFailure(typeName: CharSequence) = "TypeKind $typeName unsupported"
+
+    fun arrayFailure() = "Array types are not supported as they can be mutated by callers"
+
+    fun nonInterfaceReturnFailure() = "Must return an interface"
+
+    fun voidReturnFailure() = "Cannot return void"
+
+    fun staticNonFinalFailure() = "Static member must be final"
+}
\ No newline at end of file
diff --git a/tools/processors/immutability/test/android/processor/ImmutabilityProcessorTest.kt b/tools/processors/immutability/test/android/processor/ImmutabilityProcessorTest.kt
new file mode 100644
index 0000000..f26357f
--- /dev/null
+++ b/tools/processors/immutability/test/android/processor/ImmutabilityProcessorTest.kt
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.processor
+
+import android.processor.immutability.IMMUTABLE_ANNOTATION_NAME
+import android.processor.immutability.ImmutabilityProcessor
+import android.processor.immutability.MessageUtils
+import com.google.common.truth.Expect
+import com.google.testing.compile.CompilationSubject.assertThat
+import com.google.testing.compile.Compiler.javac
+import com.google.testing.compile.JavaFileObjects
+import org.junit.Rule
+import org.junit.Test
+import java.util.*
+import javax.tools.JavaFileObject
+
+class ImmutabilityProcessorTest {
+
+    companion object {
+        private const val PACKAGE_PREFIX = "android.processor.immutability"
+        private const val DATA_CLASS_NAME = "DataClass"
+        private val ANNOTATION = JavaFileObjects.forResource("Immutable.java")
+
+        private val FINAL_CLASSES = listOf(
+            JavaFileObjects.forSourceString(
+                "$PACKAGE_PREFIX.NonFinalClassFinalFields",
+                /* language=JAVA */ """
+                    package $PACKAGE_PREFIX;
+
+                    public class NonFinalClassFinalFields {
+                        private final String finalField;
+                        public NonFinalClassFinalFields(String value) {
+                            this.finalField = value;
+                        }
+                    }
+                """.trimIndent()
+            ),
+            JavaFileObjects.forSourceString(
+                "$PACKAGE_PREFIX.NonFinalClassNonFinalFields",
+                /* language=JAVA */ """
+                    package $PACKAGE_PREFIX;
+
+                    public class NonFinalClassNonFinalFields {
+                        private String nonFinalField;
+                    }
+                """.trimIndent()
+            ),
+            JavaFileObjects.forSourceString(
+                "$PACKAGE_PREFIX.FinalClassFinalFields",
+                /* language=JAVA */ """
+                    package $PACKAGE_PREFIX;
+
+                    public final class FinalClassFinalFields {
+                        private final String finalField;
+                        public FinalClassFinalFields(String value) {
+                            this.finalField = value;
+                        }
+                    }
+                """.trimIndent()
+            ),
+            JavaFileObjects.forSourceString(
+                "$PACKAGE_PREFIX.FinalClassNonFinalFields",
+                /* language=JAVA */ """
+                    package $PACKAGE_PREFIX;
+
+                    public final class FinalClassNonFinalFields {
+                        private String nonFinalField;
+                    }
+                """.trimIndent()
+            )
+        )
+    }
+
+    @get:Rule
+    val expect = Expect.create()
+
+    @Test
+    fun validInterface() = test(
+        JavaFileObjects.forSourceString(
+            "$PACKAGE_PREFIX.$DATA_CLASS_NAME",
+            /* language=JAVA */ """
+                package $PACKAGE_PREFIX;
+
+                import $IMMUTABLE_ANNOTATION_NAME;
+                import java.util.ArrayList;
+                import java.util.Collections;
+                import java.util.List;
+
+                @Immutable
+                public interface $DATA_CLASS_NAME {
+                    InnerInterface DEFAULT = new InnerInterface() {
+                        @Override
+                        public String getValue() {
+                            return "";
+                        }
+                        @Override
+                        public List<String> getArray() {
+                            return Collections.emptyList();
+                        }
+                    };
+
+                    String getValue();
+                    ArrayList<String> getArray();
+                    InnerInterface getInnerInterface();
+
+                    @Immutable
+                    interface InnerInterface {
+                        String getValue();
+                        List<String> getArray();
+                    }
+                }
+                """.trimIndent()
+        ), errors = emptyList()
+    )
+
+    @Test
+    fun abstractClass() = test(
+        JavaFileObjects.forSourceString(
+            "$PACKAGE_PREFIX.$DATA_CLASS_NAME",
+            /* language=JAVA */ """
+                package $PACKAGE_PREFIX;
+
+                import $IMMUTABLE_ANNOTATION_NAME;
+                import java.util.Map;
+
+                @Immutable
+                public abstract class $DATA_CLASS_NAME {
+                    public static final String IMMUTABLE = "";
+                    public static final InnerClass NOT_IMMUTABLE = null;
+                    public static InnerClass NOT_FINAL = null;
+
+                    // Field finality doesn't matter, methods are always enforced so that future
+                    // field compaction or deprecation is possible
+                    private final String fieldFinal = "";
+                    private String fieldNonFinal;
+                    public abstract void sideEffect();
+                    public abstract String[] getArray();
+                    public abstract InnerClass getInnerClassOne();
+                    public abstract InnerClass getInnerClassTwo();
+                    @Immutable.Ignore
+                    public abstract InnerClass getIgnored();
+                    public abstract InnerInterface getInnerInterface();
+
+                    public abstract Map<String, String> getValidMap();
+                    public abstract Map<InnerClass, InnerClass> getInvalidMap();
+
+                    public static final class InnerClass {
+                        public String innerField;
+                        public String[] getArray() { return null; }
+                    }
+
+                    public interface InnerInterface {
+                        String[] getArray();
+                        InnerClass getInnerClass();
+                    }
+                }
+                """.trimIndent()
+        ), errors = listOf(
+            nonInterfaceClassFailure(line = 7),
+            nonInterfaceReturnFailure(line = 9),
+            staticNonFinalFailure(line = 10),
+            nonInterfaceReturnFailure(line = 10),
+            memberNotMethodFailure(line = 14),
+            memberNotMethodFailure(line = 15),
+            voidReturnFailure(line = 16),
+            arrayFailure(line = 17),
+            nonInterfaceReturnFailure(line = 18),
+            nonInterfaceReturnFailure(line = 19),
+            classNotImmutableFailure(line = 22, className = "InnerInterface"),
+            nonInterfaceReturnFailure(line = 25, prefix = "Key InnerClass"),
+            nonInterfaceReturnFailure(line = 25, prefix = "Value InnerClass"),
+            classNotImmutableFailure(line = 27, className = "InnerClass"),
+            nonInterfaceClassFailure(line = 27),
+            memberNotMethodFailure(line = 28),
+            arrayFailure(line = 29),
+            arrayFailure(line = 33),
+            nonInterfaceReturnFailure(line = 34),
+        )
+    )
+
+    @Test
+    fun finalClasses() = test(
+        JavaFileObjects.forSourceString(
+            "$PACKAGE_PREFIX.$DATA_CLASS_NAME",
+            /* language=JAVA */ """
+            package $PACKAGE_PREFIX;
+
+            import java.util.List;
+
+            @Immutable
+            public interface $DATA_CLASS_NAME {
+                NonFinalClassFinalFields getNonFinalFinal();
+                List<NonFinalClassNonFinalFields> getNonFinalNonFinal();
+                FinalClassFinalFields getFinalFinal();
+                List<FinalClassNonFinalFields> getFinalNonFinal();
+
+                @Immutable.Policy(exceptions = {Immutable.Policy.Exception.FINAL_CLASSES_WITH_FINAL_FIELDS})
+                NonFinalClassFinalFields getPolicyNonFinalFinal();
+
+                @Immutable.Policy(exceptions = {Immutable.Policy.Exception.FINAL_CLASSES_WITH_FINAL_FIELDS})
+                List<NonFinalClassNonFinalFields> getPolicyNonFinalNonFinal();
+
+                @Immutable.Policy(exceptions = {Immutable.Policy.Exception.FINAL_CLASSES_WITH_FINAL_FIELDS})
+                FinalClassFinalFields getPolicyFinalFinal();
+
+                @Immutable.Policy(exceptions = {Immutable.Policy.Exception.FINAL_CLASSES_WITH_FINAL_FIELDS})
+                List<FinalClassNonFinalFields> getPolicyFinalNonFinal();
+            }
+            """.trimIndent()
+        ), errors = listOf(
+            nonInterfaceReturnFailure(line = 7),
+            nonInterfaceReturnFailure(line = 8, index = 0),
+            nonInterfaceReturnFailure(line = 9),
+            nonInterfaceReturnFailure(line = 10, index = 0),
+            classNotFinalFailure(line = 13, "NonFinalClassFinalFields"),
+        ), otherErrors = listOf(
+            memberNotMethodFailure(line = 4) to FINAL_CLASSES[1],
+            memberNotMethodFailure(line = 4) to FINAL_CLASSES[3],
+        )
+    )
+
+    private fun test(
+        source: JavaFileObject,
+        errors: List<CompilationError>,
+        otherErrors: List<Pair<CompilationError, JavaFileObject>> = emptyList(),
+    ) {
+        val compilation = javac()
+            .withProcessors(ImmutabilityProcessor())
+            .compile(FINAL_CLASSES + ANNOTATION + listOf(source))
+        val allErrors = otherErrors + errors.map { it to source }
+        allErrors.forEach { (error, file) ->
+            try {
+                assertThat(compilation)
+                    .hadErrorContaining(error.message)
+                    .inFile(file)
+                    .onLine(error.line)
+            } catch (e: AssertionError) {
+                // Wrap the exception so that the line number is logged
+                val wrapped = AssertionError("Expected $error, ${e.message}").apply {
+                    stackTrace = e.stackTrace
+                }
+
+                // Wrap again with Expect so that all errors are reported. This is very bad code
+                // but can only be fixed by updating compile-testing with a better Truth Subject
+                // implementation.
+                expect.that(wrapped).isNull()
+            }
+        }
+
+        try {
+            assertThat(compilation).hadErrorCount(allErrors.size)
+        } catch (e: AssertionError) {
+            expect.withMessage(
+                compilation.errors()
+                    .joinToString(separator = "\n") {
+                        "${it.lineNumber}: ${it.getMessage(Locale.ENGLISH)?.trim()}"
+                    }
+            ).that(e).isNull()
+        }
+    }
+
+    private fun classNotImmutableFailure(line: Long, className: String) =
+        CompilationError(line = line, message = MessageUtils.classNotImmutableFailure(className))
+
+    private fun nonInterfaceClassFailure(line: Long) =
+        CompilationError(line = line, message = MessageUtils.nonInterfaceClassFailure())
+
+    private fun nonInterfaceReturnFailure(line: Long) =
+        CompilationError(line = line, message = MessageUtils.nonInterfaceReturnFailure())
+
+    private fun nonInterfaceReturnFailure(line: Long, prefix: String = "", index: Int = -1) =
+        CompilationError(
+            line = line,
+            message = MessageUtils.nonInterfaceReturnFailure(prefix = prefix, index = index)
+        )
+
+    private fun memberNotMethodFailure(line: Long) =
+        CompilationError(line = line, message = MessageUtils.memberNotMethodFailure())
+
+    private fun voidReturnFailure(line: Long) =
+        CompilationError(line = line, message = MessageUtils.voidReturnFailure())
+
+    private fun staticNonFinalFailure(line: Long) =
+        CompilationError(line = line, message = MessageUtils.staticNonFinalFailure())
+
+    private fun arrayFailure(line: Long) =
+        CompilationError(line = line, message = MessageUtils.arrayFailure())
+
+    private fun classNotFinalFailure(line: Long, className: String) =
+        CompilationError(line = line, message = MessageUtils.classNotFinalFailure(className))
+
+    data class CompilationError(
+        val line: Long,
+        val message: String,
+    )
+}
\ No newline at end of file