Merge "Introduce more RenderEffect APIs"
diff --git a/Android.bp b/Android.bp
index 6b55cc9..bc39882 100644
--- a/Android.bp
+++ b/Android.bp
@@ -485,7 +485,6 @@
     name: "framework-internal-utils",
     static_libs: [
         "apex_aidl_interface-java",
-        "suspend_control_aidl_interface-java",
         "framework-protos",
         "updatable-driver-protos",
         "android.hidl.base-V1.0-java",
@@ -520,6 +519,8 @@
         "android.hardware.vibrator-V1.1-java",
         "android.hardware.vibrator-V1.2-java",
         "android.hardware.vibrator-V1.3-java",
+        "android.system.keystore2-java",
+        "android.system.suspend.control.internal-java",
         "devicepolicyprotosnano",
 
         "com.android.sysprop.apex",
@@ -580,6 +581,7 @@
     aidl: {
         generate_get_transaction_name: true,
         local_include_dirs: ["media/aidl"],
+        include_dirs: ["frameworks/av/aidl"],
     },
     dxflags: [
         "--core-library",
@@ -596,6 +598,7 @@
         "framework-platform-compat-config",
         // TODO: remove gps_debug and protolog.conf.json when the build system propagates "required" properly.
         "gps_debug.conf",
+        "icu4j-platform-compat-config",
         "libcore-platform-compat-config",
         "protolog.conf.json.gz",
         "services-platform-compat-config",
@@ -614,6 +617,7 @@
         // If MimeMap ever becomes its own APEX, then this dependency would need to be removed
         // in favor of an API stubs dependency in java_library "framework" below.
         "mimemap",
+        "av-types-aidl-java",
         "mediatranscoding_aidl_interface-java",
         "soundtrigger_middleware-aidl-java",
     ],
@@ -782,6 +786,7 @@
         "core/java/android/annotation/RequiresPermission.java",
         "core/java/android/annotation/SdkConstant.java",
         "core/java/android/annotation/StringDef.java",
+        "core/java/android/annotation/SuppressLint.java",
         "core/java/android/annotation/SystemApi.java",
         "core/java/android/annotation/SystemService.java",
         "core/java/android/annotation/TestApi.java",
diff --git a/ApiDocs.bp b/ApiDocs.bp
index faa0e5d..7ed7ec5 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -86,6 +86,7 @@
     // TODO(b/169090544): remove below aidl includes.
     aidl: {
         local_include_dirs: ["media/aidl"],
+        include_dirs: ["frameworks/av/aidl"],
     },
 }
 
@@ -157,6 +158,7 @@
     // TODO(b/169090544): remove below aidl includes.
     aidl: {
         local_include_dirs: ["media/aidl"],
+        include_dirs: ["frameworks/av/aidl"],
     },
 }
 
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 8090bec..8fca23f 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -57,6 +57,7 @@
             "telephony/java",
             "media/aidl",
         ],
+        include_dirs: ["frameworks/av/aidl"],
     },
     // These are libs from framework-internal-utils that are required (i.e. being referenced)
     // from framework-non-updatable-sources. Add more here when there's a need.
@@ -229,7 +230,7 @@
 }
 
 droidstubs {
-    name: "test-api-stubs-docs",
+    name: "test-api-stubs-docs-non-updatable",
     defaults: ["metalava-non-updatable-api-stubs-default"],
     arg_files: [
         "core/res/AndroidManifest.xml",
@@ -241,12 +242,12 @@
         + "\\)",
     check_api: {
         current: {
-            api_file: "api/test-current.txt",
-            removed_api_file: "api/test-removed.txt",
+            api_file: "core/api/test-current.txt",
+            removed_api_file: "core/api/test-removed.txt",
         },
         api_lint: {
             enabled: true,
-            baseline_file: "api/test-lint-baseline.txt",
+            baseline_file: "core/api/test-lint-baseline.txt",
         },
     },
     dist: {
@@ -316,14 +317,7 @@
 }
 
 java_library_static {
-    name: "android_monolith_stubs_current",
-    srcs: [ ":api-stubs-docs" ],
-    static_libs: [ "private-stub-annotations-jar" ],
-    defaults: ["android_defaults_stubs_current"],
-}
-
-java_library_static {
-    name: "android_merged_stubs_current",
+    name: "android_stubs_current",
     srcs: [ ":api-stubs-docs-non-updatable" ],
     static_libs: [
         "conscrypt.module.public.api.stubs",
@@ -338,19 +332,6 @@
         "framework-wifi.stubs",
         "private-stub-annotations-jar",
     ],
-    defaults: ["android_defaults_stubs_current"],
-}
-
-java_library_static {
-    name: "android_stubs_current",
-    static_libs: ["android_merged_stubs_current"],
-    defaults: ["android_defaults_stubs_current"],
-}
-
-java_library_static {
-    name: "android_system_monolith_stubs_current",
-    srcs: [ ":system-api-stubs-docs" ],
-    static_libs: [ "private-stub-annotations-jar" ],
     defaults: [
         "android_defaults_stubs_current",
         "android_stubs_dists_default",
@@ -369,7 +350,7 @@
 }
 
 java_library_static {
-    name: "android_system_merged_stubs_current",
+    name: "android_system_stubs_current",
     srcs: [ ":system-api-stubs-docs-non-updatable" ],
     static_libs: [
         "conscrypt.module.public.api.stubs",
@@ -388,14 +369,8 @@
 }
 
 java_library_static {
-    name: "android_system_stubs_current",
-    static_libs: ["android_system_merged_stubs_current"],
-    defaults: ["android_defaults_stubs_current"],
-}
-
-java_library_static {
     name: "android_test_stubs_current",
-    srcs: [ ":test-api-stubs-docs" ],
+    srcs: [ ":test-api-stubs-docs-non-updatable" ],
     static_libs: [
         // Modules do not have test APIs, but we want to include their SystemApis, like we include
         // the SystemApi of framework-non-updatable-sources.
diff --git a/apct-tests/perftests/core/src/android/os/ParcelStringPerfTest.java b/apct-tests/perftests/core/src/android/os/ParcelStringPerfTest.java
new file mode 100644
index 0000000..2b861cb
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/ParcelStringPerfTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package android.os;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.filters.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@LargeTest
+@RunWith(Parameterized.class)
+public class ParcelStringPerfTest {
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameterized.Parameter(0)
+    public String mName;
+    @Parameterized.Parameter(1)
+    public String mValue;
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Collection<Object[]> getParameters() {
+        return Arrays.asList(new Object[][] {
+                { "simple", "com.example.typical_package_name" },
+                { "complex", "從不喜歡孤單一個 - 蘇永康/吳雨霏" },
+        });
+    }
+
+    @Test
+    public void timeWriteString8() {
+        final Parcel parcel = Parcel.obtain();
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            parcel.setDataPosition(0);
+            parcel.writeString8(mValue);
+        }
+    }
+
+    @Test
+    public void timeWriteString16() {
+        final Parcel parcel = Parcel.obtain();
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            parcel.setDataPosition(0);
+            parcel.writeString16(mValue);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/text/VariableFontPerfTest.java b/apct-tests/perftests/core/src/android/text/VariableFontPerfTest.java
new file mode 100644
index 0000000..fbe67a4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/text/VariableFontPerfTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+package android.text;
+
+import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class VariableFontPerfTest {
+    private static final int WORD_LENGTH = 9;  // Random word has 9 characters.
+    private static final boolean NO_STYLE_TEXT = false;
+
+    private static final TextPaint PAINT = new TextPaint();
+
+    public VariableFontPerfTest() {}
+
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private final TextPerfUtils mTextUtil = new TextPerfUtils();
+
+    @Before
+    public void setUp() {
+        mTextUtil.resetRandom(0 /* seed */);
+    }
+
+    @Test
+    public void testDraw_SetVariationOnce() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+        final Paint paint = new Paint(PAINT);
+        paint.setFontVariationSettings("'wght' 700");
+        final RenderNode node = RenderNode.create("benchmark", null);
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final RecordingCanvas c = node.beginRecording(1200, 200);
+            state.resumeTiming();
+
+            c.drawText(text, 0, text.length(), 0, 100, paint);
+
+            state.pauseTiming();
+            node.endRecording();
+            state.resumeTiming();
+
+        }
+    }
+
+    @Test
+    public void testDraw_SetVariationEachDraw() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+        final Paint paint = new Paint(PAINT);
+        final RenderNode node = RenderNode.create("benchmark", null);
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final RecordingCanvas c = node.beginRecording(1200, 200);
+            paint.setFontVariationSettings("'wght' 700");
+            state.resumeTiming();
+
+            c.drawText(text, 0, text.length(), 0, 100, paint);
+
+            state.pauseTiming();
+            node.endRecording();
+            state.resumeTiming();
+
+        }
+    }
+
+    @Test
+    public void testDraw_SetDifferentVariationEachDraw() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
+        final Paint paint = new Paint(PAINT);
+        final RenderNode node = RenderNode.create("benchmark", null);
+        final Random random = new Random(0);
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            final RecordingCanvas c = node.beginRecording(1200, 200);
+            int weight = random.nextInt(1000);
+            paint.setFontVariationSettings("'wght' " + weight);
+            state.resumeTiming();
+
+            c.drawText(text, 0, text.length(), 0, 100, paint);
+
+            state.pauseTiming();
+            node.endRecording();
+            state.resumeTiming();
+        }
+    }
+
+    @Test
+    public void testSetFontVariationSettings() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final Paint paint = new Paint(PAINT);
+        final Random random = new Random(0);
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            int weight = random.nextInt(1000);
+            state.resumeTiming();
+
+            paint.setFontVariationSettings("'wght' " + weight);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/widget/EditTextLongTextPerfTest.java b/apct-tests/perftests/core/src/android/widget/EditTextLongTextPerfTest.java
index f4ad5dd..c48fa4f 100644
--- a/apct-tests/perftests/core/src/android/widget/EditTextLongTextPerfTest.java
+++ b/apct-tests/perftests/core/src/android/widget/EditTextLongTextPerfTest.java
@@ -43,8 +43,8 @@
     @Parameters(name = "{0}")
     public static Collection cases() {
         return Arrays.asList(new Object[][] {
-            { "10x30K", 10, 30000 },
-            { "300x1K", 300, 1000 },
+            { "10x3K", 10, 3000 },
+            { "30x1K", 30, 1000 },
         });
     }
 
diff --git a/apex/Android.bp b/apex/Android.bp
index c5b4901..0a535a8 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -112,6 +112,8 @@
     ],
     stubs_source_visibility: ["//visibility:private"],
 
+    defaults_visibility: ["//visibility:private"],
+
     // Collates API usages from each module for further analysis.
     plugins: ["java_api_finder"],
 
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 c8a04d6..ba2a8a3 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -268,6 +268,7 @@
      */
     Bundle mIdleOptions;
 
+    // TODO(b/172085676): Move inside alarm store.
     private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
             new SparseArray<>();
     private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray =
@@ -276,6 +277,9 @@
             new SparseBooleanArray();
     private boolean mNextAlarmClockMayChange;
 
+    @GuardedBy("mLock")
+    private final Runnable mAlarmClockUpdater = () -> mNextAlarmClockMayChange = true;
+
     // May only use on mHandler's thread, locking not required.
     private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray =
             new SparseArray<>();
@@ -410,6 +414,9 @@
         private static final String KEY_APP_STANDBY_RESTRICTED_WINDOW =
                 "app_standby_restricted_window";
 
+        @VisibleForTesting
+        static final String KEY_LAZY_BATCHING = "lazy_batching";
+
         private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
         private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
         private static final long DEFAULT_MAX_INTERVAL = 365 * DateUtils.DAY_IN_MILLIS;
@@ -432,6 +439,8 @@
         private static final int DEFAULT_APP_STANDBY_RESTRICTED_QUOTA = 1;
         private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = MILLIS_IN_DAY;
 
+        private static final boolean DEFAULT_LAZY_BATCHING = false;
+
         // Minimum futurity of a new alarm
         public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
 
@@ -460,6 +469,8 @@
         public int APP_STANDBY_RESTRICTED_QUOTA = DEFAULT_APP_STANDBY_RESTRICTED_QUOTA;
         public long APP_STANDBY_RESTRICTED_WINDOW = DEFAULT_APP_STANDBY_RESTRICTED_WINDOW;
 
+        public boolean LAZY_BATCHING = DEFAULT_LAZY_BATCHING;
+
         private long mLastAllowWhileIdleWhitelistDuration = -1;
 
         Constants() {
@@ -538,6 +549,14 @@
                         case KEY_APP_STANDBY_RESTRICTED_WINDOW:
                             updateStandbyWindowsLocked();
                             break;
+                        case KEY_LAZY_BATCHING:
+                            final boolean oldLazyBatching = LAZY_BATCHING;
+                            LAZY_BATCHING = properties.getBoolean(
+                                    KEY_LAZY_BATCHING, DEFAULT_LAZY_BATCHING);
+                            if (oldLazyBatching != LAZY_BATCHING) {
+                                migrateAlarmsToNewStoreLocked();
+                            }
+                            break;
                         default:
                             if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
                                 // The quotas need to be updated in order, so we can't just rely
@@ -551,6 +570,15 @@
             }
         }
 
+        private void migrateAlarmsToNewStoreLocked() {
+            final AlarmStore newStore = LAZY_BATCHING ? new LazyAlarmStore()
+                    : new BatchingAlarmStore();
+            final ArrayList<Alarm> allAlarms = mAlarmStore.remove((unused) -> true);
+            newStore.addAll(allAlarms);
+            mAlarmStore = newStore;
+            mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
+        }
+
         private void updateStandbyQuotasLocked() {
             // The bucket quotas need to be read as an atomic unit but the properties passed to
             // onPropertiesChanged may only have one key populated at a time.
@@ -659,6 +687,9 @@
             TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_WINDOW, pw);
             pw.println();
 
+            pw.print(KEY_LAZY_BATCHING, LAZY_BATCHING);
+            pw.println();
+
             pw.decreaseIndent();
         }
 
@@ -770,7 +801,7 @@
     // minimum recurrence period or alarm futurity for us to be able to fuzz it
     static final long MIN_FUZZABLE_INTERVAL = 10000;
     @GuardedBy("mLock")
-    final AlarmStore mAlarmStore;
+    AlarmStore mAlarmStore;
 
     // set to non-null if in idle mode; while in this mode, any alarms we don't want
     // to run during this time are rescehduled to go off after this alarm.
@@ -781,7 +812,6 @@
     AlarmManagerService(Context context, Injector injector) {
         super(context);
         mInjector = injector;
-        mAlarmStore = new BatchingAlarmStore(() -> mNextAlarmClockMayChange = true);
     }
 
     public AlarmManagerService(Context context) {
@@ -1219,6 +1249,11 @@
         synchronized (mLock) {
             mHandler = new AlarmHandler();
             mConstants = new Constants();
+
+            mAlarmStore = mConstants.LAZY_BATCHING ? new LazyAlarmStore()
+                    : new BatchingAlarmStore();
+            mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
+
             mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
 
             mNextWakeup = mNextNonWakeup = 0;
@@ -3055,12 +3090,13 @@
 
     static final void dumpAlarmList(IndentingPrintWriter ipw, ArrayList<Alarm> list,
             long nowELAPSED, SimpleDateFormat sdf) {
-        for (int i = list.size() - 1; i >= 0; i--) {
+        final int n = list.size();
+        for (int i = n - 1; i >= 0; i--) {
             final Alarm a = list.get(i);
             final String label = Alarm.typeToString(a.type);
             ipw.print(label);
             ipw.print(" #");
-            ipw.print(i);
+            ipw.print(n - i);
             ipw.print(": ");
             ipw.println(a);
             ipw.increaseIndent();
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java
index 7a846b9..0e442d0 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmStore.java
@@ -40,6 +40,13 @@
     void add(Alarm a);
 
     /**
+     * Adds all the given alarms to this store.
+     *
+     * @param alarms The alarms to add.
+     */
+    void addAll(ArrayList<Alarm> alarms);
+
+    /**
      * Removes alarms that pass the given predicate.
      *
      * @param whichAlarms The predicate describing the alarms to remove.
@@ -48,11 +55,17 @@
     ArrayList<Alarm> remove(Predicate<Alarm> whichAlarms);
 
     /**
+     * Set a listener to be invoked whenever an alarm clock is removed by a call to
+     * {@link #remove(Predicate) remove} from this store.
+     */
+    void setAlarmClockRemovalListener(Runnable listener);
+
+    /**
      * Gets the earliest alarm with the flag {@link android.app.AlarmManager#FLAG_WAKE_FROM_IDLE}
      * based on {@link Alarm#getWhenElapsed()}.
      *
      * @return An alarm object matching the description above or {@code null} if no such alarm was
-     *         found.
+     * found.
      */
     Alarm getNextWakeFromIdleAlarm();
 
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
index cbfe80b..e7edfb7 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
@@ -41,45 +41,22 @@
  */
 public class BatchingAlarmStore implements AlarmStore {
 
-    private ArrayList<Batch> mAlarmBatches = new ArrayList<>();
+    private final ArrayList<Batch> mAlarmBatches = new ArrayList<>();
     private int mSize;
-    private AlarmClockRemovalListener mAlarmClockRemovalListener;
+    private Runnable mOnAlarmClockRemoved;
 
     interface Stats {
         int REBATCH_ALL_ALARMS = 0;
     }
 
-    final StatLogger mStatLogger = new StatLogger("Alarm store stats", new String[]{
+    final StatLogger mStatLogger = new StatLogger("BatchingAlarmStore stats", new String[]{
             "REBATCH_ALL_ALARMS",
     });
 
-    private static final Comparator<Batch> sBatchOrder = (b1, b2) -> {
-        long when1 = b1.mStart;
-        long when2 = b2.mStart;
-        if (when1 > when2) {
-            return 1;
-        }
-        if (when1 < when2) {
-            return -1;
-        }
-        return 0;
-    };
+    private static final Comparator<Batch> sBatchOrder = Comparator.comparingLong(b -> b.mStart);
 
-    private static final Comparator<Alarm> sIncreasingTimeOrder = (a1, a2) -> {
-        long when1 = a1.getWhenElapsed();
-        long when2 = a2.getWhenElapsed();
-        if (when1 > when2) {
-            return 1;
-        }
-        if (when1 < when2) {
-            return -1;
-        }
-        return 0;
-    };
-
-    BatchingAlarmStore(AlarmClockRemovalListener listener) {
-        mAlarmClockRemovalListener = listener;
-    }
+    private static final Comparator<Alarm> sIncreasingTimeOrder = Comparator.comparingLong(
+            Alarm::getWhenElapsed);
 
     @Override
     public void add(Alarm a) {
@@ -88,6 +65,16 @@
     }
 
     @Override
+    public void addAll(ArrayList<Alarm> alarms) {
+        if (alarms == null) {
+            return;
+        }
+        for (final Alarm a : alarms) {
+            add(a);
+        }
+    }
+
+    @Override
     public ArrayList<Alarm> remove(Predicate<Alarm> whichAlarms) {
         final ArrayList<Alarm> removed = new ArrayList<>();
         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
@@ -106,6 +93,11 @@
     }
 
     @Override
+    public void setAlarmClockRemovalListener(Runnable listener) {
+        mOnAlarmClockRemoved = listener;
+    }
+
+    @Override
     public Alarm getNextWakeFromIdleAlarm() {
         for (final Batch batch : mAlarmBatches) {
             if ((batch.mFlags & AlarmManager.FLAG_WAKE_FROM_IDLE) == 0) {
@@ -317,8 +309,8 @@
                 Alarm alarm = mAlarms.get(i);
                 if (predicate.test(alarm)) {
                     removed.add(mAlarms.remove(i));
-                    if (alarm.alarmClock != null && mAlarmClockRemovalListener != null) {
-                        mAlarmClockRemovalListener.onRemoved();
+                    if (alarm.alarmClock != null && mOnAlarmClockRemoved != null) {
+                        mOnAlarmClockRemoved.run();
                     }
                     if (isTimeTickAlarm(alarm)) {
                         // This code path is not invoked when delivering alarms, only when removing
@@ -388,9 +380,4 @@
             proto.end(token);
         }
     }
-
-    @FunctionalInterface
-    interface AlarmClockRemovalListener {
-        void onRemoved();
-    }
 }
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java
new file mode 100644
index 0000000..8ca1446
--- /dev/null
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+
+package com.android.server.alarm;
+
+import static com.android.server.alarm.AlarmManagerService.TAG;
+import static com.android.server.alarm.AlarmManagerService.dumpAlarmList;
+import static com.android.server.alarm.AlarmManagerService.isTimeTickAlarm;
+
+import android.app.AlarmManager;
+import android.util.IndentingPrintWriter;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.util.StatLogger;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.function.Predicate;
+
+/**
+ * Lazy implementation of an alarm store.
+ * This keeps the alarms in a sorted list, and only batches them at the time of delivery.
+ */
+public class LazyAlarmStore implements AlarmStore {
+
+    private final ArrayList<Alarm> mAlarms = new ArrayList<>();
+    private Runnable mOnAlarmClockRemoved;
+
+    interface Stats {
+        int GET_NEXT_DELIVERY_TIME = 0;
+        int GET_NEXT_WAKEUP_DELIVERY_TIME = 1;
+    }
+
+    final StatLogger mStatLogger = new StatLogger("LazyAlarmStore stats", new String[]{
+            "GET_NEXT_DELIVERY_TIME",
+            "GET_NEXT_WAKEUP_DELIVERY_TIME",
+    });
+
+    // Decreasing time order because it is more efficient to remove from the tail of an array list.
+    private static final Comparator<Alarm> sDecreasingTimeOrder = Comparator.comparingLong(
+            Alarm::getWhenElapsed).reversed();
+
+    @Override
+    public void add(Alarm a) {
+        int index = Collections.binarySearch(mAlarms, a, sDecreasingTimeOrder);
+        if (index < 0) {
+            index = 0 - index - 1;
+        }
+        mAlarms.add(index, a);
+    }
+
+    @Override
+    public void addAll(ArrayList<Alarm> alarms) {
+        if (alarms == null) {
+            return;
+        }
+        mAlarms.addAll(alarms);
+        Collections.sort(alarms, sDecreasingTimeOrder);
+    }
+
+    @Override
+    public ArrayList<Alarm> remove(Predicate<Alarm> whichAlarms) {
+        final ArrayList<Alarm> removedAlarms = new ArrayList<>();
+        for (int i = mAlarms.size() - 1; i >= 0; i--) {
+            if (whichAlarms.test(mAlarms.get(i))) {
+                final Alarm removed = mAlarms.remove(i);
+                if (removed.alarmClock != null && mOnAlarmClockRemoved != null) {
+                    mOnAlarmClockRemoved.run();
+                }
+                if (isTimeTickAlarm(removed)) {
+                    // This code path is not invoked when delivering alarms, only when removing
+                    // alarms due to the caller cancelling it or getting uninstalled, etc.
+                    Slog.wtf(TAG, "Removed TIME_TICK alarm");
+                }
+                removedAlarms.add(removed);
+            }
+        }
+        return removedAlarms;
+    }
+
+    @Override
+    public void setAlarmClockRemovalListener(Runnable listener) {
+        mOnAlarmClockRemoved = listener;
+    }
+
+    @Override
+    public Alarm getNextWakeFromIdleAlarm() {
+        for (int i = mAlarms.size() - 1; i >= 0; i--) {
+            final Alarm alarm = mAlarms.get(i);
+            if ((alarm.flags & AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
+                return alarm;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public int size() {
+        return mAlarms.size();
+    }
+
+    @Override
+    public long getNextWakeupDeliveryTime() {
+        final long start = mStatLogger.getTime();
+        long nextWakeup = 0;
+        for (int i = mAlarms.size() - 1; i >= 0; i--) {
+            final Alarm a = mAlarms.get(i);
+            if (!a.wakeup) {
+                continue;
+            }
+            if (nextWakeup == 0) {
+                nextWakeup = a.getMaxWhenElapsed();
+            } else {
+                if (a.getWhenElapsed() > nextWakeup) {
+                    break;
+                }
+                nextWakeup = Math.min(nextWakeup, a.getMaxWhenElapsed());
+            }
+        }
+        mStatLogger.logDurationStat(Stats.GET_NEXT_WAKEUP_DELIVERY_TIME, start);
+        return nextWakeup;
+    }
+
+    @Override
+    public long getNextDeliveryTime() {
+        final long start = mStatLogger.getTime();
+        final int n = mAlarms.size();
+        if (n == 0) {
+            return 0;
+        }
+        long nextDelivery = mAlarms.get(n - 1).getMaxWhenElapsed();
+        for (int i = n - 2; i >= 0; i--) {
+            final Alarm a = mAlarms.get(i);
+            if (a.getWhenElapsed() > nextDelivery) {
+                break;
+            }
+            nextDelivery = Math.min(nextDelivery, a.getMaxWhenElapsed());
+        }
+        mStatLogger.logDurationStat(Stats.GET_NEXT_DELIVERY_TIME, start);
+        return nextDelivery;
+    }
+
+    @Override
+    public ArrayList<Alarm> removePendingAlarms(long nowElapsed) {
+        final ArrayList<Alarm> pending = new ArrayList<>();
+        final ArrayList<Alarm> standAlones = new ArrayList<>();
+
+        for (int i = mAlarms.size() - 1; i >= 0; i--) {
+            final Alarm alarm = mAlarms.get(i);
+            if (alarm.getWhenElapsed() > nowElapsed) {
+                break;
+            }
+            pending.add(alarm);
+            if ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) {
+                standAlones.add(alarm);
+            }
+        }
+        if (!standAlones.isEmpty()) {
+            // If there are deliverable standalone alarms, others must not go out yet.
+            mAlarms.removeAll(standAlones);
+            return standAlones;
+        }
+        mAlarms.removeAll(pending);
+        return pending;
+    }
+
+    @Override
+    public boolean updateAlarmDeliveries(AlarmDeliveryCalculator deliveryCalculator) {
+        boolean changed = false;
+        for (final Alarm alarm : mAlarms) {
+            changed |= deliveryCalculator.updateAlarmDelivery(alarm);
+        }
+        if (changed) {
+            Collections.sort(mAlarms, sDecreasingTimeOrder);
+        }
+        return changed;
+    }
+
+    @Override
+    public ArrayList<Alarm> asList() {
+        final ArrayList<Alarm> copy = new ArrayList<>(mAlarms);
+        Collections.reverse(copy);
+        return copy;
+    }
+
+    @Override
+    public void dump(IndentingPrintWriter ipw, long nowElapsed, SimpleDateFormat sdf) {
+        ipw.println(mAlarms.size() + " pending alarms: ");
+        ipw.increaseIndent();
+        dumpAlarmList(ipw, mAlarms, nowElapsed, sdf);
+        ipw.decreaseIndent();
+        mStatLogger.dump(ipw);
+    }
+
+    @Override
+    public void dumpProto(ProtoOutputStream pos, long nowElapsed) {
+        for (final Alarm a : mAlarms) {
+            a.dumpDebug(pos, AlarmManagerServiceDumpProto.PENDING_ALARMS, nowElapsed);
+        }
+    }
+}
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index 045b413..8bdca76 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -1186,11 +1186,10 @@
             // TODO: For efficiency, the same implementation should be used, by providing a
             // clearBuffers() method, or similar.
             long resourceLength = seekableInputReader.getLength();
-            if (resourceLength == -1) {
-                mResourceByteCount = -1;
-            }
-            if (mResourceByteCount != -1) {
-                mResourceByteCount += resourceLength;
+            if (mResourceByteCount == 0) {
+                // For resource byte count metric collection, we only take into account the length
+                // of the first provided input reader.
+                mResourceByteCount = resourceLength;
             }
             mExtractorInput =
                     new DefaultExtractorInput(
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index b5e7224..fbda86f 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -54,6 +54,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -194,40 +195,38 @@
                 int numRecords = 0;
                 // Add in all the apps for every user/profile.
                 for (UserHandle userHandle : users) {
-                    List<PackageInfo> pi =
-                            pm.getInstalledPackagesAsUser(PackageManager.MATCH_UNINSTALLED_PACKAGES
-                                            | PackageManager.MATCH_ANY_USER
-                                            | PackageManager.MATCH_APEX,
-                                    userHandle.getIdentifier());
-                    for (int j = 0; j < pi.size(); j++) {
-                        if (pi.get(j).applicationInfo != null) {
+                    List<PackageInfo> packagesPlusApex = getAllPackagesWithApex(pm, userHandle);
+                    for (int j = 0; j < packagesPlusApex.size(); j++) {
+                        if (packagesPlusApex.get(j).applicationInfo != null) {
                             String installer;
                             try {
-                                installer = pm.getInstallerPackageName(pi.get(j).packageName);
+                                installer = pm.getInstallerPackageName(
+                                        packagesPlusApex.get(j).packageName);
                             } catch (IllegalArgumentException e) {
                                 installer = "";
                             }
                             long applicationInfoToken =
                                     output.start(ProtoOutputStream.FIELD_TYPE_MESSAGE
                                             | ProtoOutputStream.FIELD_COUNT_REPEATED
-                                                    | APPLICATION_INFO_FIELD_ID);
+                                            | APPLICATION_INFO_FIELD_ID);
                             output.write(ProtoOutputStream.FIELD_TYPE_INT32
-                                    | ProtoOutputStream.FIELD_COUNT_SINGLE | UID_FIELD_ID,
-                                            pi.get(j).applicationInfo.uid);
+                                            | ProtoOutputStream.FIELD_COUNT_SINGLE | UID_FIELD_ID,
+                                    packagesPlusApex.get(j).applicationInfo.uid);
                             output.write(ProtoOutputStream.FIELD_TYPE_INT64
-                                    | ProtoOutputStream.FIELD_COUNT_SINGLE
-                                            | VERSION_FIELD_ID, pi.get(j).getLongVersionCode());
+                                            | ProtoOutputStream.FIELD_COUNT_SINGLE
+                                            | VERSION_FIELD_ID,
+                                    packagesPlusApex.get(j).getLongVersionCode());
+                            output.write(ProtoOutputStream.FIELD_TYPE_STRING
+                                            | ProtoOutputStream.FIELD_COUNT_SINGLE
+                                            | VERSION_STRING_FIELD_ID,
+                                    packagesPlusApex.get(j).versionName);
                             output.write(ProtoOutputStream.FIELD_TYPE_STRING
                                     | ProtoOutputStream.FIELD_COUNT_SINGLE
-                                    | VERSION_STRING_FIELD_ID,
-                                            pi.get(j).versionName);
+                                    | PACKAGE_NAME_FIELD_ID, packagesPlusApex.get(j).packageName);
                             output.write(ProtoOutputStream.FIELD_TYPE_STRING
-                                    | ProtoOutputStream.FIELD_COUNT_SINGLE
-                                            | PACKAGE_NAME_FIELD_ID, pi.get(j).packageName);
-                            output.write(ProtoOutputStream.FIELD_TYPE_STRING
-                                    | ProtoOutputStream.FIELD_COUNT_SINGLE
+                                            | ProtoOutputStream.FIELD_COUNT_SINGLE
                                             | INSTALLER_FIELD_ID,
-                                                    installer == null ? "" : installer);
+                                    installer == null ? "" : installer);
                             numRecords++;
                             output.end(applicationInfoToken);
                         }
@@ -245,6 +244,26 @@
         });
     }
 
+    private static List<PackageInfo> getAllPackagesWithApex(PackageManager pm,
+            UserHandle userHandle) {
+        // We want all the uninstalled packages because uninstalled package uids can still be logged
+        // to statsd.
+        List<PackageInfo> allPackages = new ArrayList<>(
+                pm.getInstalledPackagesAsUser(PackageManager.MATCH_UNINSTALLED_PACKAGES
+                                | PackageManager.MATCH_ANY_USER,
+                        userHandle.getIdentifier()));
+        // We make a second query to package manager for the apex modules because package manager
+        // returns both installed and uninstalled apexes with
+        // PackageManager.MATCH_UNINSTALLED_PACKAGES flag. We only want active apexes because
+        // inactive apexes can conflict with active ones.
+        for (PackageInfo packageInfo : pm.getInstalledPackages(PackageManager.MATCH_APEX)) {
+            if (packageInfo.isApex) {
+                allPackages.add(packageInfo);
+            }
+        }
+        return allPackages;
+    }
+
     private static class WakelockThread extends Thread {
         private final PowerManager.WakeLock mWl;
         private final Runnable mRunnable;
diff --git a/api/Android.bp b/api/Android.bp
index 21a7166..a5def69 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -16,36 +16,17 @@
     default_visibility: ["//visibility:private"],
 }
 
-// *-current.txt files for use by modules in other directories like cts
-filegroup {
-    name: "frameworks-base-api-current.txt",
-    srcs: ["current.txt"],
-    visibility: ["//visibility:public"],
-}
-
-filegroup {
-    name: "frameworks-base-api-system-current.txt",
-    srcs: ["system-current.txt"],
-    visibility: ["//visibility:public"],
-}
-
-filegroup {
-    name: "frameworks-base-api-system-removed.txt",
-    srcs: ["system-removed.txt"],
-    visibility: ["//visibility:public"],
-}
-
 genrule {
     name: "current-api-xml",
     tools: ["metalava"],
-    srcs: ["current.txt"],
+    srcs: [":frameworks-base-api-current.txt"],
     out: ["current.api"],
     cmd: "$(location metalava) --no-banner -convert2xmlnostrip $(in) $(out)",
     visibility: ["//visibility:public"],
 }
 
 genrule {
-    name: "frameworks-base-api-current-merged.txt",
+    name: "frameworks-base-api-current.txt",
     srcs: [
         ":conscrypt.module.public.api{.public.api.txt}",
         ":framework-appsearch{.public.api.txt}",
@@ -74,10 +55,11 @@
             dest: "android.txt",
         },
     ],
+    visibility: ["//visibility:public"],
 }
 
 genrule {
-    name: "frameworks-base-api-removed-merged.txt",
+    name: "frameworks-base-api-removed.txt",
     srcs: [
         ":conscrypt.module.public.api{.public.removed-api.txt}",
         ":framework-appsearch{.public.removed-api.txt}",
@@ -104,7 +86,7 @@
 }
 
 genrule {
-    name: "frameworks-base-api-system-current-merged.txt",
+    name: "frameworks-base-api-system-current.txt",
     srcs: [
         ":framework-appsearch{.system.api.txt}",
         ":framework-graphics{.system.api.txt}",
@@ -132,10 +114,11 @@
             dest: "android.txt",
         },
     ],
+    visibility: ["//visibility:public"],
 }
 
 genrule {
-    name: "frameworks-base-api-system-removed-merged.txt",
+    name: "frameworks-base-api-system-removed.txt",
     srcs: [
         ":framework-appsearch{.system.removed-api.txt}",
         ":framework-graphics{.system.removed-api.txt}",
@@ -158,10 +141,11 @@
             dest: "system-removed.txt",
         },
     ],
+    visibility: ["//visibility:public"],
 }
 
 genrule {
-    name: "frameworks-base-api-module-lib-current-merged.txt",
+    name: "frameworks-base-api-module-lib-current.txt",
     srcs: [
         ":framework-appsearch{.module-lib.api.txt}",
         ":framework-graphics{.module-lib.api.txt}",
@@ -192,7 +176,7 @@
 }
 
 genrule {
-    name: "frameworks-base-api-module-lib-removed-merged.txt",
+    name: "frameworks-base-api-module-lib-removed.txt",
     srcs: [
         ":framework-appsearch{.module-lib.removed-api.txt}",
         ":framework-graphics{.module-lib.removed-api.txt}",
@@ -220,8 +204,8 @@
 genrule {
     name: "combined-removed-dex",
     srcs: [
-        ":frameworks-base-api-removed-merged.txt",
-        ":frameworks-base-api-system-removed-merged.txt",
+        ":frameworks-base-api-removed.txt",
+        ":frameworks-base-api-system-removed.txt",
         ":android.car-stubs-docs{.removed-api.txt}",
         ":android.car-system-stubs-docs{.removed-api.txt}",
     ],
diff --git a/api/current.txt b/api/current.txt
index 8799598..b1f7930b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -31,6 +31,7 @@
     field @Deprecated public static final String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
     field @Deprecated public static final String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
+    field public static final String BIND_COMPANION_DEVICE_SERVICE = "android.permission.BIND_COMPANION_DEVICE_SERVICE";
     field public static final String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE";
     field public static final String BIND_CONTROLS = "android.permission.BIND_CONTROLS";
     field public static final String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
@@ -133,6 +134,7 @@
     field public static final String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
     field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO";
     field public static final String REORDER_TASKS = "android.permission.REORDER_TASKS";
+    field public static final String REQUEST_COMPANION_PROFILE_WATCH = "android.permission.REQUEST_COMPANION_PROFILE_WATCH";
     field public static final String REQUEST_COMPANION_RUN_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND";
     field public static final String REQUEST_COMPANION_USE_DATA_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND";
     field public static final String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
@@ -5528,6 +5530,7 @@
     field @Deprecated public static final String EXTRA_PEOPLE = "android.people";
     field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
     field public static final String EXTRA_PICTURE = "android.picture";
+    field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
     field public static final String EXTRA_PROGRESS = "android.progress";
     field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
     field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
@@ -5673,6 +5676,7 @@
     method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
     method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon);
     method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap);
+    method @NonNull public android.app.Notification.BigPictureStyle bigPictureContentDescription(@Nullable CharSequence);
     method public android.app.Notification.BigPictureStyle setBigContentTitle(CharSequence);
     method public android.app.Notification.BigPictureStyle setSummaryText(CharSequence);
   }
@@ -5972,6 +5976,7 @@
     method public long[] getVibrationPattern();
     method public boolean hasUserSetImportance();
     method public boolean hasUserSetSound();
+    method public boolean isConversation();
     method public boolean isDemoted();
     method public boolean isImportantConversation();
     method public void setAllowBubbles(boolean);
@@ -6138,6 +6143,7 @@
     method public android.content.IntentSender getIntentSender();
     method public static android.app.PendingIntent getService(android.content.Context, int, @NonNull android.content.Intent, int);
     method @Deprecated public String getTargetPackage();
+    method public boolean isImmutable();
     method @Nullable public static android.app.PendingIntent readPendingIntentOrNullFromParcel(@NonNull android.os.Parcel);
     method public void send() throws android.app.PendingIntent.CanceledException;
     method public void send(int) throws android.app.PendingIntent.CanceledException;
@@ -9430,14 +9436,16 @@
 
   public final class AssociationRequest implements android.os.Parcelable {
     method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
+    field public static final String DEVICE_PROFILE_WATCH = "android.app.role.COMPANION_DEVICE_WATCH";
   }
 
   public static final class AssociationRequest.Builder {
     ctor public AssociationRequest.Builder();
     method @NonNull public android.companion.AssociationRequest.Builder addDeviceFilter(@Nullable android.companion.DeviceFilter<?>);
     method @NonNull public android.companion.AssociationRequest build();
+    method @NonNull public android.companion.AssociationRequest.Builder setDeviceProfile(@NonNull String);
     method @NonNull public android.companion.AssociationRequest.Builder setSingleDevice(boolean);
   }
 
@@ -9487,6 +9495,14 @@
     method public abstract void onFailure(CharSequence);
   }
 
+  public abstract class CompanionDeviceService extends android.app.Service {
+    ctor public CompanionDeviceService();
+    method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method @MainThread public abstract void onDeviceAppeared(@NonNull String);
+    method @MainThread public abstract void onDeviceDisappeared(@NonNull String);
+    field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
+  }
+
   public interface DeviceFilter<D extends android.os.Parcelable> extends android.os.Parcelable {
   }
 
@@ -10679,8 +10695,6 @@
     field public static final String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
     field public static final String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
     field public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
-    field public static final String ACTION_PACKAGE_STARTABLE = "android.intent.action.PACKAGE_STARTABLE";
-    field public static final String ACTION_PACKAGE_UNSTARTABLE = "android.intent.action.PACKAGE_UNSTARTABLE";
     field public static final String ACTION_PACKAGE_VERIFIED = "android.intent.action.PACKAGE_VERIFIED";
     field public static final String ACTION_PASTE = "android.intent.action.PASTE";
     field public static final String ACTION_PICK = "android.intent.action.PICK";
@@ -12308,9 +12322,6 @@
     field public static final int SYNCHRONOUS = 2; // 0x2
     field @Nullable public static final java.util.List<java.security.cert.Certificate> TRUST_ALL;
     field @NonNull public static final java.util.List<java.security.cert.Certificate> TRUST_NONE;
-    field public static final int UNSTARTABLE_REASON_CONNECTION_ERROR = 1; // 0x1
-    field public static final int UNSTARTABLE_REASON_INSUFFICIENT_STORAGE = 2; // 0x2
-    field public static final int UNSTARTABLE_REASON_UNKNOWN = 0; // 0x0
     field public static final int VERIFICATION_ALLOW = 1; // 0x1
     field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
     field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
@@ -16439,6 +16450,7 @@
     method public float getGlyphBounds(@IntRange(from=0) int, @NonNull android.graphics.Paint, @Nullable android.graphics.RectF);
     method @NonNull public android.os.LocaleList getLocaleList();
     method public void getMetrics(@NonNull android.graphics.Paint, @Nullable android.graphics.Paint.FontMetrics);
+    method public int getSourceIdentifier();
     method @NonNull public android.graphics.fonts.FontStyle getStyle();
     method @IntRange(from=0) public int getTtcIndex();
   }
@@ -25288,6 +25300,7 @@
   public final class MediaCas implements java.lang.AutoCloseable {
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     ctor public MediaCas(@NonNull android.content.Context, int, @Nullable String, int) throws android.media.MediaCasException.UnsupportedCasException;
+    ctor public MediaCas(@NonNull android.content.Context, int, @Nullable String, int, @Nullable android.os.Handler, @Nullable android.media.MediaCas.EventListener) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
     method protected void finalize();
@@ -31419,6 +31432,8 @@
     field @Deprecated public String FQDN;
     field @Deprecated public static final int SECURITY_TYPE_EAP = 3; // 0x3
     field @Deprecated public static final int SECURITY_TYPE_EAP_SUITE_B = 5; // 0x5
+    field @Deprecated public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE = 9; // 0x9
+    field @Deprecated public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT = 5; // 0x5
     field @Deprecated public static final int SECURITY_TYPE_OPEN = 0; // 0x0
     field @Deprecated public static final int SECURITY_TYPE_OWE = 6; // 0x6
     field @Deprecated public static final int SECURITY_TYPE_PSK = 2; // 0x2
@@ -31656,6 +31671,7 @@
     method public boolean isWapiSupported();
     method public boolean isWifiEnabled();
     method public boolean isWifiStandardSupported(int);
+    method public boolean isWpa3ApValidationSupported();
     method public boolean isWpa3SaeSupported();
     method public boolean isWpa3SuiteBSupported();
     method @Deprecated public boolean pingSupplicant();
@@ -43148,6 +43164,11 @@
     field public static final int PURPOSE_SIGN = 4; // 0x4
     field public static final int PURPOSE_VERIFY = 8; // 0x8
     field public static final int PURPOSE_WRAP_KEY = 32; // 0x20
+    field public static final int SECURITY_LEVEL_SOFTWARE = 0; // 0x0
+    field public static final int SECURITY_LEVEL_STRONGBOX = 2; // 0x2
+    field public static final int SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1; // 0x1
+    field public static final int SECURITY_LEVEL_UNKNOWN = -2; // 0xfffffffe
+    field public static final int SECURITY_LEVEL_UNKNOWN_SECURE = -1; // 0xffffffff
     field public static final String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
     field public static final String SIGNATURE_PADDING_RSA_PSS = "PSS";
   }
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index 8ca290f..1a65064 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -99,10 +99,17 @@
     method public boolean dispatchMediaKeyEventToSessionAsSystemService(@NonNull android.view.KeyEvent, @NonNull android.media.session.MediaSession.Token);
     method public void dispatchVolumeKeyEventAsSystemService(@NonNull android.view.KeyEvent, int);
     method public void dispatchVolumeKeyEventToSessionAsSystemService(@NonNull android.view.KeyEvent, @NonNull android.media.session.MediaSession.Token);
+    method public void registerRemoteVolumeControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.RemoteVolumeControllerCallback);
+    method public void unregisterRemoteVolumeControllerCallback(@NonNull android.media.session.MediaSessionManager.RemoteVolumeControllerCallback);
     field public static final int RESULT_MEDIA_KEY_HANDLED = 1; // 0x1
     field public static final int RESULT_MEDIA_KEY_NOT_HANDLED = 0; // 0x0
   }
 
+  public static interface MediaSessionManager.RemoteVolumeControllerCallback {
+    method public void onSessionChanged(@Nullable android.media.session.MediaSession.Token);
+    method public void onVolumeChanged(@NonNull android.media.session.MediaSession.Token, int);
+  }
+
   public final class PlaybackState implements android.os.Parcelable {
     method public boolean isActiveState();
   }
diff --git a/api/module-lib-lint-baseline.txt b/api/module-lib-lint-baseline.txt
deleted file mode 100644
index 56f7a02..0000000
--- a/api/module-lib-lint-baseline.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-// Baseline format: 1.0
-ActionValue: android.net.TetheringConstants#EXTRA_ADD_TETHER_TYPE:
-    Inconsistent extra value; expected `android.net.extra.ADD_TETHER_TYPE`, was `extraAddTetherType`
-ActionValue: android.net.TetheringConstants#EXTRA_PROVISION_CALLBACK:
-    Inconsistent extra value; expected `android.net.extra.PROVISION_CALLBACK`, was `extraProvisionCallback`
-ActionValue: android.net.TetheringConstants#EXTRA_REM_TETHER_TYPE:
-    Inconsistent extra value; expected `android.net.extra.REM_TETHER_TYPE`, was `extraRemTetherType`
-ActionValue: android.net.TetheringConstants#EXTRA_RUN_PROVISION:
-    Inconsistent extra value; expected `android.net.extra.RUN_PROVISION`, was `extraRunProvision`
-ActionValue: android.net.TetheringConstants#EXTRA_SET_ALARM:
-    Inconsistent extra value; expected `android.net.extra.SET_ALARM`, was `extraSetAlarm`
-ActionValue: android.net.TetheringManager#ACTION_TETHER_STATE_CHANGED:
-    Inconsistent action value; expected `android.net.action.TETHER_STATE_CHANGED`, was `android.net.conn.TETHER_STATE_CHANGED`
-ActionValue: android.net.TetheringManager#EXTRA_ACTIVE_TETHER:
-    Inconsistent extra value; expected `android.net.extra.ACTIVE_TETHER`, was `tetherArray`
-ActionValue: android.net.TetheringManager#EXTRA_AVAILABLE_TETHER:
-    Inconsistent extra value; expected `android.net.extra.AVAILABLE_TETHER`, was `availableArray`
-ActionValue: android.net.TetheringManager#EXTRA_ERRORED_TETHER:
-    Inconsistent extra value; expected `android.net.extra.ERRORED_TETHER`, was `erroredArray`
-
-
-ManagerConstructor: android.net.TetheringManager#TetheringManager(android.content.Context, java.util.function.Supplier<android.os.IBinder>):
-    Managers must always be obtained from Context; no direct constructors
-
-
-PrivateSuperclass: android.location.GnssAntennaInfo.PhaseCenterVariationCorrections:
-    Public class android.location.GnssAntennaInfo.PhaseCenterVariationCorrections extends private class android.location.GnssAntennaInfo.SphericalCorrections
-PrivateSuperclass: android.location.GnssAntennaInfo.SignalGainCorrections:
-    Public class android.location.GnssAntennaInfo.SignalGainCorrections extends private class android.location.GnssAntennaInfo.SphericalCorrections
diff --git a/api/module-lib-removed.txt b/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/api/system-current.txt b/api/system-current.txt
index 9cf0926..b28e7af 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -381,6 +381,7 @@
     field public static final String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
     field public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
     field public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
+    field public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn";
     field public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
     field public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
     field public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
@@ -4423,11 +4424,11 @@
   }
 
   public class MediaPlayer implements android.media.AudioRouting android.media.VolumeAutomation {
-    method @RequiresPermission("android.permission.BIND_IMS_SERVICE") public void setOnImsRxNoticeListener(@Nullable android.media.MediaPlayer.OnImsRxNoticeListener, @Nullable android.os.Handler);
+    method @RequiresPermission("android.permission.BIND_IMS_SERVICE") public void setOnRtpRxNoticeListener(@NonNull android.content.Context, @NonNull android.media.MediaPlayer.OnRtpRxNoticeListener, @Nullable android.os.Handler);
   }
 
-  public static interface MediaPlayer.OnImsRxNoticeListener {
-    method public void onImsRxNotice(@NonNull android.media.MediaPlayer, @NonNull byte[]);
+  public static interface MediaPlayer.OnRtpRxNoticeListener {
+    method public void onRtpRxNotice(@NonNull android.media.MediaPlayer, int, @NonNull int[]);
   }
 
   public final class MediaRecorder.AudioSource {
@@ -5090,6 +5091,7 @@
     field public static final int INVALID_AV_SYNC_ID = -1; // 0xffffffff
     field public static final int INVALID_FILTER_ID = -1; // 0xffffffff
     field public static final long INVALID_FILTER_ID_64BIT = -1L; // 0xffffffffffffffffL
+    field public static final int INVALID_FIRST_MACROBLOCK_IN_SLICE = -1; // 0xffffffff
     field public static final int INVALID_FRONTEND_SETTING_FREQUENCY = -1; // 0xffffffff
     field public static final int INVALID_LTS_ID = -1; // 0xffffffff
     field public static final int INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = -1; // 0xffffffff
@@ -5390,6 +5392,7 @@
 
   public class MmtpRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
     method public long getDataLength();
+    method public int getFirstMbInSlice();
     method public int getMpuSequenceNumber();
     method public long getPts();
     method public int getScHevcIndexMask();
@@ -5430,9 +5433,14 @@
     field public static final int SC_HEVC_INDEX_SLICE_TRAIL_CRA = 128; // 0x80
     field public static final int SC_HEVC_INDEX_SPS = 1; // 0x1
     field public static final int SC_INDEX_B_FRAME = 4; // 0x4
+    field public static final int SC_INDEX_B_SLICE = 64; // 0x40
     field public static final int SC_INDEX_I_FRAME = 1; // 0x1
+    field public static final int SC_INDEX_I_SLICE = 16; // 0x10
     field public static final int SC_INDEX_P_FRAME = 2; // 0x2
+    field public static final int SC_INDEX_P_SLICE = 32; // 0x20
     field public static final int SC_INDEX_SEQUENCE = 8; // 0x8
+    field public static final int SC_INDEX_SI_SLICE = 128; // 0x80
+    field public static final int SC_INDEX_SP_SLICE = 256; // 0x100
     field public static final int TS_INDEX_ADAPTATION_EXTENSION_FLAG = 4096; // 0x1000
     field public static final int TS_INDEX_CHANGE_TO_EVEN_SCRAMBLED = 8; // 0x8
     field public static final int TS_INDEX_CHANGE_TO_NOT_SCRAMBLED = 4; // 0x4
@@ -5553,6 +5561,7 @@
 
   public class TsRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
     method public long getDataLength();
+    method public int getFirstMbInSlice();
     method public int getPacketId();
     method public long getPts();
     method public int getScIndexMask();
@@ -5878,6 +5887,7 @@
   public class DvbsFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
     method @NonNull public static android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder builder();
     method @Nullable public android.media.tv.tuner.frontend.DvbsCodeRate getCodeRate();
+    method public boolean getCouldHandleDiseqcRxMessage();
     method public int getInputStreamId();
     method public int getModulation();
     method public int getPilot();
@@ -5887,7 +5897,6 @@
     method public int getSymbolRate();
     method public int getType();
     method public int getVcmMode();
-    method public boolean isDiseqcRxMessage();
     field public static final int MODULATION_AUTO = 1; // 0x1
     field public static final int MODULATION_MOD_128APSK = 2048; // 0x800
     field public static final int MODULATION_MOD_16APSK = 256; // 0x100
@@ -5931,7 +5940,7 @@
   public static class DvbsFrontendSettings.Builder {
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings build();
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setCodeRate(@Nullable android.media.tv.tuner.frontend.DvbsCodeRate);
-    method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setDiseqcRxMessage(boolean);
+    method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setCouldHandleDiseqcRxMessage(boolean);
     method @IntRange(from=1) @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setFrequency(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setInputStreamId(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setModulation(int);
@@ -6071,7 +6080,7 @@
   }
 
   public abstract class FrontendSettings {
-    method public int getEndFrequency();
+    method @IntRange(from=1) public int getEndFrequency();
     method public int getFrequency();
     method public int getFrontendSpectralInversion();
     method public abstract int getType();
@@ -6353,6 +6362,7 @@
   public interface ScanCallback {
     method public void onAnalogSifStandardReported(int);
     method public void onAtsc3PlpInfosReported(@NonNull android.media.tv.tuner.frontend.Atsc3PlpInfo[]);
+    method public default void onDvbcAnnexReported(int);
     method public void onDvbsStandardReported(int);
     method public void onDvbtStandardReported(int);
     method public void onFrequenciesReported(@NonNull int[]);
@@ -12337,6 +12347,17 @@
 
 package android.telephony.ims {
 
+  public final class AudioCodecAttributes implements android.os.Parcelable {
+    ctor public AudioCodecAttributes(float, @NonNull android.util.Range<java.lang.Float>, float, @NonNull android.util.Range<java.lang.Float>);
+    method public int describeContents();
+    method public float getBandwidthKhz();
+    method @NonNull public android.util.Range<java.lang.Float> getBandwidthRangeKhz();
+    method public float getBitrateKbps();
+    method @NonNull public android.util.Range<java.lang.Float> getBitrateRangeKbps();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.AudioCodecAttributes> CREATOR;
+  }
+
   public final class ImsCallForwardInfo implements android.os.Parcelable {
     ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
     method public int describeContents();
@@ -12366,6 +12387,7 @@
     ctor public ImsCallProfile(int, int);
     ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
     method public int describeContents();
+    method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes();
     method public String getCallExtra(String);
     method public String getCallExtra(String, String);
     method public boolean getCallExtraBoolean(String);
@@ -12380,6 +12402,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes();
     method @NonNull public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
@@ -12390,6 +12413,7 @@
     method public boolean isVideoCall();
     method public boolean isVideoPaused();
     method public static int presentationToOir(int);
+    method public void setAcceptedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
     method public void setCallExtra(String, String);
     method public void setCallExtraBoolean(String, boolean);
     method public void setCallExtraInt(String, int);
@@ -12400,6 +12424,7 @@
     method public void setEmergencyServiceCategories(int);
     method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
     method public void setHasKnownUserIntentEmergency(boolean);
+    method public void setOfferedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
     method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
     method public void updateCallType(android.telephony.ims.ImsCallProfile);
     method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
@@ -12459,6 +12484,7 @@
     method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
+    method public void callSessionDtmfReceived(char);
     method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
     method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
     method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
@@ -12479,6 +12505,7 @@
     method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
     method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
     method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
+    method public void callSessionRtpHeaderExtensionsReceived(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
     method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
     method public void callSessionRttMessageReceived(String);
     method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
@@ -12705,6 +12732,7 @@
     ctor public ImsStreamMediaProfile(int, int, int, int, int);
     method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
     method public int describeContents();
+    method @Nullable public android.telephony.ims.AudioCodecAttributes getAudioCodecAttributes();
     method public int getAudioDirection();
     method public int getAudioQuality();
     method public int getRttMode();
@@ -12712,6 +12740,7 @@
     method public int getVideoQuality();
     method public boolean isReceivingRttAudio();
     method public boolean isRttCall();
+    method public void setAudioCodecAttributes(@NonNull android.telephony.ims.AudioCodecAttributes);
     method public void setReceivingRttAudio(boolean);
     method public void setRttMode(int);
     method public void writeToParcel(android.os.Parcel, int);
@@ -12833,6 +12862,24 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
   }
 
+  public final class RtpHeaderExtension implements android.os.Parcelable {
+    ctor public RtpHeaderExtension(@IntRange(from=1, to=14) int, @NonNull byte[]);
+    method public int describeContents();
+    method @NonNull public byte[] getExtensionData();
+    method @IntRange(from=1, to=14) public int getLocalIdentifier();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtension> CREATOR;
+  }
+
+  public final class RtpHeaderExtensionType implements android.os.Parcelable {
+    ctor public RtpHeaderExtensionType(@IntRange(from=1, to=14) int, @NonNull android.net.Uri);
+    method public int describeContents();
+    method @IntRange(from=1, to=14) public int getLocalIdentifier();
+    method @NonNull public android.net.Uri getUri();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtensionType> CREATOR;
+  }
+
   public class SipDelegateManager {
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSupported() throws android.telephony.ims.ImsException;
   }
@@ -12949,6 +12996,7 @@
     method public void removeParticipants(String[]);
     method public void resume(android.telephony.ims.ImsStreamMediaProfile);
     method public void sendDtmf(char, android.os.Message);
+    method public void sendRtpHeaderExtensions(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
     method public void sendRttMessage(String);
     method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
     method public void sendRttModifyResponse(boolean);
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
index 773ecd03..3ef1f35 100644
--- a/api/system-lint-baseline.txt
+++ b/api/system-lint-baseline.txt
@@ -41,8 +41,8 @@
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTunnelModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex)
 
 
-ExecutorRegistration: android.media.MediaPlayer#setOnImsRxNoticeListener(android.media.MediaPlayer.OnImsRxNoticeListener, android.os.Handler):
-    Registration methods should have overload that accepts delivery Executor: `setOnImsRxNoticeListener`
+ExecutorRegistration: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
+    Registration methods should have overload that accepts delivery Executor: `setOnRtpRxNoticeListener`
 ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#deletePersistentGroup(android.net.wifi.p2p.WifiP2pManager.Channel, int, android.net.wifi.p2p.WifiP2pManager.ActionListener):
     
 ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#factoryReset(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener):
@@ -377,8 +377,8 @@
     
 SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioTrack.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-SamShouldBeLast: android.media.MediaPlayer#setOnImsRxNoticeListener(android.media.MediaPlayer.OnImsRxNoticeListener, android.os.Handler):
-    SAM-compatible parameters (such as parameter 1, "listener", in android.media.MediaPlayer.setOnImsRxNoticeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
+    SAM-compatible parameters (such as parameter 2, "listener", in android.media.MediaPlayer.setOnRtpRxNoticeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.MediaRecorder#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
     
 SamShouldBeLast: android.media.MediaRecorder#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
diff --git a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
index 8683ca1..a0361d0 100644
--- a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
+++ b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
@@ -294,9 +294,9 @@
                 "       -a|--authority <AUTHORITY>\n" +
                 "    App-standby related options\n" +
                 "\n" +
-                "       -f|--foreground (cause WORKING_SET, FREQUENT sync adapters" +
-                        " to run immediately)\n" +
-                "       -F|--top (cause even RARE sync adapters to run immediately)\n" +
+                "       -f|--foreground (defeat app-standby job throttling," +
+                " but not battery saver)\n" +
+                "       -F|--top (defeat app-standby job throttling and battery saver)\n" +
                 "    ContentResolver extra options:\n" +
                 "      --is|--ignore-settings: Add SYNC_EXTRAS_IGNORE_SETTINGS\n" +
                 "      --ib|--ignore-backoff: Add SYNC_EXTRAS_IGNORE_BACKOFF\n" +
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index ac2a8e4..b270a52 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -502,6 +502,7 @@
         MediametricsMediaParserReported mediametrics_mediaparser_reported = 316;
         TlsHandshakeReported tls_handshake_reported = 317 [(module) = "conscrypt"];
         TextClassifierApiUsageReported text_classifier_api_usage_reported = 318  [(module) = "textclassifier"];
+        KilledAppStatsReported killed_app_stats_reported = 319 [(module) = "carwatchdogd"];
 
         // StatsdStats tracks platform atoms with ids upto 500.
         // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value.
@@ -4280,9 +4281,16 @@
     optional android.stats.sysui.NotificationImportance old_importance = 5;
     // New importance setting
     optional android.stats.sysui.NotificationImportance importance = 6;
+    // whether or not this channel represents a conversation
+    optional bool is_conversation = 7;
+    // Hash of app-assigned notification conversation id
+    optional int32 conversation_id_hash = 8;
+    // whether or not the user demoted this channel out of the conversation space
+    optional bool is_conversation_demoted = 9;
+    // whether this conversation is marked as being a priority
+    optional bool is_conversation_priority = 10;
 }
 
-
 /**
  * Logs when a biometric acquire event occurs.
  *
@@ -5304,6 +5312,11 @@
         LAUNCHER_APP_CLOSE_TO_HOME = 10;
         LAUNCHER_APP_CLOSE_TO_PIP = 11;
         LAUNCHER_QUICK_SWITCH = 12;
+        SHADE_HEADS_UP_APPEAR = 13;
+        SHADE_HEADS_UP_DISAPPEAR = 14;
+        SHADE_NOTIFICATION_ADD = 15;
+        SHADE_NOTIFICATION_REMOVE = 16;
+        SHADE_APP_LAUNCH = 17;
     }
 
     optional InteractionType interaction_type = 1;
@@ -12067,3 +12080,143 @@
     optional ResultType result_type = 2;
     optional int64 latency_millis = 3;
 }
+
+/**
+ * Logs the current state of an application before it is killed.
+ *
+ * Pushed from:
+ *  packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp
+ */
+message KilledAppStatsReported {
+    // Linux process uid for the package.
+    optional int32 uid = 1 [(is_uid) = true];
+
+    // Name of the package that was killed.
+    optional string package_name = 2;
+
+    // State of the application when it was killed.
+    enum AppState {
+        UNKNOWN_APP_STATE = 0;
+        BACKGROUND = 1;
+        FOREGROUND = 2;
+    }
+    optional AppState app_state = 3;
+
+    // System state indicating whether the system was in normal mode or garage mode.
+    enum SystemState {
+        UNKNOWN_SYSTEM_STATE = 0;
+        USER_INTERACTION_MODE = 1;
+        NO_USER_INTERACTION_MODE = 2;
+    }
+    optional SystemState system_state = 4;
+
+    // Reason for killing the application.
+    // Keep in sync between:
+    //   packages/services/Car/watchdog/server/src/ApplicationTerminator.h
+    //   frameworks/base/cmds/statsd/src/atoms.proto
+    enum KillReason {
+        UNKNOWN_KILL_REASON = 0;
+        KILLED_ON_ANR = 1;
+        KILLED_ON_IO_OVERUSE = 2;
+        KILLED_ON_MEMORY_OVERUSE = 3;
+    }
+    optional KillReason kill_reason = 5;
+
+    // Stats of the processes owned by the application when the application was killed.
+    // The process stack traces are not collected when the application was killed due to IO_OVERUSE.
+    optional ProcessStats process_stat = 6 [(log_mode) = MODE_BYTES];
+
+    // The application's I/O overuse stats logged only when the kill reason is KILLED_ON_IO_OVERUSE.
+    optional IoOveruseStats io_overuse_stats = 7 [(log_mode) = MODE_BYTES];
+}
+
+/**
+ * Logs I/O overuse stats for a package.
+ *
+ * Keep in sync between:
+ *  packages/services/Car/watchdog/server/src/proto/statsd.proto
+ *  frameworks/base/cmds/statsd/src/atoms.proto
+ *
+ * Logged from:
+ *  packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp
+ */
+message IoOveruseStats {
+    enum Period {
+        DAILY = 0;
+        WEEKLY = 1;
+    }
+
+    // Threshold and usage stats period.
+    optional Period period = 1;
+
+    // Threshold in-terms of write bytes defined for the package.
+    optional PerStateBytes threshold = 2;
+
+    // Number of write bytes in each state for the specified period.
+    optional PerStateBytes written_bytes = 3;
+};
+
+/**
+ * Logs bytes attributed to each application and system states.
+ *
+ * Keep in sync between:
+ *  packages/services/Car/watchdog/server/src/proto/statsd.proto
+ *  frameworks/base/cmds/statsd/src/atoms.proto
+ *
+ * Logged from:
+ *  packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp
+ */
+message PerStateBytes {
+    // Number of bytes attributed to the application foreground.
+    optional int64 foreground_bytes = 1;
+
+    // Number of bytes attributed to the application background.
+    optional int64 background_bytes = 2;
+
+    // Number of bytes attributed to the garage mode.
+    optional int64 garage_mode_bytes = 3;
+}
+
+/**
+ * Logs each ProcessStat in ProcessStats.
+ * Keep in sync between:
+ *  packages/services/Car/watchdog/server/src/proto/statsd.proto
+ *  frameworks/base/cmds/statsd/src/atoms.proto
+ * Logged from:
+ *  packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp
+ */
+message ProcessStats {
+    // Records the stats of the processes owned by an application.
+    repeated ProcessStat process_stat = 1;
+}
+
+/**
+ * Logs a process's stats.
+ * Keep in sync between:
+ *  packages/services/Car/watchdog/server/src/proto/statsd.proto
+ *  frameworks/base/cmds/statsd/src/atoms.proto
+ * Logged from:
+ *  packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp
+ */
+message ProcessStat {
+    // Command name of the process.
+    optional string process_name = 1;
+
+    // Process uptime.
+    optional uint64 uptime_milliseconds = 2;
+
+    // Number of major page faults caused by the process and its children.
+    optional uint64 major_page_faults = 3;
+
+    // Peak virtual memory size in kb.
+    optional uint64 vm_peak_kb = 4;
+
+    // Virtual memory size in kb.
+    optional uint64 vm_size_kb = 5;
+
+    // Peak resident set size (high water mark) in kb.
+    optional uint64 vm_hwm_kb = 6;
+
+    // Resident set size in kb.
+    optional uint64 vm_rss_kb = 7;
+}
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index d80f9db..acc12aa 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -90,61 +90,7 @@
     mVersionStringsInReport = config.version_strings_in_metric_report();
     mInstallerInReport = config.installer_in_metric_report();
 
-    // Init allowed pushed atom uids.
-    if (config.allowed_log_source_size() == 0) {
-        mConfigValid = false;
-        ALOGE("Log source allowlist is empty! This config won't get any data. Suggest adding at "
-                      "least AID_SYSTEM and AID_STATSD to the allowed_log_source field.");
-    } else {
-        for (const auto& source : config.allowed_log_source()) {
-            auto it = UidMap::sAidToUidMapping.find(source);
-            if (it != UidMap::sAidToUidMapping.end()) {
-                mAllowedUid.push_back(it->second);
-            } else {
-                mAllowedPkg.push_back(source);
-            }
-        }
-
-        if (mAllowedUid.size() + mAllowedPkg.size() > StatsdStats::kMaxLogSourceCount) {
-            ALOGE("Too many log sources. This is likely to be an error in the config.");
-            mConfigValid = false;
-        } else {
-            initLogSourceWhiteList();
-        }
-    }
-
-    // Init default allowed pull atom uids.
-    int numPullPackages = 0;
-    for (const string& pullSource : config.default_pull_packages()) {
-        auto it = UidMap::sAidToUidMapping.find(pullSource);
-        if (it != UidMap::sAidToUidMapping.end()) {
-            numPullPackages++;
-            mDefaultPullUids.insert(it->second);
-        } else {
-            ALOGE("Default pull atom packages must be in sAidToUidMapping");
-            mConfigValid = false;
-        }
-    }
-    // Init per-atom pull atom packages.
-    for (const PullAtomPackages& pullAtomPackages : config.pull_atom_packages()) {
-        int32_t atomId = pullAtomPackages.atom_id();
-        for (const string& pullPackage : pullAtomPackages.packages()) {
-            numPullPackages++;
-            auto it = UidMap::sAidToUidMapping.find(pullPackage);
-            if (it != UidMap::sAidToUidMapping.end()) {
-                mPullAtomUids[atomId].insert(it->second);
-            } else {
-                mPullAtomPackages[atomId].insert(pullPackage);
-            }
-        }
-    }
-    if (numPullPackages > StatsdStats::kMaxPullAtomPackages) {
-        ALOGE("Too many sources in default_pull_packages and pull_atom_packages. This is likely to "
-              "be an error in the config");
-        mConfigValid = false;
-    } else {
-        initPullAtomSources();
-    }
+    createAllLogSourcesFromConfig(config);
     mPullerManager->RegisterPullUidProvider(mConfigKey, this);
 
     // Store the sub-configs used.
@@ -241,10 +187,75 @@
     mAllAnomalyTrackers = newAnomalyTrackers;
     mAlertTrackerMap = newAlertTrackerMap;
     mAllPeriodicAlarmTrackers = newPeriodicAlarmTrackers;
+
+    mAllowedUid.clear();
+    mAllowedPkg.clear();
+    mDefaultPullUids.clear();
+    mPullAtomUids.clear();
+    mPullAtomPackages.clear();
+    createAllLogSourcesFromConfig(config);
     return mConfigValid;
 }
 
-void MetricsManager::initLogSourceWhiteList() {
+void MetricsManager::createAllLogSourcesFromConfig(const StatsdConfig& config) {
+    // Init allowed pushed atom uids.
+    if (config.allowed_log_source_size() == 0) {
+        mConfigValid = false;
+        ALOGE("Log source allowlist is empty! This config won't get any data. Suggest adding at "
+              "least AID_SYSTEM and AID_STATSD to the allowed_log_source field.");
+    } else {
+        for (const auto& source : config.allowed_log_source()) {
+            auto it = UidMap::sAidToUidMapping.find(source);
+            if (it != UidMap::sAidToUidMapping.end()) {
+                mAllowedUid.push_back(it->second);
+            } else {
+                mAllowedPkg.push_back(source);
+            }
+        }
+
+        if (mAllowedUid.size() + mAllowedPkg.size() > StatsdStats::kMaxLogSourceCount) {
+            ALOGE("Too many log sources. This is likely to be an error in the config.");
+            mConfigValid = false;
+        } else {
+            initAllowedLogSources();
+        }
+    }
+
+    // Init default allowed pull atom uids.
+    int numPullPackages = 0;
+    for (const string& pullSource : config.default_pull_packages()) {
+        auto it = UidMap::sAidToUidMapping.find(pullSource);
+        if (it != UidMap::sAidToUidMapping.end()) {
+            numPullPackages++;
+            mDefaultPullUids.insert(it->second);
+        } else {
+            ALOGE("Default pull atom packages must be in sAidToUidMapping");
+            mConfigValid = false;
+        }
+    }
+    // Init per-atom pull atom packages.
+    for (const PullAtomPackages& pullAtomPackages : config.pull_atom_packages()) {
+        int32_t atomId = pullAtomPackages.atom_id();
+        for (const string& pullPackage : pullAtomPackages.packages()) {
+            numPullPackages++;
+            auto it = UidMap::sAidToUidMapping.find(pullPackage);
+            if (it != UidMap::sAidToUidMapping.end()) {
+                mPullAtomUids[atomId].insert(it->second);
+            } else {
+                mPullAtomPackages[atomId].insert(pullPackage);
+            }
+        }
+    }
+    if (numPullPackages > StatsdStats::kMaxPullAtomPackages) {
+        ALOGE("Too many sources in default_pull_packages and pull_atom_packages. This is likely to "
+              "be an error in the config");
+        mConfigValid = false;
+    } else {
+        initPullAtomSources();
+    }
+}
+
+void MetricsManager::initAllowedLogSources() {
     std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
     mAllowedLogSources.clear();
     mAllowedLogSources.insert(mAllowedUid.begin(), mAllowedUid.end());
@@ -288,7 +299,7 @@
     if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) {
         // We will re-initialize the whole list because we don't want to keep the multi mapping of
         // UID<->pkg inside MetricsManager to reduce the memory usage.
-        initLogSourceWhiteList();
+        initAllowedLogSources();
     }
 
     for (const auto& it : mPullAtomPackages) {
@@ -309,7 +320,7 @@
     if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) {
         // We will re-initialize the whole list because we don't want to keep the multi mapping of
         // UID<->pkg inside MetricsManager to reduce the memory usage.
-        initLogSourceWhiteList();
+        initAllowedLogSources();
     }
 
     for (const auto& it : mPullAtomPackages) {
@@ -329,7 +340,7 @@
     if (mAllowedPkg.size() == 0) {
         return;
     }
-    initLogSourceWhiteList();
+    initAllowedLogSources();
 }
 
 void MetricsManager::onStatsdInitCompleted(const int64_t& eventTimeNs) {
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 27f3d51..23048ae 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -285,10 +285,14 @@
 
     std::vector<int> mMetricIndexesWithActivation;
 
-    void initLogSourceWhiteList();
+    void initAllowedLogSources();
 
     void initPullAtomSources();
 
+    // Only called on config creation/update to initialize log sources from the config.
+    // Calls initAllowedLogSources and initPullAtomSources. Sets mConfigValid to false on error.
+    void createAllLogSourcesFromConfig(const StatsdConfig& config);
+
     // The metrics that don't need to be uploaded or even reported.
     std::set<int64_t> mNoReportMetricIds;
 
@@ -330,6 +334,7 @@
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 
     FRIEND_TEST(MetricsManagerTest, TestLogSources);
+    FRIEND_TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate);
 
     FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
     FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index 2dd774e..f05ec49 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <private/android_filesystem_config.h>
 #include <stdio.h>
@@ -92,8 +93,12 @@
     return config;
 }
 
-bool isSubset(const set<int32_t>& set1, const set<int32_t>& set2) {
-    return std::includes(set2.begin(), set2.end(), set1.begin(), set1.end());
+set<int32_t> unionSet(const vector<set<int32_t>> sets) {
+    set<int32_t> toRet;
+    for (const set<int32_t>& s : sets) {
+        toRet.insert(s.begin(), s.end());
+    }
+    return toRet;
 }
 }  // anonymous namespace
 
@@ -110,9 +115,7 @@
     pkgToUids[app2] = app2Uids;
     pkgToUids[app3] = app3Uids;
 
-    int32_t atom1 = 10;
-    int32_t atom2 = 20;
-    int32_t atom3 = 30;
+    int32_t atom1 = 10, atom2 = 20, atom3 = 30;
     sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
     EXPECT_CALL(*uidMap, getAppUid(_))
             .Times(4)
@@ -150,42 +153,115 @@
 
     MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
                                   pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
     EXPECT_TRUE(metricsManager.isConfigValid());
 
-    ASSERT_EQ(metricsManager.mAllowedUid.size(), 1);
-    EXPECT_EQ(metricsManager.mAllowedUid[0], AID_SYSTEM);
-
-    ASSERT_EQ(metricsManager.mAllowedPkg.size(), 1);
-    EXPECT_EQ(metricsManager.mAllowedPkg[0], app1);
-
-    ASSERT_EQ(metricsManager.mAllowedLogSources.size(), 3);
-    EXPECT_TRUE(isSubset({AID_SYSTEM}, metricsManager.mAllowedLogSources));
-    EXPECT_TRUE(isSubset(app1Uids, metricsManager.mAllowedLogSources));
-
-    ASSERT_EQ(metricsManager.mDefaultPullUids.size(), 2);
-    EXPECT_TRUE(isSubset(defaultPullUids, metricsManager.mDefaultPullUids));
-    ;
+    EXPECT_THAT(metricsManager.mAllowedUid, ElementsAre(AID_SYSTEM));
+    EXPECT_THAT(metricsManager.mAllowedPkg, ElementsAre(app1));
+    EXPECT_THAT(metricsManager.mAllowedLogSources,
+                ContainerEq(unionSet(vector<set<int32_t>>({app1Uids, {AID_SYSTEM}}))));
+    EXPECT_THAT(metricsManager.mDefaultPullUids, ContainerEq(defaultPullUids));
 
     vector<int32_t> atom1Uids = metricsManager.getPullAtomUids(atom1);
-    ASSERT_EQ(atom1Uids.size(), 5);
-    set<int32_t> expectedAtom1Uids;
-    expectedAtom1Uids.insert(defaultPullUids.begin(), defaultPullUids.end());
-    expectedAtom1Uids.insert(app1Uids.begin(), app1Uids.end());
-    expectedAtom1Uids.insert(app3Uids.begin(), app3Uids.end());
-    EXPECT_TRUE(isSubset(expectedAtom1Uids, set<int32_t>(atom1Uids.begin(), atom1Uids.end())));
+    EXPECT_THAT(atom1Uids,
+                UnorderedElementsAreArray(unionSet({defaultPullUids, app1Uids, app3Uids})));
 
     vector<int32_t> atom2Uids = metricsManager.getPullAtomUids(atom2);
-    ASSERT_EQ(atom2Uids.size(), 4);
-    set<int32_t> expectedAtom2Uids;
-    expectedAtom1Uids.insert(defaultPullUids.begin(), defaultPullUids.end());
-    expectedAtom1Uids.insert(app2Uids.begin(), app2Uids.end());
-    expectedAtom1Uids.insert(AID_STATSD);
-    EXPECT_TRUE(isSubset(expectedAtom2Uids, set<int32_t>(atom2Uids.begin(), atom2Uids.end())));
+    EXPECT_THAT(atom2Uids,
+                UnorderedElementsAreArray(unionSet({defaultPullUids, app2Uids, {AID_STATSD}})));
 
     vector<int32_t> atom3Uids = metricsManager.getPullAtomUids(atom3);
-    ASSERT_EQ(atom3Uids.size(), 2);
-    EXPECT_TRUE(isSubset(defaultPullUids, set<int32_t>(atom3Uids.begin(), atom3Uids.end())));
+    EXPECT_THAT(atom3Uids, UnorderedElementsAreArray(defaultPullUids));
+}
+
+TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate) {
+    string app1 = "app1";
+    set<int32_t> app1Uids = {1111, 11111};
+    string app2 = "app2";
+    set<int32_t> app2Uids = {2222};
+    string app3 = "app3";
+    set<int32_t> app3Uids = {3333, 1111};
+
+    map<string, set<int32_t>> pkgToUids;
+    pkgToUids[app1] = app1Uids;
+    pkgToUids[app2] = app2Uids;
+    pkgToUids[app3] = app3Uids;
+
+    int32_t atom1 = 10, atom2 = 20, atom3 = 30;
+    sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
+    EXPECT_CALL(*uidMap, getAppUid(_))
+            .Times(8)
+            .WillRepeatedly(Invoke([&pkgToUids](const string& pkg) {
+                const auto& it = pkgToUids.find(pkg);
+                if (it != pkgToUids.end()) {
+                    return it->second;
+                }
+                return set<int32_t>();
+            }));
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterPullUidProvider(kConfigKey, _)).Times(1);
+    EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey, _)).Times(1);
+
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
+
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_SYSTEM");
+    config.add_allowed_log_source(app1);
+    config.add_default_pull_packages("AID_SYSTEM");
+    config.add_default_pull_packages("AID_ROOT");
+
+    PullAtomPackages* pullAtomPackages = config.add_pull_atom_packages();
+    pullAtomPackages->set_atom_id(atom1);
+    pullAtomPackages->add_packages(app1);
+    pullAtomPackages->add_packages(app3);
+
+    pullAtomPackages = config.add_pull_atom_packages();
+    pullAtomPackages->set_atom_id(atom2);
+    pullAtomPackages->add_packages(app2);
+    pullAtomPackages->add_packages("AID_STATSD");
+
+    MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
+                                  pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
+    EXPECT_TRUE(metricsManager.isConfigValid());
+
+    // Update with new allowed log sources.
+    StatsdConfig newConfig;
+    newConfig.add_allowed_log_source("AID_ROOT");
+    newConfig.add_allowed_log_source(app2);
+    newConfig.add_default_pull_packages("AID_SYSTEM");
+    newConfig.add_default_pull_packages("AID_STATSD");
+
+    pullAtomPackages = newConfig.add_pull_atom_packages();
+    pullAtomPackages->set_atom_id(atom2);
+    pullAtomPackages->add_packages(app1);
+    pullAtomPackages->add_packages(app3);
+
+    pullAtomPackages = newConfig.add_pull_atom_packages();
+    pullAtomPackages->set_atom_id(atom3);
+    pullAtomPackages->add_packages(app2);
+    pullAtomPackages->add_packages("AID_ADB");
+
+    metricsManager.updateConfig(newConfig, timeBaseSec, timeBaseSec, anomalyAlarmMonitor,
+                                periodicAlarmMonitor);
+    EXPECT_TRUE(metricsManager.isConfigValid());
+
+    EXPECT_THAT(metricsManager.mAllowedUid, ElementsAre(AID_ROOT));
+    EXPECT_THAT(metricsManager.mAllowedPkg, ElementsAre(app2));
+    EXPECT_THAT(metricsManager.mAllowedLogSources,
+                ContainerEq(unionSet(vector<set<int32_t>>({app2Uids, {AID_ROOT}}))));
+    const set<int32_t> defaultPullUids = {AID_SYSTEM, AID_STATSD};
+    EXPECT_THAT(metricsManager.mDefaultPullUids, ContainerEq(defaultPullUids));
+
+    vector<int32_t> atom1Uids = metricsManager.getPullAtomUids(atom1);
+    EXPECT_THAT(atom1Uids, UnorderedElementsAreArray(defaultPullUids));
+
+    vector<int32_t> atom2Uids = metricsManager.getPullAtomUids(atom2);
+    EXPECT_THAT(atom2Uids,
+                UnorderedElementsAreArray(unionSet({defaultPullUids, app1Uids, app3Uids})));
+
+    vector<int32_t> atom3Uids = metricsManager.getPullAtomUids(atom3);
+    EXPECT_THAT(atom3Uids,
+                UnorderedElementsAreArray(unionSet({defaultPullUids, app2Uids, {AID_ADB}})));
 }
 
 TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
diff --git a/core/api/current.txt b/core/api/current.txt
index 0ec1531..a875df0b 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -31,6 +31,7 @@
     field @Deprecated public static final String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
     field @Deprecated public static final String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
+    field public static final String BIND_COMPANION_DEVICE_SERVICE = "android.permission.BIND_COMPANION_DEVICE_SERVICE";
     field public static final String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE";
     field public static final String BIND_CONTROLS = "android.permission.BIND_CONTROLS";
     field public static final String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
@@ -133,6 +134,7 @@
     field public static final String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
     field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO";
     field public static final String REORDER_TASKS = "android.permission.REORDER_TASKS";
+    field public static final String REQUEST_COMPANION_PROFILE_WATCH = "android.permission.REQUEST_COMPANION_PROFILE_WATCH";
     field public static final String REQUEST_COMPANION_RUN_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND";
     field public static final String REQUEST_COMPANION_USE_DATA_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND";
     field public static final String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
@@ -5528,6 +5530,7 @@
     field @Deprecated public static final String EXTRA_PEOPLE = "android.people";
     field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
     field public static final String EXTRA_PICTURE = "android.picture";
+    field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
     field public static final String EXTRA_PROGRESS = "android.progress";
     field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
     field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
@@ -5673,6 +5676,7 @@
     method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
     method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon);
     method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap);
+    method @NonNull public android.app.Notification.BigPictureStyle bigPictureContentDescription(@Nullable CharSequence);
     method public android.app.Notification.BigPictureStyle setBigContentTitle(CharSequence);
     method public android.app.Notification.BigPictureStyle setSummaryText(CharSequence);
   }
@@ -5972,6 +5976,7 @@
     method public long[] getVibrationPattern();
     method public boolean hasUserSetImportance();
     method public boolean hasUserSetSound();
+    method public boolean isConversation();
     method public boolean isDemoted();
     method public boolean isImportantConversation();
     method public void setAllowBubbles(boolean);
@@ -6138,6 +6143,7 @@
     method public android.content.IntentSender getIntentSender();
     method public static android.app.PendingIntent getService(android.content.Context, int, @NonNull android.content.Intent, int);
     method @Deprecated public String getTargetPackage();
+    method public boolean isImmutable();
     method @Nullable public static android.app.PendingIntent readPendingIntentOrNullFromParcel(@NonNull android.os.Parcel);
     method public void send() throws android.app.PendingIntent.CanceledException;
     method public void send(int) throws android.app.PendingIntent.CanceledException;
@@ -9430,14 +9436,16 @@
 
   public final class AssociationRequest implements android.os.Parcelable {
     method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
+    field public static final String DEVICE_PROFILE_WATCH = "android.app.role.COMPANION_DEVICE_WATCH";
   }
 
   public static final class AssociationRequest.Builder {
     ctor public AssociationRequest.Builder();
     method @NonNull public android.companion.AssociationRequest.Builder addDeviceFilter(@Nullable android.companion.DeviceFilter<?>);
     method @NonNull public android.companion.AssociationRequest build();
+    method @NonNull public android.companion.AssociationRequest.Builder setDeviceProfile(@NonNull String);
     method @NonNull public android.companion.AssociationRequest.Builder setSingleDevice(boolean);
   }
 
@@ -9487,6 +9495,14 @@
     method public abstract void onFailure(CharSequence);
   }
 
+  public abstract class CompanionDeviceService extends android.app.Service {
+    ctor public CompanionDeviceService();
+    method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method @MainThread public abstract void onDeviceAppeared(@NonNull String);
+    method @MainThread public abstract void onDeviceDisappeared(@NonNull String);
+    field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
+  }
+
   public interface DeviceFilter<D extends android.os.Parcelable> extends android.os.Parcelable {
   }
 
@@ -10679,8 +10695,6 @@
     field public static final String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
     field public static final String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
     field public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
-    field public static final String ACTION_PACKAGE_STARTABLE = "android.intent.action.PACKAGE_STARTABLE";
-    field public static final String ACTION_PACKAGE_UNSTARTABLE = "android.intent.action.PACKAGE_UNSTARTABLE";
     field public static final String ACTION_PACKAGE_VERIFIED = "android.intent.action.PACKAGE_VERIFIED";
     field public static final String ACTION_PASTE = "android.intent.action.PASTE";
     field public static final String ACTION_PICK = "android.intent.action.PICK";
@@ -12308,9 +12322,6 @@
     field public static final int SYNCHRONOUS = 2; // 0x2
     field @Nullable public static final java.util.List<java.security.cert.Certificate> TRUST_ALL;
     field @NonNull public static final java.util.List<java.security.cert.Certificate> TRUST_NONE;
-    field public static final int UNSTARTABLE_REASON_CONNECTION_ERROR = 1; // 0x1
-    field public static final int UNSTARTABLE_REASON_INSUFFICIENT_STORAGE = 2; // 0x2
-    field public static final int UNSTARTABLE_REASON_UNKNOWN = 0; // 0x0
     field public static final int VERIFICATION_ALLOW = 1; // 0x1
     field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
     field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
@@ -16421,6 +16432,7 @@
     method public float getGlyphBounds(@IntRange(from=0) int, @NonNull android.graphics.Paint, @Nullable android.graphics.RectF);
     method @NonNull public android.os.LocaleList getLocaleList();
     method public void getMetrics(@NonNull android.graphics.Paint, @Nullable android.graphics.Paint.FontMetrics);
+    method public int getSourceIdentifier();
     method @NonNull public android.graphics.fonts.FontStyle getStyle();
     method @IntRange(from=0) public int getTtcIndex();
   }
@@ -25270,6 +25282,7 @@
   public final class MediaCas implements java.lang.AutoCloseable {
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     ctor public MediaCas(@NonNull android.content.Context, int, @Nullable String, int) throws android.media.MediaCasException.UnsupportedCasException;
+    ctor public MediaCas(@NonNull android.content.Context, int, @Nullable String, int, @Nullable android.os.Handler, @Nullable android.media.MediaCas.EventListener) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
     method protected void finalize();
@@ -41263,6 +41276,11 @@
     field public static final int PURPOSE_SIGN = 4; // 0x4
     field public static final int PURPOSE_VERIFY = 8; // 0x8
     field public static final int PURPOSE_WRAP_KEY = 32; // 0x20
+    field public static final int SECURITY_LEVEL_SOFTWARE = 0; // 0x0
+    field public static final int SECURITY_LEVEL_STRONGBOX = 2; // 0x2
+    field public static final int SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1; // 0x1
+    field public static final int SECURITY_LEVEL_UNKNOWN = -2; // 0xfffffffe
+    field public static final int SECURITY_LEVEL_UNKNOWN_SECURE = -1; // 0xffffffff
     field public static final String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
     field public static final String SIGNATURE_PADDING_RSA_PSS = "PSS";
   }
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 06e6d9c..40ac3cd 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -89,10 +89,17 @@
     method public boolean dispatchMediaKeyEventToSessionAsSystemService(@NonNull android.view.KeyEvent, @NonNull android.media.session.MediaSession.Token);
     method public void dispatchVolumeKeyEventAsSystemService(@NonNull android.view.KeyEvent, int);
     method public void dispatchVolumeKeyEventToSessionAsSystemService(@NonNull android.view.KeyEvent, @NonNull android.media.session.MediaSession.Token);
+    method public void registerRemoteVolumeControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.RemoteVolumeControllerCallback);
+    method public void unregisterRemoteVolumeControllerCallback(@NonNull android.media.session.MediaSessionManager.RemoteVolumeControllerCallback);
     field public static final int RESULT_MEDIA_KEY_HANDLED = 1; // 0x1
     field public static final int RESULT_MEDIA_KEY_NOT_HANDLED = 0; // 0x0
   }
 
+  public static interface MediaSessionManager.RemoteVolumeControllerCallback {
+    method public void onSessionChanged(@Nullable android.media.session.MediaSession.Token);
+    method public void onVolumeChanged(@NonNull android.media.session.MediaSession.Token, int);
+  }
+
   public final class PlaybackState implements android.os.Parcelable {
     method public boolean isActiveState();
   }
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index b37f738..8b15ec3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -381,6 +381,7 @@
     field public static final String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
     field public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
     field public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
+    field public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn";
     field public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
     field public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
     field public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
@@ -4363,11 +4364,11 @@
   }
 
   public class MediaPlayer implements android.media.AudioRouting android.media.VolumeAutomation {
-    method @RequiresPermission("android.permission.BIND_IMS_SERVICE") public void setOnImsRxNoticeListener(@Nullable android.media.MediaPlayer.OnImsRxNoticeListener, @Nullable android.os.Handler);
+    method @RequiresPermission("android.permission.BIND_IMS_SERVICE") public void setOnRtpRxNoticeListener(@NonNull android.content.Context, @NonNull android.media.MediaPlayer.OnRtpRxNoticeListener, @Nullable android.os.Handler);
   }
 
-  public static interface MediaPlayer.OnImsRxNoticeListener {
-    method public void onImsRxNotice(@NonNull android.media.MediaPlayer, @NonNull byte[]);
+  public static interface MediaPlayer.OnRtpRxNoticeListener {
+    method public void onRtpRxNotice(@NonNull android.media.MediaPlayer, int, @NonNull int[]);
   }
 
   public final class MediaRecorder.AudioSource {
@@ -5030,6 +5031,7 @@
     field public static final int INVALID_AV_SYNC_ID = -1; // 0xffffffff
     field public static final int INVALID_FILTER_ID = -1; // 0xffffffff
     field public static final long INVALID_FILTER_ID_64BIT = -1L; // 0xffffffffffffffffL
+    field public static final int INVALID_FIRST_MACROBLOCK_IN_SLICE = -1; // 0xffffffff
     field public static final int INVALID_FRONTEND_SETTING_FREQUENCY = -1; // 0xffffffff
     field public static final int INVALID_LTS_ID = -1; // 0xffffffff
     field public static final int INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = -1; // 0xffffffff
@@ -5330,6 +5332,7 @@
 
   public class MmtpRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
     method public long getDataLength();
+    method public int getFirstMbInSlice();
     method public int getMpuSequenceNumber();
     method public long getPts();
     method public int getScHevcIndexMask();
@@ -5370,9 +5373,14 @@
     field public static final int SC_HEVC_INDEX_SLICE_TRAIL_CRA = 128; // 0x80
     field public static final int SC_HEVC_INDEX_SPS = 1; // 0x1
     field public static final int SC_INDEX_B_FRAME = 4; // 0x4
+    field public static final int SC_INDEX_B_SLICE = 64; // 0x40
     field public static final int SC_INDEX_I_FRAME = 1; // 0x1
+    field public static final int SC_INDEX_I_SLICE = 16; // 0x10
     field public static final int SC_INDEX_P_FRAME = 2; // 0x2
+    field public static final int SC_INDEX_P_SLICE = 32; // 0x20
     field public static final int SC_INDEX_SEQUENCE = 8; // 0x8
+    field public static final int SC_INDEX_SI_SLICE = 128; // 0x80
+    field public static final int SC_INDEX_SP_SLICE = 256; // 0x100
     field public static final int TS_INDEX_ADAPTATION_EXTENSION_FLAG = 4096; // 0x1000
     field public static final int TS_INDEX_CHANGE_TO_EVEN_SCRAMBLED = 8; // 0x8
     field public static final int TS_INDEX_CHANGE_TO_NOT_SCRAMBLED = 4; // 0x4
@@ -5493,6 +5501,7 @@
 
   public class TsRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
     method public long getDataLength();
+    method public int getFirstMbInSlice();
     method public int getPacketId();
     method public long getPts();
     method public int getScIndexMask();
@@ -5818,6 +5827,7 @@
   public class DvbsFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
     method @NonNull public static android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder builder();
     method @Nullable public android.media.tv.tuner.frontend.DvbsCodeRate getCodeRate();
+    method public boolean getCouldHandleDiseqcRxMessage();
     method public int getInputStreamId();
     method public int getModulation();
     method public int getPilot();
@@ -5827,7 +5837,6 @@
     method public int getSymbolRate();
     method public int getType();
     method public int getVcmMode();
-    method public boolean isDiseqcRxMessage();
     field public static final int MODULATION_AUTO = 1; // 0x1
     field public static final int MODULATION_MOD_128APSK = 2048; // 0x800
     field public static final int MODULATION_MOD_16APSK = 256; // 0x100
@@ -5871,7 +5880,7 @@
   public static class DvbsFrontendSettings.Builder {
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings build();
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setCodeRate(@Nullable android.media.tv.tuner.frontend.DvbsCodeRate);
-    method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setDiseqcRxMessage(boolean);
+    method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setCouldHandleDiseqcRxMessage(boolean);
     method @IntRange(from=1) @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setFrequency(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setInputStreamId(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setModulation(int);
@@ -6011,7 +6020,7 @@
   }
 
   public abstract class FrontendSettings {
-    method public int getEndFrequency();
+    method @IntRange(from=1) public int getEndFrequency();
     method public int getFrequency();
     method public int getFrontendSpectralInversion();
     method public abstract int getType();
@@ -6293,6 +6302,7 @@
   public interface ScanCallback {
     method public void onAnalogSifStandardReported(int);
     method public void onAtsc3PlpInfosReported(@NonNull android.media.tv.tuner.frontend.Atsc3PlpInfo[]);
+    method public default void onDvbcAnnexReported(int);
     method public void onDvbsStandardReported(int);
     method public void onDvbtStandardReported(int);
     method public void onFrequenciesReported(@NonNull int[]);
@@ -11179,6 +11189,17 @@
 
 package android.telephony.ims {
 
+  public final class AudioCodecAttributes implements android.os.Parcelable {
+    ctor public AudioCodecAttributes(float, @NonNull android.util.Range<java.lang.Float>, float, @NonNull android.util.Range<java.lang.Float>);
+    method public int describeContents();
+    method public float getBandwidthKhz();
+    method @NonNull public android.util.Range<java.lang.Float> getBandwidthRangeKhz();
+    method public float getBitrateKbps();
+    method @NonNull public android.util.Range<java.lang.Float> getBitrateRangeKbps();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.AudioCodecAttributes> CREATOR;
+  }
+
   public final class ImsCallForwardInfo implements android.os.Parcelable {
     ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
     method public int describeContents();
@@ -11208,6 +11229,7 @@
     ctor public ImsCallProfile(int, int);
     ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
     method public int describeContents();
+    method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes();
     method public String getCallExtra(String);
     method public String getCallExtra(String, String);
     method public boolean getCallExtraBoolean(String);
@@ -11222,6 +11244,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes();
     method @NonNull public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
@@ -11232,6 +11255,7 @@
     method public boolean isVideoCall();
     method public boolean isVideoPaused();
     method public static int presentationToOir(int);
+    method public void setAcceptedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
     method public void setCallExtra(String, String);
     method public void setCallExtraBoolean(String, boolean);
     method public void setCallExtraInt(String, int);
@@ -11242,6 +11266,7 @@
     method public void setEmergencyServiceCategories(int);
     method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
     method public void setHasKnownUserIntentEmergency(boolean);
+    method public void setOfferedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
     method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
     method public void updateCallType(android.telephony.ims.ImsCallProfile);
     method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
@@ -11301,6 +11326,7 @@
     method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
     method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
+    method public void callSessionDtmfReceived(char);
     method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
     method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
     method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
@@ -11321,6 +11347,7 @@
     method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
     method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
     method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
+    method public void callSessionRtpHeaderExtensionsReceived(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
     method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
     method public void callSessionRttMessageReceived(String);
     method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
@@ -11547,6 +11574,7 @@
     ctor public ImsStreamMediaProfile(int, int, int, int, int);
     method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
     method public int describeContents();
+    method @Nullable public android.telephony.ims.AudioCodecAttributes getAudioCodecAttributes();
     method public int getAudioDirection();
     method public int getAudioQuality();
     method public int getRttMode();
@@ -11554,6 +11582,7 @@
     method public int getVideoQuality();
     method public boolean isReceivingRttAudio();
     method public boolean isRttCall();
+    method public void setAudioCodecAttributes(@NonNull android.telephony.ims.AudioCodecAttributes);
     method public void setReceivingRttAudio(boolean);
     method public void setRttMode(int);
     method public void writeToParcel(android.os.Parcel, int);
@@ -11675,6 +11704,24 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
   }
 
+  public final class RtpHeaderExtension implements android.os.Parcelable {
+    ctor public RtpHeaderExtension(@IntRange(from=1, to=14) int, @NonNull byte[]);
+    method public int describeContents();
+    method @NonNull public byte[] getExtensionData();
+    method @IntRange(from=1, to=14) public int getLocalIdentifier();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtension> CREATOR;
+  }
+
+  public final class RtpHeaderExtensionType implements android.os.Parcelable {
+    ctor public RtpHeaderExtensionType(@IntRange(from=1, to=14) int, @NonNull android.net.Uri);
+    method public int describeContents();
+    method @IntRange(from=1, to=14) public int getLocalIdentifier();
+    method @NonNull public android.net.Uri getUri();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtensionType> CREATOR;
+  }
+
   public class SipDelegateManager {
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSupported() throws android.telephony.ims.ImsException;
   }
@@ -11791,6 +11838,7 @@
     method public void removeParticipants(String[]);
     method public void resume(android.telephony.ims.ImsStreamMediaProfile);
     method public void sendDtmf(char, android.os.Message);
+    method public void sendRtpHeaderExtensions(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
     method public void sendRttMessage(String);
     method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
     method public void sendRttModifyResponse(boolean);
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index 4db55e7..a3fb06c 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -6,7 +6,8 @@
 BuilderSetStyle: android.net.IpSecTransform.Builder#buildTunnelModeTransform(java.net.InetAddress, android.net.IpSecManager.SecurityParameterIndex):
     Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTunnelModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex)
 
-ExecutorRegistration: android.media.MediaPlayer#setOnImsRxNoticeListener(android.media.MediaPlayer.OnImsRxNoticeListener, android.os.Handler):
+ExecutorRegistration: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
+    Registration methods should have overload that accepts delivery Executor: `setOnRtpRxNoticeListener`
     
 GenericException: android.app.prediction.AppPredictor#finalize():
     
@@ -182,7 +183,8 @@
     
 SamShouldBeLast: android.media.AudioRouting#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
     
-SamShouldBeLast: android.media.MediaPlayer#setOnImsRxNoticeListener(android.media.MediaPlayer.OnImsRxNoticeListener, android.os.Handler):
+SamShouldBeLast: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
+    SAM-compatible parameters (such as parameter 2, "listener", in android.media.MediaPlayer.setOnRtpRxNoticeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
     
 SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
     
diff --git a/api/test-current.txt b/core/api/test-current.txt
similarity index 100%
rename from api/test-current.txt
rename to core/api/test-current.txt
diff --git a/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
similarity index 100%
rename from api/test-lint-baseline.txt
rename to core/api/test-lint-baseline.txt
diff --git a/api/test-removed.txt b/core/api/test-removed.txt
similarity index 100%
rename from api/test-removed.txt
rename to core/api/test-removed.txt
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 2ac345d..75ffb280 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -77,6 +77,7 @@
 import android.os.Looper;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
+import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager.ServiceNotFoundException;
@@ -5814,7 +5815,7 @@
                 intent.migrateExtraStreamToClipData(this);
                 intent.prepareToLeaveProcess(this);
                 result = ActivityTaskManager.getService()
-                    .startActivity(mMainThread.getApplicationThread(), getBasePackageName(),
+                    .startActivity(mMainThread.getApplicationThread(), getOpPackageName(),
                             getAttributionTag(), intent,
                             intent.resolveTypeIfNeeded(getContentResolver()), mToken, mEmbeddedID,
                             requestCode, ActivityManager.START_FLAG_ONLY_IF_NEEDED, null, options);
@@ -8722,13 +8723,16 @@
      * the activity is visible after the screen is turned on when the lockscreen is up. In addition,
      * if this flag is set and the activity calls {@link
      * KeyguardManager#requestDismissKeyguard(Activity, KeyguardManager.KeyguardDismissCallback)}
-     * the screen will turn on.
+     * the screen will turn on. If the screen is off and device is not secured, this flag can turn
+     * screen on and dismiss keyguard to make this activity visible and resume, which can be used to
+     * replace {@link PowerManager#ACQUIRE_CAUSES_WAKEUP}
      *
      * @param turnScreenOn {@code true} to turn on the screen; {@code false} otherwise.
      *
      * @see #setShowWhenLocked(boolean)
      * @see android.R.attr#turnScreenOn
      * @see android.R.attr#showWhenLocked
+     * @see KeyguardManager#isDeviceSecure()
      */
     public void setTurnScreenOn(boolean turnScreenOn) {
         try {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index ec287fe..bd51fc5 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import static android.app.WindowConfiguration.activityTypeToString;
+import static android.app.WindowConfiguration.windowingModeToString;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
 
@@ -1693,6 +1695,13 @@
         @Deprecated
         public int affiliatedTaskId;
 
+        /**
+         * Information of organized child tasks.
+         *
+         * @hide
+         */
+        public ArrayList<RecentTaskInfo> childrenTaskInfos = new ArrayList<>();
+
         public RecentTaskInfo() {
         }
 
@@ -1708,6 +1717,7 @@
         public void readFromParcel(Parcel source) {
             id = source.readInt();
             persistentId = source.readInt();
+            childrenTaskInfos = source.readArrayList(RecentTaskInfo.class.getClassLoader());
             super.readFromParcel(source);
         }
 
@@ -1715,6 +1725,7 @@
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(id);
             dest.writeInt(persistentId);
+            dest.writeList(childrenTaskInfos);
             super.writeToParcel(dest, flags);
         }
 
@@ -1732,11 +1743,6 @@
          * @hide
          */
         public void dump(PrintWriter pw, String indent) {
-            final String activityType = WindowConfiguration.activityTypeToString(
-                    configuration.windowConfiguration.getActivityType());
-            final String windowingMode = WindowConfiguration.activityTypeToString(
-                    configuration.windowConfiguration.getActivityType());
-
             pw.println(); pw.print("   ");
             pw.print(" id="); pw.print(persistentId);
             pw.print(" stackId="); pw.print(stackId);
@@ -1762,8 +1768,8 @@
             pw.print("   ");
             pw.print(" isExcluded=");
             pw.print(((baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0));
-            pw.print(" activityType="); pw.print(activityType);
-            pw.print(" windowingMode="); pw.print(windowingMode);
+            pw.print(" activityType="); pw.print(activityTypeToString(getActivityType()));
+            pw.print(" windowingMode="); pw.print(windowingModeToString(getWindowingMode()));
             pw.print(" supportsSplitScreenMultiWindow=");
             pw.println(supportsSplitScreenMultiWindow);
             if (taskDescription != null) {
@@ -1930,7 +1936,7 @@
         ArrayList<AppTask> tasks = new ArrayList<AppTask>();
         List<IBinder> appTasks;
         try {
-            appTasks = getTaskService().getAppTasks(mContext.getPackageName());
+            appTasks = getTaskService().getAppTasks(mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2465,7 +2471,7 @@
         try {
             ActivityThread thread = ActivityThread.currentActivityThread();
             IApplicationThread appThread = thread.getApplicationThread();
-            String packageName = mContext.getPackageName();
+            String packageName = mContext.getOpPackageName();
             getTaskService().moveTaskToFront(appThread, packageName, taskId, flags, options);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b681947..b292094 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -186,6 +186,7 @@
 import com.android.org.conscrypt.TrustedCertificateStore;
 import com.android.server.am.MemInfoDumpProto;
 
+import dalvik.system.AppSpecializationHooks;
 import dalvik.system.CloseGuard;
 import dalvik.system.VMDebug;
 import dalvik.system.VMRuntime;
@@ -6309,6 +6310,9 @@
         Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
 
         AppCompatCallbacks.install(data.disabledCompatChanges);
+        // Let libcore handle any compat changes after installing the list of compat changes.
+        AppSpecializationHooks.handleCompatChangesBeforeBindingApplication();
+
         mBoundApplication = data;
         mConfiguration = new Configuration(data.config);
         mCompatConfiguration = new Configuration(data.config);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index e20ef7f..26b4234 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -31,6 +31,7 @@
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -52,6 +53,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.LongSparseArray;
@@ -1462,6 +1464,7 @@
     @SystemApi
     public static final String OPSTR_INTERACT_ACROSS_PROFILES = "android:interact_across_profiles";
     /** @hide Start Platform VPN without user intervention */
+    @SystemApi
     public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn";
     /** @hide */
     @SystemApi
@@ -7590,8 +7593,9 @@
                     collectNotedOpForSelf(op, proxiedAttributionTag);
                 } else if (collectionMode == COLLECT_SYNC
                         // Only collect app-ops when the proxy is trusted
-                        && mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
-                        myUid) == PackageManager.PERMISSION_GRANTED) {
+                        && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
+                        myUid) == PackageManager.PERMISSION_GRANTED
+                        || isTrustedVoiceServiceProxy(mContext.getOpPackageName(), op))) {
                     collectNotedOpSync(op, proxiedAttributionTag);
                 }
             }
@@ -7602,6 +7606,28 @@
         }
     }
 
+    private boolean isTrustedVoiceServiceProxy(String packageName, int code) {
+        // This is a workaround for R QPR, new API change is not allowed. We only allow the current
+        // voice recognizer is also the voice interactor to noteproxy op.
+        if (code != OP_RECORD_AUDIO) {
+            return false;
+        }
+        final String voiceRecognitionComponent = Settings.Secure.getString(
+                mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE);
+        final String voiceInteractionComponent = Settings.Secure.getString(
+                mContext.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE);
+
+        final String voiceRecognitionServicePackageName =
+                voiceRecognitionComponent != null ? ComponentName.unflattenFromString(
+                        voiceRecognitionComponent).getPackageName() : "";
+        final String voiceInteractionServicePackageName =
+                voiceInteractionComponent != null ? ComponentName.unflattenFromString(
+                        voiceInteractionComponent).getPackageName() : "";
+
+        return Objects.equals(packageName, voiceRecognitionServicePackageName) && Objects.equals(
+                voiceRecognitionServicePackageName, voiceInteractionServicePackageName);
+    }
+
     /**
      * Do a quick check for whether an application might be able to perform an operation.
      * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
diff --git a/core/java/android/app/AsyncNotedAppOp.java b/core/java/android/app/AsyncNotedAppOp.java
index b0c2762c..db58c21 100644
--- a/core/java/android/app/AsyncNotedAppOp.java
+++ b/core/java/android/app/AsyncNotedAppOp.java
@@ -72,7 +72,7 @@
 
 
 
-    // Code below generated by codegen v1.0.15.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -261,10 +261,10 @@
     };
 
     @DataClass.Generated(
-            time = 1583866239013L,
-            codegenVersion = "1.0.15",
+            time = 1604456255752L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/core/java/android/app/AsyncNotedAppOp.java",
-            inputSignatures = "private final @android.annotation.IntRange(from=0L) int mOpCode\nprivate final @android.annotation.IntRange(from=0L) int mNotingUid\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.annotation.CurrentTimeMillisLong long mTime\npublic @android.annotation.NonNull java.lang.String getOp()\nprivate  void onConstructed()\nclass AsyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genHiddenConstructor=true)")
+            inputSignatures = "private final @android.annotation.IntRange int mOpCode\nprivate final @android.annotation.IntRange int mNotingUid\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.annotation.CurrentTimeMillisLong long mTime\npublic @android.annotation.NonNull java.lang.String getOp()\nprivate  void onConstructed()\nclass AsyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genHiddenConstructor=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 5c3be31..9727a28 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1039,7 +1039,7 @@
     public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
         try {
             ActivityTaskManager.getService().startActivityAsUser(
-                    mMainThread.getApplicationThread(), getBasePackageName(), getAttributionTag(),
+                    mMainThread.getApplicationThread(), getOpPackageName(), getAttributionTag(),
                     intent, intent.resolveTypeIfNeeded(getContentResolver()),
                     null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options,
                     user.getIdentifier());
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 879d437..560b5be 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -342,6 +342,7 @@
     @UnsupportedAppUsage
     void unregisterProcessObserver(in IProcessObserver observer);
     boolean isIntentSenderTargetedToPackage(in IIntentSender sender);
+    boolean isIntentSenderImmutable(in IIntentSender sender);
     @UnsupportedAppUsage
     void updatePersistentConfiguration(in Configuration values);
     void updatePersistentConfigurationWithAttribution(in Configuration values,
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index d798f22..a8ce73d 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -96,6 +96,8 @@
     NotificationChannelGroup getPopulatedNotificationChannelGroupForPackage(String pkg, int uid, String groupId, boolean includeDeleted);
     void updateNotificationChannelGroupForPackage(String pkg, int uid, in NotificationChannelGroup group);
     void updateNotificationChannelForPackage(String pkg, int uid, in NotificationChannel channel);
+    void unlockNotificationChannel(String pkg, int uid, String channelId);
+    void unlockAllNotificationChannels();
     NotificationChannel getNotificationChannel(String callingPkg, int userId, String pkg, String channelId);
     NotificationChannel getConversationNotificationChannel(String callingPkg, int userId, String pkg, String channelId, boolean returnParentIfNoConversationChannel, String conversationId);
     void createConversationNotificationChannelForPackage(String pkg, int uid, in NotificationChannel parentChannel, String conversationId);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 9e96795..3e249bb 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1725,7 +1725,7 @@
             intent.migrateExtraStreamToClipData(who);
             intent.prepareToLeaveProcess(who);
             int result = ActivityTaskManager.getService().startActivity(whoThread,
-                    who.getBasePackageName(), who.getAttributionTag(), intent,
+                    who.getOpPackageName(), who.getAttributionTag(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                     target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
             checkStartActivityResult(result, intent);
@@ -1797,7 +1797,7 @@
                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
             }
             int result = ActivityTaskManager.getService().startActivities(whoThread,
-                    who.getBasePackageName(), who.getAttributionTag(), intents, resolvedTypes,
+                    who.getOpPackageName(), who.getAttributionTag(), intents, resolvedTypes,
                     token, options, userId);
             checkStartActivityResult(result, intents[0]);
             return result;
@@ -1864,7 +1864,7 @@
             intent.migrateExtraStreamToClipData(who);
             intent.prepareToLeaveProcess(who);
             int result = ActivityTaskManager.getService().startActivity(whoThread,
-                    who.getBasePackageName(), who.getAttributionTag(), intent,
+                    who.getOpPackageName(), who.getAttributionTag(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()), token, target,
                     requestCode, 0, null, options);
             checkStartActivityResult(result, intent);
@@ -1931,7 +1931,7 @@
             intent.migrateExtraStreamToClipData(who);
             intent.prepareToLeaveProcess(who);
             int result = ActivityTaskManager.getService().startActivityAsUser(whoThread,
-                    who.getBasePackageName(), who.getAttributionTag(), intent,
+                    who.getOpPackageName(), who.getAttributionTag(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()), token, resultWho,
                     requestCode, 0, null, options, user.getIdentifier());
             checkStartActivityResult(result, intent);
@@ -1977,11 +1977,11 @@
             intent.migrateExtraStreamToClipData(who);
             intent.prepareToLeaveProcess(who);
             int result = ActivityTaskManager.getService()
-                .startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
-                        intent.resolveTypeIfNeeded(who.getContentResolver()),
-                        token, target != null ? target.mEmbeddedID : null,
-                        requestCode, 0, null, options, permissionToken,
-                        ignoreTargetSecurity, userId);
+                    .startActivityAsCaller(whoThread, who.getOpPackageName(), intent,
+                            intent.resolveTypeIfNeeded(who.getContentResolver()),
+                            token, target != null ? target.mEmbeddedID : null,
+                            requestCode, 0, null, options, permissionToken,
+                            ignoreTargetSecurity, userId);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
@@ -2023,7 +2023,7 @@
         try {
             intent.migrateExtraStreamToClipData(who);
             intent.prepareToLeaveProcess(who);
-            int result = appTask.startActivity(whoThread.asBinder(), who.getBasePackageName(),
+            int result = appTask.startActivity(whoThread.asBinder(), who.getOpPackageName(),
                     who.getAttributionTag(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()), options);
             checkStartActivityResult(result, intent);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index b609462..4eef616 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -286,7 +286,7 @@
         return mSecurityViolation;
     }
 
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @UnsupportedAppUsage(trackingBug = 172409979)
     public CompatibilityInfo getCompatibilityInfo() {
         return mDisplayAdjustments.getCompatibilityInfo();
     }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a1abe3d..8cafaa8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1147,6 +1147,14 @@
     public static final String EXTRA_PICTURE = "android.picture";
 
     /**
+     * {@link #extras} key: this is a content description of the big picture supplied from
+     * {@link BigPictureStyle#bigPicture(Bitmap)}, supplied to
+     * {@link BigPictureStyle#bigPictureContentDescription(CharSequence)}.
+     */
+    public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION =
+            "android.pictureContentDescription";
+
+    /**
      * {@link #extras} key: An array of CharSequences to show in {@link InboxStyle} expanded
      * notifications, each of which was supplied to {@link InboxStyle#addLine(CharSequence)}.
      */
@@ -6728,6 +6736,7 @@
         private Bitmap mPicture;
         private Icon mBigLargeIcon;
         private boolean mBigLargeIconSet = false;
+        private CharSequence mPictureContentDescription;
 
         public BigPictureStyle() {
         }
@@ -6758,6 +6767,16 @@
         }
 
         /**
+         * Set the content description of the big picture.
+         */
+        @NonNull
+        public BigPictureStyle bigPictureContentDescription(
+                @Nullable CharSequence contentDescription) {
+            mPictureContentDescription = contentDescription;
+            return this;
+        }
+
+        /**
          * @hide
          */
         public Bitmap getBigPicture() {
@@ -6870,6 +6889,11 @@
             }
 
             contentView.setImageViewBitmap(R.id.big_picture, mPicture);
+
+            if (mPictureContentDescription != null) {
+                contentView.setContentDescription(R.id.big_picture, mPictureContentDescription);
+            }
+
             return contentView;
         }
 
@@ -6882,6 +6906,10 @@
             if (mBigLargeIconSet) {
                 extras.putParcelable(EXTRA_LARGE_ICON_BIG, mBigLargeIcon);
             }
+            if (mPictureContentDescription != null) {
+                extras.putCharSequence(EXTRA_PICTURE_CONTENT_DESCRIPTION,
+                        mPictureContentDescription);
+            }
             extras.putParcelable(EXTRA_PICTURE, mPicture);
         }
 
@@ -6896,6 +6924,12 @@
                 mBigLargeIconSet = true;
                 mBigLargeIcon = extras.getParcelable(EXTRA_LARGE_ICON_BIG);
             }
+
+            if (extras.containsKey(EXTRA_PICTURE_CONTENT_DESCRIPTION)) {
+                mPictureContentDescription =
+                        extras.getCharSequence(EXTRA_PICTURE_CONTENT_DESCRIPTION);
+            }
+
             mPicture = extras.getParcelable(EXTRA_PICTURE);
         }
 
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index a06ffbd..080aac9 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -629,12 +629,20 @@
     }
 
     /**
+     * Whether or not this channel represents a conversation.
+     */
+    public boolean isConversation() {
+        return !TextUtils.isEmpty(getConversationId());
+    }
+
+
+    /**
      * Whether or not notifications in this conversation are considered important.
      *
      * <p>Important conversations may get special visual treatment, and might be able to bypass DND.
      *
-     * <p>This is only valid for channels that represent conversations, that is, those with a valid
-     * {@link #getConversationId() conversation id}.
+     * <p>This is only valid for channels that represent conversations, that is,
+     * where {@link #isConversation()} is true.
      */
     public boolean isImportantConversation() {
         return mImportantConvo;
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 21dfbbd..f76a757 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -1145,6 +1145,18 @@
     }
 
     /**
+     * Check if this PendingIntent is marked with {@link #FLAG_IMMUTABLE}.
+     */
+    public boolean isImmutable() {
+        try {
+            return ActivityManager.getService()
+                    .isIntentSenderImmutable(mTarget);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * @hide
      * Check whether this PendingIntent will launch an Activity.
      */
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 43b7722c..5dfab6e 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -257,6 +257,18 @@
     }
 
     /** @hide */
+    @WindowConfiguration.WindowingMode
+    public int getWindowingMode() {
+        return configuration.windowConfiguration.getWindowingMode();
+    }
+
+    /** @hide */
+    @WindowConfiguration.ActivityType
+    public int getActivityType() {
+        return configuration.windowConfiguration.getActivityType();
+    }
+
+    /** @hide */
     public void addLaunchCookie(IBinder cookie) {
         if (cookie == null || launchCookies.contains(cookie)) return;
         launchCookies.add(cookie);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 224e3a8..1d644c4 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -525,7 +525,7 @@
      * @hide
      */
     public static final String ACTION_REMOTE_BUGREPORT_DISPATCH =
-            "com.android.server.action.REMOTE_BUGREPORT_DISPATCH";
+            "android.intent.action.REMOTE_BUGREPORT_DISPATCH";
 
     /**
      * Extra for shared bugreport's SHA-256 hash.
@@ -4271,6 +4271,9 @@
      * This method can be called on the {@link DevicePolicyManager} instance returned by
      * {@link #getParentProfileInstance(ComponentName)} in order to lock the parent profile.
      * <p>
+     * NOTE: on {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds}, this
+     * method doesn't turn off the screen as it would be a driving safety distraction.
+     * <p>
      * Equivalent to calling {@link #lockNow(int)} with no flags.
      *
      * @throws SecurityException if the calling application does not own an active administrator
@@ -4314,6 +4317,9 @@
      * Calling the method twice in this order ensures that all users are locked and does not
      * stop the device admin on the managed profile from issuing a second call to lock its own
      * profile.
+     * <p>
+     * NOTE: on {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds}, this
+     * method doesn't turn off the screen as it would be a driving safety distraction.
      *
      * @param flags May be 0 or {@link #FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY}.
      * @throws SecurityException if the calling application does not own an active administrator
@@ -6990,7 +6996,7 @@
         throwIfParentInstance("isProfileOwnerApp");
         if (mService != null) {
             try {
-                ComponentName profileOwner = mService.getProfileOwner(myUserId());
+                ComponentName profileOwner = mService.getProfileOwnerAsUser(myUserId());
                 return profileOwner != null
                         && profileOwner.getPackageName().equals(packageName);
             } catch (RemoteException re) {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 60dce22..f4105e9 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -156,7 +156,6 @@
 
     boolean setProfileOwner(in ComponentName who, String ownerName, int userHandle);
     ComponentName getProfileOwnerAsUser(int userHandle);
-    ComponentName getProfileOwner(int userHandle);
     ComponentName getProfileOwnerOrDeviceOwnerSupervisionComponent(in UserHandle userHandle);
     String getProfileOwnerName(int userHandle);
     void setProfileEnabled(in ComponentName who);
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 0531359..44a4b78 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -21,10 +21,14 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -435,6 +439,17 @@
         return false;
     }
 
+
+    /**
+     * If this change is enabled, the {@code BACKUP} permission needed for
+     * {@code isBackupServiceActive()} will be enforced on the service end
+     * rather than client-side in {@link BackupManager}.
+     * @hide
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
+    public static final long IS_BACKUP_SERVICE_ACTIVE_ENFORCE_PERMISSION_IN_SERVICE = 158482162;
+
     /**
      * Report whether the backup mechanism is currently active.
      * When it is inactive, the device will not perform any backup operations, nor will it
@@ -445,8 +460,11 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.BACKUP)
     public boolean isBackupServiceActive(UserHandle user) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
-                "isBackupServiceActive");
+        if (!CompatChanges.isChangeEnabled(
+                IS_BACKUP_SERVICE_ACTIVE_ENFORCE_PERMISSION_IN_SERVICE)) {
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                    "isBackupServiceActive");
+        }
         checkServiceBinder();
         if (sService != null) {
             try {
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index 8170bf9..57b0828 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -16,8 +16,11 @@
 
 package android.companion;
 
+import static com.android.internal.util.CollectionUtils.emptyIfNull;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringDef;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
@@ -25,7 +28,7 @@
 import android.provider.OneTimeUseBuilder;
 
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.CollectionUtils;
+import com.android.internal.util.DataClass;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -43,23 +46,66 @@
  * You can also set {@link Builder#setSingleDevice single device} to request a popup with single
  * device to be shown instead of a list to choose from
  */
+@DataClass(
+        genToString = true,
+        genEqualsHashCode = true,
+        genHiddenGetters = true,
+        genParcelable = true,
+        genHiddenConstructor = true,
+        genBuilder = false)
 public final class AssociationRequest implements Parcelable {
 
-    private final boolean mSingleDevice;
-    private final List<DeviceFilter<?>> mDeviceFilters;
-    private String mCallingPackage;
+    /**
+     * Device profile: watch.
+     *
+     * @see AssociationRequest.Builder#setDeviceProfile
+     */
+    public static final String DEVICE_PROFILE_WATCH =
+            "android.app.role.COMPANION_DEVICE_WATCH";
 
-    private AssociationRequest(
-            boolean singleDevice, @Nullable List<DeviceFilter<?>> deviceFilters) {
-        this.mSingleDevice = singleDevice;
-        this.mDeviceFilters = CollectionUtils.emptyIfNull(deviceFilters);
+    /** @hide */
+    @StringDef(value = { DEVICE_PROFILE_WATCH })
+    public @interface DeviceProfile {}
+
+    /**
+     * Whether only a single device should match the provided filter.
+     *
+     * When scanning for a single device with a specifc {@link BluetoothDeviceFilter} mac
+     * address, bonded devices are also searched among. This allows to obtain the necessary app
+     * privileges even if the device is already paired.
+     */
+    private boolean mSingleDevice = false;
+
+    /**
+     * If set, only devices matching either of the given filters will be shown to the user
+     */
+    @DataClass.PluralOf("deviceFilter")
+    private @NonNull List<DeviceFilter<?>> mDeviceFilters = new ArrayList<>();
+
+    /**
+     * If set, association will be requested as a corresponding kind of device
+     */
+    private @Nullable @DeviceProfile String mDeviceProfile = null;
+
+    /**
+     * The app package making the request.
+     *
+     * Populated by the system.
+     *
+     * @hide
+     */
+    private @Nullable String mCallingPackage = null;
+
+    /** @hide */
+    public void setCallingPackage(@NonNull String pkg) {
+        mCallingPackage = pkg;
     }
 
-    private AssociationRequest(Parcel in) {
-        this(
-            in.readByte() != 0,
-            in.readParcelableList(new ArrayList<>(), AssociationRequest.class.getClassLoader()));
-        setCallingPackage(in.readString());
+    private void onConstructed() {
+        if (mDeviceProfile != null
+                && !Objects.equals(mDeviceProfile, DEVICE_PROFILE_WATCH)) {
+            throw new IllegalArgumentException("Invalid device profile: " + mDeviceProfile);
+        }
     }
 
     /** @hide */
@@ -75,70 +121,13 @@
         return mDeviceFilters;
     }
 
-    /** @hide */
-    public String getCallingPackage() {
-        return mCallingPackage;
-    }
-
-    /** @hide */
-    public void setCallingPackage(String pkg) {
-        mCallingPackage = pkg;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        AssociationRequest that = (AssociationRequest) o;
-        return mSingleDevice == that.mSingleDevice
-                && Objects.equals(mDeviceFilters, that.mDeviceFilters)
-                && Objects.equals(mCallingPackage, that.mCallingPackage);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mSingleDevice, mDeviceFilters, mCallingPackage);
-    }
-
-    @Override
-    public String toString() {
-        return "AssociationRequest{"
-                + "mSingleDevice=" + mSingleDevice
-                + ", mDeviceFilters=" + mDeviceFilters
-                + ", mCallingPackage=" + mCallingPackage
-                + '}';
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeByte((byte) (mSingleDevice ? 1 : 0));
-        dest.writeParcelableList(mDeviceFilters, flags);
-        dest.writeString(mCallingPackage);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @android.annotation.NonNull Creator<AssociationRequest> CREATOR = new Creator<AssociationRequest>() {
-        @Override
-        public AssociationRequest createFromParcel(Parcel in) {
-            return new AssociationRequest(in);
-        }
-
-        @Override
-        public AssociationRequest[] newArray(int size) {
-            return new AssociationRequest[size];
-        }
-    };
-
     /**
      * A builder for {@link AssociationRequest}
      */
     public static final class Builder extends OneTimeUseBuilder<AssociationRequest> {
         private boolean mSingleDevice = false;
         @Nullable private ArrayList<DeviceFilter<?>> mDeviceFilters = null;
+        private @Nullable String mDeviceProfile = null;
 
         public Builder() {}
 
@@ -172,12 +161,219 @@
             return this;
         }
 
+        /**
+         * If set, association will be requested as a corresponding kind of device
+         */
+        @NonNull
+        public Builder setDeviceProfile(@NonNull @DeviceProfile String deviceProfile) {
+            checkNotUsed();
+            mDeviceProfile = deviceProfile;
+            return this;
+        }
+
         /** @inheritDoc */
         @NonNull
         @Override
         public AssociationRequest build() {
             markUsed();
-            return new AssociationRequest(mSingleDevice, mDeviceFilters);
+            return new AssociationRequest(
+                    mSingleDevice, emptyIfNull(mDeviceFilters),
+                    mDeviceProfile, null);
         }
     }
+
+
+
+
+    // Code below generated by codegen v1.0.20.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/companion/AssociationRequest.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /**
+     * Creates a new AssociationRequest.
+     *
+     * @param singleDevice
+     *   Whether only a single device should match the provided filter.
+     *
+     *   When scanning for a single device with a specifc {@link BluetoothDeviceFilter} mac
+     *   address, bonded devices are also searched among. This allows to obtain the necessary app
+     *   privileges even if the device is already paired.
+     * @param deviceFilters
+     *   If set, only devices matching either of the given filters will be shown to the user
+     * @param deviceProfile
+     *   If set, association will be requested as a corresponding kind of device
+     * @param callingPackage
+     *   The app package making the request.
+     *
+     *   Populated by the system.
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public AssociationRequest(
+            boolean singleDevice,
+            @NonNull List<DeviceFilter<?>> deviceFilters,
+            @Nullable @DeviceProfile String deviceProfile,
+            @Nullable String callingPackage) {
+        this.mSingleDevice = singleDevice;
+        this.mDeviceFilters = deviceFilters;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mDeviceFilters);
+        this.mDeviceProfile = deviceProfile;
+        com.android.internal.util.AnnotationValidations.validate(
+                DeviceProfile.class, null, mDeviceProfile);
+        this.mCallingPackage = callingPackage;
+
+        onConstructed();
+    }
+
+    /**
+     * If set, association will be requested as a corresponding kind of device
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public @Nullable @DeviceProfile String getDeviceProfile() {
+        return mDeviceProfile;
+    }
+
+    /**
+     * The app package making the request.
+     *
+     * Populated by the system.
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public @Nullable String getCallingPackage() {
+        return mCallingPackage;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "AssociationRequest { " +
+                "singleDevice = " + mSingleDevice + ", " +
+                "deviceFilters = " + mDeviceFilters + ", " +
+                "deviceProfile = " + mDeviceProfile + ", " +
+                "callingPackage = " + mCallingPackage +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public boolean equals(@Nullable Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(AssociationRequest other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        AssociationRequest that = (AssociationRequest) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && mSingleDevice == that.mSingleDevice
+                && Objects.equals(mDeviceFilters, that.mDeviceFilters)
+                && Objects.equals(mDeviceProfile, that.mDeviceProfile)
+                && Objects.equals(mCallingPackage, that.mCallingPackage);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + Boolean.hashCode(mSingleDevice);
+        _hash = 31 * _hash + Objects.hashCode(mDeviceFilters);
+        _hash = 31 * _hash + Objects.hashCode(mDeviceProfile);
+        _hash = 31 * _hash + Objects.hashCode(mCallingPackage);
+        return _hash;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        byte flg = 0;
+        if (mSingleDevice) flg |= 0x1;
+        if (mDeviceProfile != null) flg |= 0x4;
+        if (mCallingPackage != null) flg |= 0x8;
+        dest.writeByte(flg);
+        dest.writeParcelableList(mDeviceFilters, flags);
+        if (mDeviceProfile != null) dest.writeString(mDeviceProfile);
+        if (mCallingPackage != null) dest.writeString(mCallingPackage);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ AssociationRequest(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        boolean singleDevice = (flg & 0x1) != 0;
+        List<DeviceFilter<?>> deviceFilters = new ArrayList<>();
+        in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader());
+        String deviceProfile = (flg & 0x4) == 0 ? null : in.readString();
+        String callingPackage = (flg & 0x8) == 0 ? null : in.readString();
+
+        this.mSingleDevice = singleDevice;
+        this.mDeviceFilters = deviceFilters;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mDeviceFilters);
+        this.mDeviceProfile = deviceProfile;
+        com.android.internal.util.AnnotationValidations.validate(
+                DeviceProfile.class, null, mDeviceProfile);
+        this.mCallingPackage = callingPackage;
+
+        onConstructed();
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<AssociationRequest> CREATOR
+            = new Parcelable.Creator<AssociationRequest>() {
+        @Override
+        public AssociationRequest[] newArray(int size) {
+            return new AssociationRequest[size];
+        }
+
+        @Override
+        public AssociationRequest createFromParcel(@NonNull Parcel in) {
+            return new AssociationRequest(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1604534468409L,
+            codegenVersion = "1.0.20",
+            sourceFile = "frameworks/base/core/java/android/companion/AssociationRequest.java",
+            inputSignatures = "public static final  java.lang.String DEVICE_PROFILE_WATCH\nprivate  boolean mSingleDevice\nprivate @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.String mCallingPackage\npublic  void setCallingPackage(java.lang.String)\nprivate  void onConstructed()\npublic @android.compat.annotation.UnsupportedAppUsage boolean isSingleDevice()\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate  boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genHiddenConstructor=true, genBuilder=false)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
 }
diff --git a/core/java/android/companion/CompanionDeviceService.java b/core/java/android/companion/CompanionDeviceService.java
new file mode 100644
index 0000000..56639ea
--- /dev/null
+++ b/core/java/android/companion/CompanionDeviceService.java
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+
+package android.companion;
+
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.android.internal.util.function.pooled.PooledLambda;
+
+import java.util.Objects;
+
+/**
+ * Service to be implemented by apps that manage a companion device.
+ *
+ * System will keep this service bound whenever an associated device is nearby,
+ * ensuring app stays alive.
+ *
+ * An app must be {@link CompanionDeviceManager#associate associated} with at leas one device,
+ * before it can take advantage of this service.
+ *
+ * You must declare this service in your manifest with an
+ * intent-filter action of {@link #SERVICE_INTERFACE} and
+ * permission of {@link android.Manifest.permission#BIND_COMPANION_DEVICE_SERVICE}
+ */
+public abstract class CompanionDeviceService extends Service {
+
+    private static final String LOG_TAG = "CompanionDeviceService";
+
+    /**
+     * An intent action for a service to be bound whenever this app's companion device(s)
+     * are nearby.
+     *
+     * <p>The app will be kept alive for as long as the device is nearby.
+     * If the app is not running at the time device gets connected, the app will be woken up.</p>
+     *
+     * <p>Shortly after the device goes out of range, the service will be unbound, and the
+     * app will be eligible for cleanup, unless any other user-visible components are running.</p>
+     *
+     * <p>An app shouldn't declare more than one of these services.
+     * If running in background is not essential for the devices that this app can manage,
+     * app should avoid declaring this service.</p>
+     *
+     * <p>The service must also require permission
+     * {@link android.Manifest.permission#BIND_COMPANION_DEVICE_SERVICE}</p>
+     */
+    public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
+
+    private final Stub mRemote = new Stub();
+
+    /**
+     * Called by system whenever a device associated with this app is available.
+     *
+     * @param address the MAC address of the device
+     */
+    @MainThread
+    public abstract void onDeviceAppeared(@NonNull String address);
+
+    /**
+     * Called by system whenever a device associated with this app stops being available.
+     *
+     * Usually this means the device goes out of range or is turned off.
+     *
+     * @param address the MAC address of the device
+     */
+    @MainThread
+    public abstract void onDeviceDisappeared(@NonNull String address);
+
+    @Nullable
+    @Override
+    public final IBinder onBind(@NonNull Intent intent) {
+        if (Objects.equals(intent.getAction(), SERVICE_INTERFACE)) {
+            return mRemote;
+        }
+        Log.w(LOG_TAG,
+                "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + "): " + intent);
+        return null;
+    }
+
+    class Stub extends ICompanionDeviceService.Stub {
+
+        @Override
+        public void onDeviceAppeared(String address) {
+            Handler.getMain().sendMessage(PooledLambda.obtainMessage(
+                    CompanionDeviceService::onDeviceAppeared,
+                    CompanionDeviceService.this, address));
+        }
+
+        @Override
+        public void onDeviceDisappeared(String address) {
+            Handler.getMain().sendMessage(PooledLambda.obtainMessage(
+                    CompanionDeviceService::onDeviceDisappeared,
+                    CompanionDeviceService.this, address));
+        }
+    }
+}
diff --git a/core/java/android/companion/ICompanionDeviceService.aidl b/core/java/android/companion/ICompanionDeviceService.aidl
new file mode 100644
index 0000000..f3977ca
--- /dev/null
+++ b/core/java/android/companion/ICompanionDeviceService.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package android.companion;
+
+import android.app.PendingIntent;
+import android.companion.IFindDeviceCallback;
+import android.companion.Association;
+import android.companion.AssociationRequest;
+import android.content.ComponentName;
+
+/** @hide */
+oneway interface ICompanionDeviceService {
+    void onDeviceAppeared(in String address);
+    void onDeviceDisappeared(in String address);
+}
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 73becb1..e3395e2 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -74,8 +74,8 @@
 
     /**
      * The MIME type for a shortcut. The ClipData must include intents with required extras
-     * {@link #EXTRA_PENDING_INTENT} and {@link Intent#EXTRA_USER}, and an optional
-     * {@link #EXTRA_ACTIVITY_OPTIONS}.
+     * {@link Intent#EXTRA_SHORTCUT_ID}, {@link Intent#EXTRA_PACKAGE_NAME} and
+     * {@link Intent#EXTRA_USER}, and an optional {@link #EXTRA_ACTIVITY_OPTIONS}.
      * @hide
      */
     public static final String MIMETYPE_APPLICATION_SHORTCUT = "application/vnd.android.shortcut";
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 782f0cd..a03bdf2 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2740,6 +2740,7 @@
      * </ul>
      *
      * <p class="note">This is a protected intent that can only be sent by the system.
+     * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PACKAGE_STARTABLE = "android.intent.action.PACKAGE_STARTABLE";
@@ -2757,6 +2758,7 @@
      * </ul>
      *
      * <p class="note">This is a protected intent that can only be sent by the system.
+     * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PACKAGE_UNSTARTABLE =
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 596d39b..0fc9fad 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1356,7 +1356,9 @@
          * Completely abandon this session, destroying all staged data and
          * rendering it invalid. Abandoned sessions will be reported to
          * {@link SessionCallback} listeners as failures. This is equivalent to
-         * opening the session and calling {@link Session#abandon()}.
+         * {@link #abandonSession(int)}.
+         * <p>If the parent is abandoned, all children will also be abandoned. Any written data
+         * would be destroyed and the created {@link Session} information will be discarded.</p>
          */
         public void abandon() {
             try {
@@ -1419,7 +1421,8 @@
          * when this session is committed.
          *
          * <p>If the parent is staged or has rollback enabled, all children must have
-         * the same properties.
+         * the same properties.</p>
+         * <p>If the parent is abandoned, all children will also be abandoned.</p>
          *
          * @param sessionId the session ID to add to this multi-package session.
          */
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 946c634..a77d8b1 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3824,18 +3824,21 @@
      * Unstartable state with no root cause specified. E.g., data loader seeing missing pages but
      * unclear about the cause. This corresponds to a generic alert window shown to the user when
      * the user attempts to launch the app.
+     * @hide
      */
     public static final int UNSTARTABLE_REASON_UNKNOWN = 0;
 
     /**
      * Unstartable state due to connection issues that interrupt package loading.
      * This corresponds to an alert window shown to the user indicating connection errors.
+     * @hide
      */
     public static final int UNSTARTABLE_REASON_CONNECTION_ERROR = 1;
 
     /**
      * Unstartable state after encountering storage limitations.
      * This corresponds to an alert window indicating limited storage.
+     * @hide
      */
     public static final int UNSTARTABLE_REASON_INSUFFICIENT_STORAGE = 2;
 
diff --git a/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java
index e7a554a..aea69ad 100644
--- a/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java
+++ b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java
@@ -59,14 +59,18 @@
 
 
 
-    // Code below generated by codegen v1.0.0.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
     //
     // To regenerate run:
     // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java
     //
-    // CHECKSTYLE:OFF Generated code
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
 
     /**
      * Creates a new SplitPermissionInfoParcelable.
@@ -154,7 +158,7 @@
 
     @Override
     @DataClass.Generated.Member
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
@@ -167,6 +171,32 @@
     @DataClass.Generated.Member
     public int describeContents() { return 0; }
 
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    protected SplitPermissionInfoParcelable(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        String splitPermission = in.readString();
+        List<String> newPermissions = new java.util.ArrayList<>();
+        in.readStringList(newPermissions);
+        int targetSdk = in.readInt();
+
+        this.mSplitPermission = splitPermission;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mSplitPermission);
+        this.mNewPermissions = newPermissions;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mNewPermissions);
+        this.mTargetSdk = targetSdk;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mTargetSdk,
+                "from", 0);
+
+        onConstructed();
+    }
+
     @DataClass.Generated.Member
     public static final @NonNull Parcelable.Creator<SplitPermissionInfoParcelable> CREATOR
             = new Parcelable.Creator<SplitPermissionInfoParcelable>() {
@@ -176,28 +206,21 @@
         }
 
         @Override
-        @SuppressWarnings({"unchecked", "RedundantCast"})
-        public SplitPermissionInfoParcelable createFromParcel(Parcel in) {
-            // You can override field unparcelling by defining methods like:
-            // static FieldType unparcelFieldName(Parcel in) { ... }
-
-            String splitPermission = in.readString();
-            List<String> newPermissions = new java.util.ArrayList<>();
-            in.readStringList(newPermissions);
-            int targetSdk = in.readInt();
-            return new SplitPermissionInfoParcelable(
-                    splitPermission,
-                    newPermissions,
-                    targetSdk);
+        public SplitPermissionInfoParcelable createFromParcel(@NonNull Parcel in) {
+            return new SplitPermissionInfoParcelable(in);
         }
     };
 
     @DataClass.Generated(
-            time = 1567634390477L,
-            codegenVersion = "1.0.0",
+            time = 1604456266666L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mSplitPermission\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mNewPermissions\nprivate final @android.annotation.IntRange(from=0L) int mTargetSdk\nprivate  void onConstructed()\nclass SplitPermissionInfoParcelable extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
+            inputSignatures = "private final @android.annotation.NonNull java.lang.String mSplitPermission\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mNewPermissions\nprivate final @android.annotation.IntRange int mTargetSdk\nprivate  void onConstructed()\nclass SplitPermissionInfoParcelable extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
     @Deprecated
     private void __metadata() {}
 
+
+    //@formatter:on
+    // End of generated code
+
 }
diff --git a/core/java/android/content/rollback/IRollbackManager.aidl b/core/java/android/content/rollback/IRollbackManager.aidl
index cda0e98..c818e93 100644
--- a/core/java/android/content/rollback/IRollbackManager.aidl
+++ b/core/java/android/content/rollback/IRollbackManager.aidl
@@ -49,10 +49,6 @@
     // NOTE: This call is synchronous.
     int notifyStagedSession(int sessionId);
 
-    // Used by the staging manager to notify the RollbackManager of the apk
-    // session for a staged session.
-    void notifyStagedApkSession(int originalSessionId, int apkSessionId);
-
     // For test purposes only.
     void blockRollbackManager(long millis);
 }
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 3effc5a..cf25c3c 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -24,6 +24,8 @@
 import android.os.Bundle;
 import android.util.Log;
 
+import dalvik.system.CloseGuard;
+
 import java.lang.ref.WeakReference;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -86,6 +88,9 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private Bundle mExtras = Bundle.EMPTY;
 
+    /** CloseGuard to detect leaked cursor **/
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
     /* -------------------------------------------------------- */
     /* These need to be implemented by subclasses */
     @Override
@@ -179,6 +184,7 @@
         mClosed = true;
         mContentObservable.unregisterAll();
         onDeactivateOrClose();
+        mCloseGuard.close();
     }
 
     /**
@@ -218,6 +224,7 @@
     /* Implementation */
     public AbstractCursor() {
         mPos = -1;
+        mCloseGuard.open("close");
     }
 
     @Override
@@ -521,6 +528,7 @@
             mContentResolver.unregisterContentObserver(mSelfObserver);
         }
         try {
+            if (mCloseGuard != null) mCloseGuard.warnIfOpen();
             if (!mClosed) close();
         } catch(Exception e) { }
     }
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 3bfbe7e..7ba63e6 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -62,9 +62,6 @@
     /** A mapping of column names to column indices, to speed up lookups */
     private Map<String, Integer> mColumnNameMap;
 
-    /** Used to find out where a cursor was allocated in case it never got released. */
-    private final Throwable mStackTrace;
-
     /** Controls fetching of rows relative to requested position **/
     private boolean mFillWindowForwardOnly;
 
@@ -102,11 +99,6 @@
         if (query == null) {
             throw new IllegalArgumentException("query object cannot be null");
         }
-        if (StrictMode.vmSqliteObjectLeaksEnabled()) {
-            mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
-        } else {
-            mStackTrace = null;
-        }
         mDriver = driver;
         mEditTable = editTable;
         mColumnNameMap = null;
@@ -283,17 +275,17 @@
         try {
             // if the cursor hasn't been closed yet, close it first
             if (mWindow != null) {
-                if (mStackTrace != null) {
+                // Report original sql statement
+                if (StrictMode.vmSqliteObjectLeaksEnabled()) {
                     String sql = mQuery.getSql();
                     int len = sql.length();
                     StrictMode.onSqliteObjectLeaked(
-                        "Finalizing a Cursor that has not been deactivated or closed. " +
-                        "database = " + mQuery.getDatabase().getLabel() +
-                        ", table = " + mEditTable +
-                        ", query = " + sql.substring(0, (len > 1000) ? 1000 : len),
-                        mStackTrace);
+                            "Finalizing a Cursor that has not been deactivated or closed. "
+                            + "database = " + mQuery.getDatabase().getLabel()
+                            + ", table = " + mEditTable
+                            + ", query = " + sql.substring(0, (len > 1000) ? 1000 : len),
+                            null);
                 }
-                close();
             }
         } finally {
             super.finalize();
diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java
index a52f983..29a6ee2 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManager.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManager.java
@@ -16,9 +16,12 @@
 
 package android.hardware.devicestate;
 
+import android.annotation.NonNull;
 import android.annotation.SystemService;
 import android.content.Context;
 
+import java.util.concurrent.Executor;
+
 /**
  * Manages the state of the system for devices with user-configurable hardware like a foldable
  * phone.
@@ -33,6 +36,47 @@
     private DeviceStateManagerGlobal mGlobal;
 
     public DeviceStateManager() {
-        mGlobal = DeviceStateManagerGlobal.getInstance();
+        DeviceStateManagerGlobal global = DeviceStateManagerGlobal.getInstance();
+        if (global == null) {
+            throw new IllegalStateException(
+                    "Failed to get instance of global device state manager.");
+        }
+        mGlobal = global;
+    }
+
+    /**
+     * Registers a listener to receive notifications about changes in device state.
+     *
+     * @param listener the listener to register.
+     * @param executor the executor to process notifications.
+     *
+     * @see DeviceStateListener
+     */
+    public void registerDeviceStateListener(@NonNull DeviceStateListener listener,
+            @NonNull Executor executor) {
+        mGlobal.registerDeviceStateListener(listener, executor);
+    }
+
+    /**
+     * Unregisters a listener previously registered with
+     * {@link #registerDeviceStateListener(DeviceStateListener, Executor)}.
+     */
+    public void unregisterDeviceStateListener(@NonNull DeviceStateListener listener) {
+        mGlobal.unregisterDeviceStateListener(listener);
+    }
+
+    /**
+     * Listens for changes in device states.
+     */
+    public interface DeviceStateListener {
+        /**
+         * Called in response to device state changes.
+         * <p>
+         * Guaranteed to be called once on registration of the listener with the
+         * initial value and then on every subsequent change in device state.
+         *
+         * @param deviceState the new device state.
+         */
+        void onDeviceStateChanged(int deviceState);
     }
 }
diff --git a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
index 4e7cf4a..c8905038 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
@@ -19,16 +19,26 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.hardware.devicestate.DeviceStateManager.DeviceStateListener;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.annotations.VisibleForTesting.Visibility;
+
+import java.util.ArrayList;
+import java.util.concurrent.Executor;
+
 /**
  * Provides communication with the device state system service on behalf of applications.
  *
  * @see DeviceStateManager
  * @hide
  */
-final class DeviceStateManagerGlobal {
+@VisibleForTesting(visibility = Visibility.PACKAGE)
+public final class DeviceStateManagerGlobal {
     private static DeviceStateManagerGlobal sInstance;
 
     /**
@@ -49,10 +59,121 @@
         }
     }
 
+    private final Object mLock = new Object();
     @NonNull
     private final IDeviceStateManager mDeviceStateManager;
+    @Nullable
+    private DeviceStateManagerCallback mCallback;
 
-    private DeviceStateManagerGlobal(@NonNull IDeviceStateManager deviceStateManager) {
+    @GuardedBy("mLock")
+    private final ArrayList<DeviceStateListenerWrapper> mListeners = new ArrayList<>();
+    @Nullable
+    @GuardedBy("mLock")
+    private Integer mLastReceivedState;
+
+    @VisibleForTesting
+    public DeviceStateManagerGlobal(@NonNull IDeviceStateManager deviceStateManager) {
         mDeviceStateManager = deviceStateManager;
     }
+
+    /**
+     * Registers a listener to receive notifications about changes in device state.
+     *
+     * @see DeviceStateManager#registerDeviceStateListener(DeviceStateListener, Executor)
+     */
+    @VisibleForTesting(visibility = Visibility.PACKAGE)
+    public void registerDeviceStateListener(@NonNull DeviceStateListener listener,
+            @NonNull Executor executor) {
+        Integer stateToReport;
+        DeviceStateListenerWrapper wrapper;
+        synchronized (mLock) {
+            registerCallbackIfNeededLocked();
+
+            int index = findListenerLocked(listener);
+            if (index != -1) {
+                // This listener is already registered.
+                return;
+            }
+
+            wrapper = new DeviceStateListenerWrapper(listener, executor);
+            mListeners.add(wrapper);
+            stateToReport = mLastReceivedState;
+        }
+
+        if (stateToReport != null) {
+            // Notify the listener with the most recent device state from the server. If the state
+            // to report is null this is likely the first listener added and we're still waiting
+            // from the callback from the server.
+            wrapper.notifyDeviceStateChanged(stateToReport);
+        }
+    }
+
+    /**
+     * Unregisters a listener previously registered with
+     * {@link #registerDeviceStateListener(DeviceStateListener, Executor)}.
+     *
+     * @see DeviceStateManager#registerDeviceStateListener(DeviceStateListener, Executor)
+     */
+    @VisibleForTesting(visibility = Visibility.PACKAGE)
+    public void unregisterDeviceStateListener(DeviceStateListener listener) {
+        synchronized (mLock) {
+            int indexToRemove = findListenerLocked(listener);
+            if (indexToRemove != -1) {
+                mListeners.remove(indexToRemove);
+            }
+        }
+    }
+
+    private void registerCallbackIfNeededLocked() {
+        if (mCallback == null) {
+            mCallback = new DeviceStateManagerCallback();
+            try {
+                mDeviceStateManager.registerCallback(mCallback);
+            } catch (RemoteException ex) {
+                throw ex.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    private int findListenerLocked(DeviceStateListener listener) {
+        for (int i = 0; i < mListeners.size(); i++) {
+            if (mListeners.get(i).mDeviceStateListener.equals(listener)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private void handleDeviceStateChanged(int newDeviceState) {
+        ArrayList<DeviceStateListenerWrapper> listeners;
+        synchronized (mLock) {
+            mLastReceivedState = newDeviceState;
+            listeners = new ArrayList<>(mListeners);
+        }
+
+        for (int i = 0; i < listeners.size(); i++) {
+            listeners.get(i).notifyDeviceStateChanged(newDeviceState);
+        }
+    }
+
+    private final class DeviceStateManagerCallback extends IDeviceStateManagerCallback.Stub {
+        @Override
+        public void onDeviceStateChanged(int deviceState) {
+            handleDeviceStateChanged(deviceState);
+        }
+    }
+
+    private static final class DeviceStateListenerWrapper {
+        private final DeviceStateListener mDeviceStateListener;
+        private final Executor mExecutor;
+
+        DeviceStateListenerWrapper(DeviceStateListener listener, Executor executor) {
+            mDeviceStateListener = listener;
+            mExecutor = executor;
+        }
+
+        void notifyDeviceStateChanged(int newDeviceState) {
+            mExecutor.execute(() -> mDeviceStateListener.onDeviceStateChanged(newDeviceState));
+        }
+    }
 }
diff --git a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
index 24913e9..a157b33 100644
--- a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
+++ b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
@@ -16,5 +16,9 @@
 
 package android.hardware.devicestate;
 
+import android.hardware.devicestate.IDeviceStateManagerCallback;
+
 /** @hide */
-interface IDeviceStateManager {}
+interface IDeviceStateManager {
+    void registerCallback(in IDeviceStateManagerCallback callback);
+}
diff --git a/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl b/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl
new file mode 100644
index 0000000..d1c5813
--- /dev/null
+++ b/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+package android.hardware.devicestate;
+
+/** @hide */
+interface IDeviceStateManagerCallback {
+    oneway void onDeviceStateChanged(int deviceState);
+}
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index 10e1c7c..71688c7c 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -93,7 +93,7 @@
 
 
 
-    // Code below generated by codegen v1.0.15.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -477,10 +477,10 @@
     }
 
     @DataClass.Generated(
-            time = 1585179350902L,
-            codegenVersion = "1.0.15",
+            time = 1604456298440L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java",
-            inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange(from=1L) int mWidth\nprivate @android.annotation.IntRange(from=1L) int mHeight\nprivate @android.annotation.IntRange(from=1L) int mDensityDpi\nprivate  int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate  int mDisplayIdToMirror\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)")
+            inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate  int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate  int mDisplayIdToMirror\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 9f322fb..75893d9 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -577,9 +577,17 @@
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
     public List<Face> getEnrolledFaces(int userId) {
+        final List<FaceSensorPropertiesInternal> faceSensorProperties =
+                getSensorPropertiesInternal();
+        if (faceSensorProperties.isEmpty()) {
+            Slog.e(TAG, "No sensors");
+            return new ArrayList<>();
+        }
+
         if (mService != null) {
             try {
-                return mService.getEnrolledFaces(userId, mContext.getOpPackageName());
+                return mService.getEnrolledFaces(faceSensorProperties.get(0).sensorId, userId,
+                        mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -606,15 +614,7 @@
      */
     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
     public boolean hasEnrolledTemplates() {
-        if (mService != null) {
-            try {
-                return mService.hasEnrolledFaces(
-                        UserHandle.myUserId(), mContext.getOpPackageName());
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-        return false;
+        return hasEnrolledTemplates(UserHandle.myUserId());
     }
 
     /**
@@ -624,9 +624,17 @@
             USE_BIOMETRIC_INTERNAL,
             INTERACT_ACROSS_USERS})
     public boolean hasEnrolledTemplates(int userId) {
+        final List<FaceSensorPropertiesInternal> faceSensorProperties =
+                getSensorPropertiesInternal();
+        if (faceSensorProperties.isEmpty()) {
+            Slog.e(TAG, "No sensors");
+            return false;
+        }
+
         if (mService != null) {
             try {
-                return mService.hasEnrolledFaces(userId, mContext.getOpPackageName());
+                return mService.hasEnrolledFaces(faceSensorProperties.get(0).sensorId, userId,
+                        mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -642,9 +650,17 @@
      */
     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
     public boolean isHardwareDetected() {
+        final List<FaceSensorPropertiesInternal> faceSensorProperties =
+                getSensorPropertiesInternal();
+        if (faceSensorProperties.isEmpty()) {
+            Slog.e(TAG, "No sensors");
+            return false;
+        }
+
         if (mService != null) {
             try {
-                return mService.isHardwareDetected(mContext.getOpPackageName());
+                return mService.isHardwareDetected(faceSensorProperties.get(0).sensorId,
+                        mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -677,7 +693,7 @@
     @NonNull
     public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal() {
         try {
-            if (mService == null || !mService.isHardwareDetected(mContext.getOpPackageName())) {
+            if (mService == null) {
                 return new ArrayList<>();
             }
             return mService.getSensorPropertiesInternal(mContext.getOpPackageName());
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 490c95b..27cdda7 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -44,12 +44,12 @@
     // called from BiometricService. The additional uid, pid, userId arguments should be determined
     // by BiometricService. To start authentication after the clients are ready, use
     // startPreparedClient().
-    void prepareForAuthentication(boolean requireConfirmation, IBinder token, long operationId,
+    void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token, long operationId,
             int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
             int cookie, int callingUid, int callingPid, int callingUserId);
 
     // Starts authentication with the previously prepared client.
-    void startPreparedClient(int cookie);
+    void startPreparedClient(int sensorId, int cookie);
 
     // Cancel authentication for the given sessionId
     void cancelAuthentication(IBinder token, String opPackageName);
@@ -58,7 +58,7 @@
     void cancelFaceDetect(IBinder token, String opPackageName);
 
     // Same as above, with extra arguments.
-    void cancelAuthenticationFromService(IBinder token, String opPackageName,
+    void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName,
             int callingUid, int callingPid, int callingUserId);
 
     // Start face enrollment
@@ -77,10 +77,10 @@
             String opPackageName);
 
     // Get the enrolled face for user.
-    List<Face> getEnrolledFaces(int userId, String opPackageName);
+    List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName);
 
     // Determine if HAL is loaded and ready
-    boolean isHardwareDetected(String opPackageName);
+    boolean isHardwareDetected(int sensorId, String opPackageName);
 
     // Get a pre-enrollment authentication token
     void generateChallenge(IBinder token, int sensorId, int userId, IFaceServiceReceiver receiver, String opPackageName);
@@ -89,13 +89,13 @@
     void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge);
 
     // Determine if a user has at least one enrolled face
-    boolean hasEnrolledFaces(int userId, String opPackageName);
+    boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName);
 
     // Return the LockoutTracker status for the specified user
-    int getLockoutModeForUser(int userId);
+    int getLockoutModeForUser(int sensorId, int userId);
 
     // Gets the authenticator ID for face
-    long getAuthenticatorId(int callingUserId);
+    long getAuthenticatorId(int sensorId, int callingUserId);
 
     // Reset the lockout when user authenticates with strong auth (e.g. PIN, pattern or password)
     void resetLockout(IBinder token, int sensorId, int userId, in byte [] hardwareAuthToken, String opPackageName);
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 4afe4b3..51e0eba 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -846,13 +846,7 @@
     @Deprecated
     @RequiresPermission(USE_FINGERPRINT)
     public boolean hasEnrolledFingerprints() {
-        if (mService != null) try {
-            return mService.hasEnrolledFingerprints(
-                    mContext.getUserId(), mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-        return false;
+        return hasEnrolledFingerprints(UserHandle.myUserId());
     }
 
     /**
@@ -863,7 +857,7 @@
             INTERACT_ACROSS_USERS})
     public boolean hasEnrolledFingerprints(int userId) {
         if (mService != null) try {
-            return mService.hasEnrolledFingerprints(userId, mContext.getOpPackageName());
+            return mService.hasEnrolledFingerprintsDeprecated(userId, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -882,7 +876,7 @@
     public boolean isHardwareDetected() {
         if (mService != null) {
             try {
-                return mService.isHardwareDetected(mContext.getOpPackageName());
+                return mService.isHardwareDetectedDeprecated(mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -900,7 +894,7 @@
     @NonNull
     public List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal() {
         try {
-            if (mService == null || !mService.isHardwareDetected(mContext.getOpPackageName())) {
+            if (mService == null) {
                 return new ArrayList<>();
             }
             return mService.getSensorPropertiesInternal(mContext.getOpPackageName());
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 5b14ef7..2128d67 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -53,12 +53,12 @@
     // called from BiometricService. The additional uid, pid, userId arguments should be determined
     // by BiometricService. To start authentication after the clients are ready, use
     // startPreparedClient().
-    void prepareForAuthentication(IBinder token, long operationId, int userId,
+    void prepareForAuthentication(int sensorId, IBinder token, long operationId, int userId,
             IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie,
             int callingUid, int callingPid, int callingUserId);
 
     // Starts authentication with the previously prepared client.
-    void startPreparedClient(int cookie);
+    void startPreparedClient(int sensorId, int cookie);
 
     // Cancel authentication for the given sessionId
     void cancelAuthentication(IBinder token, String opPackageName);
@@ -68,7 +68,7 @@
 
     // Same as above, except this is protected by the MANAGE_BIOMETRIC signature permission. Takes
     // an additional uid, pid, userid.
-    void cancelAuthenticationFromService(IBinder token, String opPackageName,
+    void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName,
             int callingUid, int callingPid, int callingUserId);
 
     // Start fingerprint enrollment
@@ -88,8 +88,11 @@
     // Get a list of enrolled fingerprints in the given userId.
     List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName);
 
-    // Determine if HAL is loaded and ready
-    boolean isHardwareDetected(String opPackageName);
+    // Determine if the HAL is loaded and ready. Meant to support the deprecated FingerprintManager APIs
+    boolean isHardwareDetectedDeprecated(String opPackageName);
+
+    // Determine if the specified HAL is loaded and ready
+    boolean isHardwareDetected(int sensorId, String opPackageName);
 
     // Get a pre-enrollment authentication token
     void generateChallenge(IBinder token, int sensorId, int userId, IFingerprintServiceReceiver receiver, String opPackageName);
@@ -97,17 +100,20 @@
     // Finish an enrollment sequence and invalidate the authentication token
     void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge);
 
-    // Determine if a user has at least one enrolled fingerprint
-    boolean hasEnrolledFingerprints(int userId, String opPackageName);
+    // Determine if a user has at least one enrolled fingerprint. Meant to support the deprecated FingerprintManager APIs
+    boolean hasEnrolledFingerprintsDeprecated(int userId, String opPackageName);
+
+    // Determine if a user has at least one enrolled fingerprint.
+    boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName);
 
     // Determine if a user has at least one enrolled fingerprint in any of the specified sensors
     boolean hasEnrolledTemplatesForAnySensor(int userId, in List<FingerprintSensorPropertiesInternal> sensors, String opPackageName);
 
     // Return the LockoutTracker status for the specified user
-    int getLockoutModeForUser(int userId);
+    int getLockoutModeForUser(int sensorId, int userId);
 
     // Gets the authenticator ID for fingerprint
-    long getAuthenticatorId(int callingUserId);
+    long getAuthenticatorId(int sensorId, int callingUserId);
 
     // Reset the timeout when user authenticates with strong auth (e.g. PIN, pattern or password)
     void resetLockout(IBinder token, int sensorId, int userId, in byte[] hardwareAuthToken, String opPackageNAame);
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 401bb9d..bf32560 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -42,9 +42,11 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
 
 /**
  * The {@link HdmiControlManager} class is used to send HDMI control messages
@@ -325,17 +327,17 @@
      *
      * @hide
      */
-    public static final String HDMI_CEC_CONTROL_ENABLED = "1";
+    public static final int HDMI_CEC_CONTROL_ENABLED = 1;
     /**
      * HDMI CEC disabled.
      *
      * @hide
      */
-    public static final String HDMI_CEC_CONTROL_DISABLED = "0";
+    public static final int HDMI_CEC_CONTROL_DISABLED = 0;
     /**
      * @hide
      */
-    @StringDef({
+    @IntDef({
             HDMI_CEC_CONTROL_ENABLED,
             HDMI_CEC_CONTROL_DISABLED
     })
@@ -401,17 +403,17 @@
      *
      * @hide
      */
-    public static final String SYSTEM_AUDIO_MODE_MUTING_ENABLED = "1";
+    public static final int SYSTEM_AUDIO_MODE_MUTING_ENABLED = 1;
     /**
      * System Audio Mode muting disabled.
      *
      * @hide
      */
-    public static final String SYSTEM_AUDIO_MODE_MUTING_DISABLED = "0";
+    public static final int SYSTEM_AUDIO_MODE_MUTING_DISABLED = 0;
     /**
      * @hide
      */
-    @StringDef({
+    @IntDef({
             SYSTEM_AUDIO_MODE_MUTING_ENABLED,
             SYSTEM_AUDIO_MODE_MUTING_DISABLED
     })
@@ -1317,24 +1319,51 @@
     }
 
     /**
-     * Get a set of allowed values for a settings.
+     * Get a set of allowed values for a setting (string value-type).
      *
      * @param name name of the setting
      * @return a set of allowed values for a settings. {@code null} on failure.
      * @throws IllegalArgumentException when setting {@code name} does not exist.
+     * @throws IllegalArgumentException when setting {@code name} value type is invalid.
      * @throws RuntimeException when the HdmiControlService is not available.
      *
      * @hide
      */
     @NonNull
     @RequiresPermission(android.Manifest.permission.HDMI_CEC)
-    public List<String> getAllowedCecSettingValues(@NonNull @CecSettingName String name) {
+    public List<String> getAllowedCecSettingStringValues(@NonNull @CecSettingName String name) {
         if (mService == null) {
             Log.e(TAG, "HdmiControlService is not available");
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            return mService.getAllowedCecSettingValues(name);
+            return mService.getAllowedCecSettingStringValues(name);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get a set of allowed values for a setting (int value-type).
+     *
+     * @param name name of the setting
+     * @return a set of allowed values for a settings. {@code null} on failure.
+     * @throws IllegalArgumentException when setting {@code name} does not exist.
+     * @throws IllegalArgumentException when setting {@code name} value type is invalid.
+     * @throws RuntimeException when the HdmiControlService is not available.
+     *
+     * @hide
+     */
+    @NonNull
+    @RequiresPermission(android.Manifest.permission.HDMI_CEC)
+    public List<Integer> getAllowedCecSettingIntValues(@NonNull @CecSettingName String name) {
+        if (mService == null) {
+            Log.e(TAG, "HdmiControlService is not available");
+            throw new RuntimeException("HdmiControlService is not available");
+        }
+        try {
+            int[] allowedValues = mService.getAllowedCecSettingIntValues(name);
+            return Arrays.stream(allowedValues).boxed().collect(Collectors.toList());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1350,13 +1379,13 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.HDMI_CEC)
-    public void setHdmiCecEnabled(@NonNull @HdmiCecControl String value) {
+    public void setHdmiCecEnabled(@NonNull @HdmiCecControl int value) {
         if (mService == null) {
             Log.e(TAG, "HdmiControlService is not available");
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            mService.setCecSettingValue(CEC_SETTING_NAME_HDMI_CEC_ENABLED, value);
+            mService.setCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_ENABLED, value);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1373,13 +1402,13 @@
     @NonNull
     @HdmiCecControl
     @RequiresPermission(android.Manifest.permission.HDMI_CEC)
-    public String getHdmiCecEnabled() {
+    public int getHdmiCecEnabled() {
         if (mService == null) {
             Log.e(TAG, "HdmiControlService is not available");
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            return mService.getCecSettingValue(CEC_SETTING_NAME_HDMI_CEC_ENABLED);
+            return mService.getCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_ENABLED);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1401,7 +1430,7 @@
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            mService.setCecSettingValue(CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP, value);
+            mService.setCecSettingStringValue(CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP, value);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1424,7 +1453,7 @@
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            return mService.getCecSettingValue(CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
+            return mService.getCecSettingStringValue(CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1447,7 +1476,7 @@
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            mService.setCecSettingValue(
+            mService.setCecSettingStringValue(
                     CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, value);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1471,7 +1500,7 @@
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            return mService.getCecSettingValue(
+            return mService.getCecSettingStringValue(
                     CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1488,13 +1517,13 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.HDMI_CEC)
-    public void setSystemAudioModeMuting(@NonNull @SystemAudioModeMuting String value) {
+    public void setSystemAudioModeMuting(@NonNull @SystemAudioModeMuting int value) {
         if (mService == null) {
             Log.e(TAG, "HdmiControlService is not available");
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            mService.setCecSettingValue(CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING, value);
+            mService.setCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING, value);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1511,13 +1540,13 @@
     @NonNull
     @SystemAudioModeMuting
     @RequiresPermission(android.Manifest.permission.HDMI_CEC)
-    public String getSystemAudioModeMuting() {
+    public int getSystemAudioModeMuting() {
         if (mService == null) {
             Log.e(TAG, "HdmiControlService is not available");
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            return mService.getCecSettingValue(CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING);
+            return mService.getCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/hardware/hdmi/HdmiControlServiceWrapper.java b/core/java/android/hardware/hdmi/HdmiControlServiceWrapper.java
index 22d4640..fab56b8 100644
--- a/core/java/android/hardware/hdmi/HdmiControlServiceWrapper.java
+++ b/core/java/android/hardware/hdmi/HdmiControlServiceWrapper.java
@@ -301,18 +301,33 @@
         }
 
         @Override
-        public List<String> getAllowedCecSettingValues(String name) {
-            return HdmiControlServiceWrapper.this.getAllowedCecSettingValues(name);
+        public List<String> getAllowedCecSettingStringValues(String name) {
+            return HdmiControlServiceWrapper.this.getAllowedCecSettingStringValues(name);
         }
 
         @Override
-        public String getCecSettingValue(String name) {
-            return HdmiControlServiceWrapper.this.getCecSettingValue(name);
+        public int[] getAllowedCecSettingIntValues(String name) {
+            return HdmiControlServiceWrapper.this.getAllowedCecSettingIntValues(name);
         }
 
         @Override
-        public void setCecSettingValue(String name, String value) {
-            HdmiControlServiceWrapper.this.setCecSettingValue(name, value);
+        public String getCecSettingStringValue(String name) {
+            return HdmiControlServiceWrapper.this.getCecSettingStringValue(name);
+        }
+
+        @Override
+        public void setCecSettingStringValue(String name, String value) {
+            HdmiControlServiceWrapper.this.setCecSettingStringValue(name, value);
+        }
+
+        @Override
+        public int getCecSettingIntValue(String name) {
+            return HdmiControlServiceWrapper.this.getCecSettingIntValue(name);
+        }
+
+        @Override
+        public void setCecSettingIntValue(String name, int value) {
+            HdmiControlServiceWrapper.this.setCecSettingIntValue(name, value);
         }
     };
 
@@ -494,15 +509,30 @@
     }
 
     /** @hide */
-    public List<String> getAllowedCecSettingValues(String name) {
+    public List<String> getAllowedCecSettingStringValues(String name) {
         return new ArrayList<>();
     }
 
     /** @hide */
-    public String getCecSettingValue(String name) {
+    public int[] getAllowedCecSettingIntValues(String name) {
+        return new int[0];
+    }
+
+    /** @hide */
+    public String getCecSettingStringValue(String name) {
         return "";
     }
 
     /** @hide */
-    public void setCecSettingValue(String name, String value) {}
+    public void setCecSettingStringValue(String name, String value) {
+    }
+
+    /** @hide */
+    public int getCecSettingIntValue(String name) {
+        return 0;
+    }
+
+    /** @hide */
+    public void setCecSettingIntValue(String name, int value) {
+    }
 }
diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
index 6df164b..af9d3ac 100644
--- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
@@ -88,7 +88,10 @@
     void reportAudioStatus(int deviceType, int volume, int maxVolume, boolean isMute);
     void setSystemAudioModeOnForAudioOnlySource();
     List<String> getUserCecSettings();
-    List<String> getAllowedCecSettingValues(String name);
-    String getCecSettingValue(String name);
-    void setCecSettingValue(String name, String value);
+    List<String> getAllowedCecSettingStringValues(String name);
+    int[] getAllowedCecSettingIntValues(String name);
+    String getCecSettingStringValue(String name);
+    void setCecSettingStringValue(String name, String value);
+    int getCecSettingIntValue(String name);
+    void setCecSettingIntValue(String name, int value);
 }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 32a8c0a..44640c4 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -46,6 +46,7 @@
 import static android.inputmethodservice.InputMethodServiceProto.TOKEN;
 import static android.inputmethodservice.InputMethodServiceProto.VIEWS_CREATED;
 import static android.inputmethodservice.InputMethodServiceProto.WINDOW_VISIBLE;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowInsets.Type.navigationBars;
@@ -80,6 +81,7 @@
 import android.os.IBinder;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.provider.Settings;
 import android.text.InputType;
 import android.text.Layout;
@@ -645,7 +647,9 @@
         @Override
         public void startInput(InputConnection ic, EditorInfo attribute) {
             if (DEBUG) Log.v(TAG, "startInput(): editor=" + attribute);
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.startInput");
             doStartInput(ic, attribute, false);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
 
         /**
@@ -705,6 +709,8 @@
                 return;
             }
             final boolean wasVisible = isInputViewShown();
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.hideSoftInput");
+
             applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */);
             mShowInputFlags = 0;
             mShowInputRequested = false;
@@ -717,6 +723,7 @@
                         : (wasVisible ? InputMethodManager.RESULT_UNCHANGED_SHOWN
                                 : InputMethodManager.RESULT_UNCHANGED_HIDDEN), null);
             }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
 
         /**
@@ -748,6 +755,13 @@
                         + " Use requestShowSelf(int) itself");
                 return;
             }
+
+            if (Trace.isEnabled()) {
+                Binder.enableTracing();
+            } else {
+                Binder.disableTracing();
+            }
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showSoftInput");
             final boolean wasVisible = isInputViewShown();
             if (dispatchOnShowInputRequested(flags, false)) {
 
@@ -764,6 +778,7 @@
                         : (wasVisible ? InputMethodManager.RESULT_UNCHANGED_SHOWN
                                 : InputMethodManager.RESULT_UNCHANGED_HIDDEN), null);
             }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
 
         /**
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 224113f..4b38d63 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -4816,4 +4816,9 @@
             e.rethrowFromSystemServer();
         }
     }
+
+    private void setOemNetworkPreference(@NonNull OemNetworkPreferences preference) {
+        Log.d(TAG, "setOemNetworkPreference called with preference: "
+                + preference.toString());
+    }
 }
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 209a3fa..923b9b76 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -20,12 +20,13 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.LinkPropertiesUtils;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 
+import com.android.net.module.util.LinkPropertiesUtils;
+
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 049e9bc..c83c23a 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -20,13 +20,13 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.MacAddressUtils;
 import android.net.wifi.WifiInfo;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import com.android.internal.util.Preconditions;
+import com.android.net.module.util.MacAddressUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt b/core/java/android/net/OemNetworkPreferences.aidl
similarity index 63%
copy from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
copy to core/java/android/net/OemNetworkPreferences.aidl
index 24768cd..2b6a4ce 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
+++ b/core/java/android/net/OemNetworkPreferences.aidl
@@ -13,17 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
 
-import android.annotation.DimenRes
-import android.annotation.UserIdInt
+package android.net;
 
-data class BubbleEntity(
-    @UserIdInt val userId: Int,
-    val packageName: String,
-    val shortcutId: String,
-    val key: String,
-    val desiredHeight: Int,
-    @DimenRes val desiredHeightResId: Int,
-    val title: String? = null
-)
+parcelable OemNetworkPreferences;
diff --git a/core/java/android/net/OemNetworkPreferences.java b/core/java/android/net/OemNetworkPreferences.java
new file mode 100644
index 0000000..0778943
--- /dev/null
+++ b/core/java/android/net/OemNetworkPreferences.java
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+package android.net;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/** @hide */
+public final class OemNetworkPreferences implements Parcelable {
+    /**
+     * Use default behavior requesting networks. Equivalent to not setting any preference at all.
+     */
+    public static final int OEM_NETWORK_PREFERENCE_DEFAULT = 0;
+
+    /**
+     * Prefer networks in order: NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_OEM_PAID, default.
+     */
+    public static final int OEM_NETWORK_PREFERENCE_OEM_PAID = 1;
+
+    /**
+     * Prefer networks in order: NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_OEM_PAID.
+     */
+    public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK = 2;
+
+    /**
+     * Prefer only NET_CAPABILITY_OEM_PAID networks.
+     */
+    public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY = 3;
+
+    /**
+     * Prefer only NET_CAPABILITY_OEM_PRIVATE networks.
+     */
+    public static final int OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY = 4;
+
+    @NonNull
+    private final SparseArray<List<String>> mNetworkMappings;
+
+    @NonNull
+    public SparseArray<List<String>> getNetworkPreferences() {
+        return mNetworkMappings.clone();
+    }
+
+    private OemNetworkPreferences(@NonNull SparseArray<List<String>> networkMappings) {
+        Objects.requireNonNull(networkMappings);
+        mNetworkMappings = networkMappings.clone();
+    }
+
+    @Override
+    public String toString() {
+        return "OemNetworkPreferences{" + "mNetworkMappings=" + mNetworkMappings + '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        OemNetworkPreferences that = (OemNetworkPreferences) o;
+
+        return mNetworkMappings.size() == that.mNetworkMappings.size()
+                && mNetworkMappings.toString().equals(that.mNetworkMappings.toString());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mNetworkMappings);
+    }
+
+    /**
+     * Builder used to create {@link OemNetworkPreferences} objects.  Specify the preferred Network
+     * to package name mappings.
+     *
+     * @hide
+     */
+    public static final class Builder {
+        private final SparseArray<List<String>> mNetworkMappings;
+
+        public Builder() {
+            mNetworkMappings = new SparseArray<>();
+        }
+
+        /**
+         * Add a network preference for a list of packages.
+         *
+         * @param preference the desired network preference to use
+         * @param packages   full package names (e.g.: "com.google.apps.contacts") for apps to use
+         *                   the given preference
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder addNetworkPreference(@OemNetworkPreference final int preference,
+                @NonNull List<String> packages) {
+            Objects.requireNonNull(packages);
+            mNetworkMappings.put(preference,
+                    Collections.unmodifiableList(new ArrayList<>(packages)));
+            return this;
+        }
+
+        /**
+         * Build {@link OemNetworkPreferences} return the current OEM network preferences.
+         */
+        @NonNull
+        public OemNetworkPreferences build() {
+            return new OemNetworkPreferences(mNetworkMappings);
+        }
+    }
+
+    /** @hide */
+    @IntDef(prefix = "OEM_NETWORK_PREFERENCE_", value = {
+            OEM_NETWORK_PREFERENCE_DEFAULT,
+            OEM_NETWORK_PREFERENCE_OEM_PAID,
+            OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK,
+            OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY,
+            OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface OemNetworkPreference {}
+
+    /**
+     * Return the string value for OemNetworkPreference
+     *
+     * @param value int value of OemNetworkPreference
+     * @return string version of OemNetworkPreference
+     */
+    @NonNull
+    public static String oemNetworkPreferenceToString(@OemNetworkPreference int value) {
+        switch (value) {
+            case OEM_NETWORK_PREFERENCE_DEFAULT:
+                return "OEM_NETWORK_PREFERENCE_DEFAULT";
+            case OEM_NETWORK_PREFERENCE_OEM_PAID:
+                return "OEM_NETWORK_PREFERENCE_OEM_PAID";
+            case OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
+                return "OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK";
+            case OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY:
+                return "OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY";
+            case OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
+                return "OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY";
+            default:
+                return Integer.toHexString(value);
+        }
+    }
+
+    @Override
+    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+        dest.writeSparseArray(mNetworkMappings);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<OemNetworkPreferences> CREATOR =
+            new Parcelable.Creator<OemNetworkPreferences>() {
+                @Override
+                public OemNetworkPreferences[] newArray(int size) {
+                    return new OemNetworkPreferences[size];
+                }
+
+                @Override
+                public OemNetworkPreferences createFromParcel(@NonNull android.os.Parcel in) {
+                    return new OemNetworkPreferences(
+                            in.readSparseArray(getClass().getClassLoader()));
+                }
+            };
+}
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 2543aa3..5b6684a 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -21,11 +21,12 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.NetUtils;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.net.module.util.NetUtils;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.Inet4Address;
diff --git a/core/java/android/os/CombinedVibrationEffect.java b/core/java/android/os/CombinedVibrationEffect.java
index 77bfa57..f552aaa 100644
--- a/core/java/android/os/CombinedVibrationEffect.java
+++ b/core/java/android/os/CombinedVibrationEffect.java
@@ -17,7 +17,12 @@
 package android.os;
 
 import android.annotation.NonNull;
+import android.util.SparseArray;
 
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -31,6 +36,8 @@
  */
 public abstract class CombinedVibrationEffect implements Parcelable {
     private static final int PARCEL_TOKEN_MONO = 1;
+    private static final int PARCEL_TOKEN_STEREO = 2;
+    private static final int PARCEL_TOKEN_SEQUENTIAL = 3;
 
     /** @hide to prevent subclassing from outside of the framework */
     public CombinedVibrationEffect() {
@@ -41,8 +48,8 @@
      *
      * A synced vibration effect should be performed by multiple vibrators at the same time.
      *
-     * @param effect The {@link VibrationEffect} to perform
-     * @return The desired combined effect.
+     * @param effect The {@link VibrationEffect} to perform.
+     * @return The synced effect.
      */
     @NonNull
     public static CombinedVibrationEffect createSynced(@NonNull VibrationEffect effect) {
@@ -51,6 +58,30 @@
         return combined;
     }
 
+    /**
+     * Start creating a synced vibration effect.
+     *
+     * A synced vibration effect should be performed by multiple vibrators at the same time.
+     *
+     * @see CombinedVibrationEffect.SyncedCombination
+     */
+    @NonNull
+    public static SyncedCombination startSynced() {
+        return new SyncedCombination();
+    }
+
+    /**
+     * Start creating a sequential vibration effect.
+     *
+     * A sequential vibration effect should be performed by multiple vibrators in order.
+     *
+     * @see CombinedVibrationEffect.SequentialCombination
+     */
+    @NonNull
+    public static SequentialCombination startSequential() {
+        return new SequentialCombination();
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -60,6 +91,164 @@
     public abstract void validate();
 
     /**
+     * A combination of haptic effects that should be played in multiple vibrators in sync.
+     *
+     * @hide
+     * @see CombinedVibrationEffect#startSynced()
+     */
+    public static final class SyncedCombination {
+
+        private final SparseArray<VibrationEffect> mEffects = new SparseArray<>();
+
+        SyncedCombination() {
+        }
+
+        /**
+         * Add or replace a one shot vibration effect to be performed by the specified vibrator.
+         *
+         * @param vibratorId The id of the vibrator that should perform this effect.
+         * @param effect     The effect this vibrator should play.
+         * @return The {@link CombinedVibrationEffect.SyncedCombination} object to enable adding
+         * multiple effects in one chain.
+         * @see VibrationEffect#createOneShot(long, int)
+         */
+        @NonNull
+        public SyncedCombination addVibrator(int vibratorId, VibrationEffect effect) {
+            mEffects.put(vibratorId, effect);
+            return this;
+        }
+
+        /**
+         * Combine all of the added effects into a combined effect.
+         *
+         * The {@link CombinedVibrationEffect.SyncedCombination} object is still valid after this
+         * call, so you can continue adding more effects to it and generating more
+         * {@link CombinedVibrationEffect}s by calling this method again.
+         *
+         * @return The {@link CombinedVibrationEffect} resulting from combining the added effects to
+         * be played in sync.
+         */
+        @NonNull
+        public CombinedVibrationEffect combine() {
+            if (mEffects.size() == 0) {
+                throw new IllegalStateException(
+                        "Combination must have at least one element to combine.");
+            }
+            CombinedVibrationEffect combined = new Stereo(mEffects);
+            combined.validate();
+            return combined;
+        }
+    }
+
+    /**
+     * A combination of haptic effects that should be played in multiple vibrators in sequence.
+     *
+     * @hide
+     * @see CombinedVibrationEffect#startSequential()
+     */
+    public static final class SequentialCombination {
+
+        private final ArrayList<CombinedVibrationEffect> mEffects = new ArrayList<>();
+        private final ArrayList<Integer> mDelays = new ArrayList<>();
+
+        SequentialCombination() {
+        }
+
+        /**
+         * Add a single vibration effect to be performed next.
+         *
+         * Similar to {@link #addNext(int, VibrationEffect, int)}, but with no delay.
+         *
+         * @param vibratorId The id of the vibrator that should perform this effect.
+         * @param effect     The effect this vibrator should play.
+         * @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
+         * multiple effects in one chain.
+         */
+        @NonNull
+        public SequentialCombination addNext(int vibratorId, @NonNull VibrationEffect effect) {
+            return addNext(vibratorId, effect, /* delay= */ 0);
+        }
+
+        /**
+         * Add a single vibration effect to be performed next.
+         *
+         * @param vibratorId The id of the vibrator that should perform this effect.
+         * @param effect     The effect this vibrator should play.
+         * @param delay      The amount of time, in milliseconds, to wait between playing the prior
+         *                   effect and this one.
+         * @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
+         * multiple effects in one chain.
+         */
+        @NonNull
+        public SequentialCombination addNext(int vibratorId, @NonNull VibrationEffect effect,
+                int delay) {
+            return addNext(
+                    CombinedVibrationEffect.startSynced().addVibrator(vibratorId, effect).combine(),
+                    delay);
+        }
+
+        /**
+         * Add a combined vibration effect to be performed next.
+         *
+         * Similar to {@link #addNext(CombinedVibrationEffect, int)}, but with no delay.
+         *
+         * @param effect The combined effect to be performed next.
+         * @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
+         * multiple effects in one chain.
+         * @see VibrationEffect#createOneShot(long, int)
+         */
+        @NonNull
+        public SequentialCombination addNext(@NonNull CombinedVibrationEffect effect) {
+            return addNext(effect, /* delay= */ 0);
+        }
+
+        /**
+         * Add a one shot vibration effect to be performed by the specified vibrator.
+         *
+         * @param effect The combined effect to be performed next.
+         * @param delay  The amount of time, in milliseconds, to wait between playing the prior
+         *               effect and this one.
+         * @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
+         * multiple effects in one chain.
+         */
+        @NonNull
+        public SequentialCombination addNext(@NonNull CombinedVibrationEffect effect, int delay) {
+            if (effect instanceof Sequential) {
+                Sequential sequentialEffect = (Sequential) effect;
+                int firstEffectIndex = mDelays.size();
+                mEffects.addAll(sequentialEffect.getEffects());
+                mDelays.addAll(sequentialEffect.getDelays());
+                mDelays.set(firstEffectIndex, delay + mDelays.get(firstEffectIndex));
+            } else {
+                mEffects.add(effect);
+                mDelays.add(delay);
+            }
+            return this;
+        }
+
+        /**
+         * Combine all of the added effects in sequence.
+         *
+         * The {@link CombinedVibrationEffect.SequentialCombination} object is still valid after
+         * this call, so you can continue adding more effects to it and generating more {@link
+         * CombinedVibrationEffect}s by calling this method again.
+         *
+         * @return The {@link CombinedVibrationEffect} resulting from combining the added effects to
+         * be played in sequence.
+         */
+        @NonNull
+        public CombinedVibrationEffect combine() {
+            if (mEffects.size() == 0) {
+                throw new IllegalStateException(
+                        "Combination must have at least one element to combine.");
+            }
+            CombinedVibrationEffect combined = new Sequential(mEffects, mDelays);
+            combined.validate();
+            return combined;
+        }
+    }
+
+    /**
      * Represents a single {@link VibrationEffect} that should be executed in all vibrators in sync.
      *
      * @hide
@@ -87,10 +276,10 @@
 
         @Override
         public boolean equals(Object o) {
-            if (!(o instanceof CombinedVibrationEffect.Mono)) {
+            if (!(o instanceof Mono)) {
                 return false;
             }
-            CombinedVibrationEffect.Mono other = (CombinedVibrationEffect.Mono) o;
+            Mono other = (Mono) o;
             return other.mEffect.equals(other.mEffect);
         }
 
@@ -128,6 +317,206 @@
                 };
     }
 
+    /**
+     * Represents a list of {@link VibrationEffect}s that should be executed in sync.
+     *
+     * @hide
+     */
+    public static final class Stereo extends CombinedVibrationEffect {
+
+        /** Mapping vibrator ids to effects. */
+        private final SparseArray<VibrationEffect> mEffects;
+
+        public Stereo(Parcel in) {
+            int size = in.readInt();
+            mEffects = new SparseArray<>(size);
+            for (int i = 0; i < size; i++) {
+                int vibratorId = in.readInt();
+                mEffects.put(vibratorId, VibrationEffect.CREATOR.createFromParcel(in));
+            }
+        }
+
+        public Stereo(@NonNull SparseArray<VibrationEffect> effects) {
+            mEffects = new SparseArray<>(effects.size());
+            for (int i = 0; i < effects.size(); i++) {
+                mEffects.put(effects.keyAt(i), effects.valueAt(i));
+            }
+        }
+
+        /** Effects to be performed in sync, where each key represents the vibrator id. */
+        public SparseArray<VibrationEffect> getEffects() {
+            return mEffects;
+        }
+
+        /** @hide */
+        @Override
+        public void validate() {
+            Preconditions.checkArgument(mEffects.size() > 0,
+                    "There should be at least one effect set for a combined effect");
+            for (int i = 0; i < mEffects.size(); i++) {
+                mEffects.valueAt(i).validate();
+            }
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof Stereo)) {
+                return false;
+            }
+            Stereo other = (Stereo) o;
+            if (mEffects.size() != other.mEffects.size()) {
+                return false;
+            }
+            for (int i = 0; i < mEffects.size(); i++) {
+                if (!mEffects.valueAt(i).equals(other.mEffects.get(mEffects.keyAt(i)))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mEffects);
+        }
+
+        @Override
+        public String toString() {
+            return "Stereo{mEffects=" + mEffects + '}';
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(PARCEL_TOKEN_STEREO);
+            out.writeInt(mEffects.size());
+            for (int i = 0; i < mEffects.size(); i++) {
+                out.writeInt(mEffects.keyAt(i));
+                mEffects.valueAt(i).writeToParcel(out, flags);
+            }
+        }
+
+        @NonNull
+        public static final Parcelable.Creator<Stereo> CREATOR =
+                new Parcelable.Creator<Stereo>() {
+                    @Override
+                    public Stereo createFromParcel(@NonNull Parcel in) {
+                        // Skip the type token
+                        in.readInt();
+                        return new Stereo(in);
+                    }
+
+                    @Override
+                    @NonNull
+                    public Stereo[] newArray(int size) {
+                        return new Stereo[size];
+                    }
+                };
+    }
+
+    /**
+     * Represents a list of {@link VibrationEffect}s that should be executed in sequence.
+     *
+     * @hide
+     */
+    public static final class Sequential extends CombinedVibrationEffect {
+        private final List<CombinedVibrationEffect> mEffects;
+        private final List<Integer> mDelays;
+
+        public Sequential(Parcel in) {
+            int size = in.readInt();
+            mEffects = new ArrayList<>(size);
+            mDelays = new ArrayList<>(size);
+            for (int i = 0; i < size; i++) {
+                mDelays.add(in.readInt());
+                mEffects.add(CombinedVibrationEffect.CREATOR.createFromParcel(in));
+            }
+        }
+
+        public Sequential(@NonNull List<CombinedVibrationEffect> effects,
+                @NonNull List<Integer> delays) {
+            mEffects = new ArrayList<>(effects);
+            mDelays = new ArrayList<>(delays);
+        }
+
+        /** Effects to be performed in sequence. */
+        public List<CombinedVibrationEffect> getEffects() {
+            return mEffects;
+        }
+
+        /** Delay to be applied before each effect in {@link #getEffects()}. */
+        public List<Integer> getDelays() {
+            return mDelays;
+        }
+
+        /** @hide */
+        @Override
+        public void validate() {
+            Preconditions.checkArgument(mEffects.size() > 0,
+                    "There should be at least one effect set for a combined effect");
+            Preconditions.checkArgument(mEffects.size() == mDelays.size(),
+                    "Effect and delays should have equal length");
+            for (long delay : mDelays) {
+                if (delay < 0) {
+                    throw new IllegalArgumentException("Delays must all be >= 0"
+                            + " (delays=" + mDelays + ")");
+                }
+            }
+            for (CombinedVibrationEffect effect : mEffects) {
+                if (effect instanceof Sequential) {
+                    throw new IllegalArgumentException(
+                            "There should be no nested sequential effects in a combined effect");
+                }
+                effect.validate();
+            }
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof Sequential)) {
+                return false;
+            }
+            Sequential other = (Sequential) o;
+            return mDelays.equals(other.mDelays) && mEffects.equals(other.mEffects);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mEffects);
+        }
+
+        @Override
+        public String toString() {
+            return "Sequential{mEffects=" + mEffects + ", mDelays=" + mDelays + '}';
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(PARCEL_TOKEN_SEQUENTIAL);
+            out.writeInt(mEffects.size());
+            for (int i = 0; i < mEffects.size(); i++) {
+                out.writeInt(mDelays.get(i));
+                mEffects.get(i).writeToParcel(out, flags);
+            }
+        }
+
+        @NonNull
+        public static final Parcelable.Creator<Sequential> CREATOR =
+                new Parcelable.Creator<Sequential>() {
+                    @Override
+                    public Sequential createFromParcel(@NonNull Parcel in) {
+                        // Skip the type token
+                        in.readInt();
+                        return new Sequential(in);
+                    }
+
+                    @Override
+                    @NonNull
+                    public Sequential[] newArray(int size) {
+                        return new Sequential[size];
+                    }
+                };
+    }
+
     @NonNull
     public static final Parcelable.Creator<CombinedVibrationEffect> CREATOR =
             new Parcelable.Creator<CombinedVibrationEffect>() {
@@ -135,7 +524,11 @@
                 public CombinedVibrationEffect createFromParcel(Parcel in) {
                     int token = in.readInt();
                     if (token == PARCEL_TOKEN_MONO) {
-                        return new CombinedVibrationEffect.Mono(in);
+                        return new Mono(in);
+                    } else if (token == PARCEL_TOKEN_STEREO) {
+                        return new Stereo(in);
+                    } else if (token == PARCEL_TOKEN_SEQUENTIAL) {
+                        return new Sequential(in);
                     } else {
                         throw new IllegalStateException(
                                 "Unexpected combined vibration event type token in parcel.");
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 2edd322..aba1f28 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -4033,7 +4033,8 @@
      * @return the {@link RemoveResult} code
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public @RemoveResult int removeUserOrSetEphemeral(@UserIdInt int userId) {
         try {
             return mService.removeUserOrSetEphemeral(userId);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cc3d92d..d22b62b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7761,6 +7761,21 @@
                 "minimal_post_processing_allowed";
 
         /**
+         * User's preference for refresh rate switching.
+         *
+         * <p>Values:
+         * 0 - Never switch refresh rates.
+         * 1 - Switch refresh rates only when it can be done seamlessly. (Default behaviour)
+         * 2 - Always prefer refresh rate switching even if it's going to have visual interruptions
+         *     for the user.
+         *
+         * @see android.view.Surface#setFrameRate
+         * @hide
+         */
+        public static final String MATCH_CONTENT_FRAME_RATE =
+                "match_content_frame_rate";
+
+        /**
          * INCALL_POWER_BUTTON_BEHAVIOR value for "turn off screen".
          * @hide
          */
@@ -9773,6 +9788,14 @@
         public static final String DEVELOPMENT_USE_BLAST_ADAPTER_SV =
                 "use_blast_adapter_sv";
 
+        /**
+         * If {@code true}, vendor provided window manager display settings will be ignored.
+         * (0 = false, 1 = true)
+         * @hide
+         */
+        public static final String DEVELOPMENT_IGNORE_VENDOR_DISPLAY_SETTINGS =
+                "ignore_vendor_display_settings";
+
        /**
         * Whether user has enabled development settings.
         */
@@ -10700,7 +10723,7 @@
          *    0 = Disabled
          *    1 = Enabled
          *
-         * Most readers of this setting should simply check if value == 1 to determined the
+         * Most readers of this setting should simply check if value == 1 to determine the
          * enabled state.
          * @hide
          * @deprecated To be removed.
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index f08756a..e32ffa6 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -157,6 +157,11 @@
     public static final int HW_AUTH_PASSWORD = 1 << 0;
     public static final int HW_AUTH_BIOMETRIC = 1 << 1;
 
+    // Security Levels.
+    public static final int KM_SECURITY_LEVEL_SOFTWARE = 0;
+    public static final int KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1;
+    public static final int KM_SECURITY_LEVEL_STRONGBOX = 2;
+
     // Error codes.
     public static final int KM_ERROR_OK = 0;
     public static final int KM_ERROR_ROOT_OF_TRUST_ALREADY_SET = -1;
diff --git a/core/java/android/service/autofill/InlinePresentation.java b/core/java/android/service/autofill/InlinePresentation.java
index 6eb2a15..fbf23b6 100644
--- a/core/java/android/service/autofill/InlinePresentation.java
+++ b/core/java/android/service/autofill/InlinePresentation.java
@@ -77,7 +77,7 @@
 
 
 
-    // Code below generated by codegen v1.0.15.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -259,10 +259,10 @@
     };
 
     @DataClass.Generated(
-            time = 1596484869201L,
-            codegenVersion = "1.0.15",
+            time = 1604456277638L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/core/java/android/service/autofill/InlinePresentation.java",
-            inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final  boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size(min=0L) java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)")
+            inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final  boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
index 2a809b1..4ffffc6 100644
--- a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
+++ b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
@@ -46,12 +46,13 @@
  * CarrierMessagingService.
  * @hide
  */
-public abstract class CarrierMessagingServiceWrapper {
+public final class CarrierMessagingServiceWrapper {
     // Populated by bindToCarrierMessagingService. bindToCarrierMessagingService must complete
     // prior to calling disposeConnection so that mCarrierMessagingServiceConnection is initialized.
     private volatile CarrierMessagingServiceConnection mCarrierMessagingServiceConnection;
 
     private volatile ICarrierMessagingService mICarrierMessagingService;
+    private Runnable mOnServiceReadyCallback;
 
     /**
      * Binds to the carrier messaging service under package {@code carrierPackageName}. This method
@@ -63,12 +64,14 @@
      * @hide
      */
     public boolean bindToCarrierMessagingService(@NonNull Context context,
-            @NonNull String carrierPackageName) {
+            @NonNull String carrierPackageName,
+            @NonNull Runnable onServiceReadyCallback) {
         Preconditions.checkState(mCarrierMessagingServiceConnection == null);
 
         Intent intent = new Intent(CarrierMessagingService.SERVICE_INTERFACE);
         intent.setPackage(carrierPackageName);
         mCarrierMessagingServiceConnection = new CarrierMessagingServiceConnection();
+        mOnServiceReadyCallback = onServiceReadyCallback;
         return context.bindService(intent, mCarrierMessagingServiceConnection,
                 Context.BIND_AUTO_CREATE);
     }
@@ -83,22 +86,17 @@
         Preconditions.checkNotNull(mCarrierMessagingServiceConnection);
         context.unbindService(mCarrierMessagingServiceConnection);
         mCarrierMessagingServiceConnection = null;
+        mOnServiceReadyCallback = null;
     }
 
     /**
-     * Implemented by subclasses to use the carrier messaging service once it is ready.
-     * @hide
-     */
-    public abstract void onServiceReady();
-
-    /**
      * Called when connection with service is established.
      *
      * @param carrierMessagingService the carrier messaing service interface
      */
     private void onServiceReady(ICarrierMessagingService carrierMessagingService) {
         mICarrierMessagingService = carrierMessagingService;
-        onServiceReady();
+        if (mOnServiceReadyCallback != null) mOnServiceReadyCallback.run();
     }
 
     /**
@@ -113,11 +111,11 @@
      * @hide
      */
     public void filterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort,
-            int subId, @NonNull final CarrierMessagingCallbackWrapper callback) {
+            int subId, @NonNull final CarrierMessagingCallback callback) {
         if (mICarrierMessagingService != null) {
             try {
                 mICarrierMessagingService.filterSms(pdu, format, destPort, subId,
-                        new CarrierMessagingCallbackWrapperInternal(callback));
+                        new CarrierMessagingCallbackInternal(callback));
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -137,11 +135,11 @@
      * @hide
      */
     public void sendTextSms(@NonNull String text, int subId, @NonNull String destAddress,
-            int sendSmsFlag, @NonNull final CarrierMessagingCallbackWrapper callback) {
+            int sendSmsFlag, @NonNull final CarrierMessagingCallback callback) {
         if (mICarrierMessagingService != null) {
             try {
                 mICarrierMessagingService.sendTextSms(text, subId, destAddress, sendSmsFlag,
-                        new CarrierMessagingCallbackWrapperInternal(callback));
+                        new CarrierMessagingCallbackInternal(callback));
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -163,11 +161,11 @@
      */
     public void sendDataSms(@NonNull byte[] data, int subId, @NonNull String destAddress,
             int destPort, int sendSmsFlag,
-            @NonNull final CarrierMessagingCallbackWrapper callback) {
+            @NonNull final CarrierMessagingCallback callback) {
         if (mICarrierMessagingService != null) {
             try {
                 mICarrierMessagingService.sendDataSms(data, subId, destAddress, destPort,
-                        sendSmsFlag, new CarrierMessagingCallbackWrapperInternal(callback));
+                        sendSmsFlag, new CarrierMessagingCallbackInternal(callback));
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -188,11 +186,11 @@
      */
     public void sendMultipartTextSms(@NonNull List<String> parts, int subId,
             @NonNull String destAddress, int sendSmsFlag,
-            @NonNull final CarrierMessagingCallbackWrapper callback) {
+            @NonNull final CarrierMessagingCallback callback) {
         if (mICarrierMessagingService != null) {
             try {
                 mICarrierMessagingService.sendMultipartTextSms(parts, subId, destAddress,
-                        sendSmsFlag, new CarrierMessagingCallbackWrapperInternal(callback));
+                        sendSmsFlag, new CarrierMessagingCallbackInternal(callback));
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -212,11 +210,11 @@
      * @hide
      */
     public void sendMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
-            @NonNull final CarrierMessagingCallbackWrapper callback) {
+            @NonNull final CarrierMessagingCallback callback) {
         if (mICarrierMessagingService != null) {
             try {
                 mICarrierMessagingService.sendMms(pduUri, subId, location,
-                        new CarrierMessagingCallbackWrapperInternal(callback));
+                        new CarrierMessagingCallbackInternal(callback));
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -235,11 +233,11 @@
      * @hide
      */
     public void downloadMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
-            @NonNull final CarrierMessagingCallbackWrapper callback) {
+            @NonNull final CarrierMessagingCallback callback) {
         if (mICarrierMessagingService != null) {
             try {
                 mICarrierMessagingService.downloadMms(pduUri, subId, location,
-                        new CarrierMessagingCallbackWrapperInternal(callback));
+                        new CarrierMessagingCallbackInternal(callback));
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -265,7 +263,7 @@
      * {@link CarrierMessagingServiceWrapper}.
      * @hide
      */
-    public abstract static class CarrierMessagingCallbackWrapper {
+    public interface CarrierMessagingCallback {
 
         /**
          * Response callback for {@link CarrierMessagingServiceWrapper#filterSms}.
@@ -277,7 +275,7 @@
          *               {@see CarrierMessagingService#onReceiveTextSms}.
          * @hide
          */
-        public void onFilterComplete(int result) {
+        default void onFilterComplete(int result) {
 
         }
 
@@ -291,7 +289,7 @@
          *                   only if result is {@link CarrierMessagingService#SEND_STATUS_OK}.
          * @hide
          */
-        public void onSendSmsComplete(int result, int messageRef) {
+        default void onSendSmsComplete(int result, int messageRef) {
 
         }
 
@@ -305,7 +303,7 @@
          *                    {@link CarrierMessagingService#SEND_STATUS_OK}.
          * @hide
          */
-        public void onSendMultipartSmsComplete(int result, @Nullable int[] messageRefs) {
+        default void onSendMultipartSmsComplete(int result, @Nullable int[] messageRefs) {
 
         }
 
@@ -319,7 +317,7 @@
          *                    {@link CarrierMessagingService#SEND_STATUS_OK}.
          * @hide
          */
-        public void onSendMmsComplete(int result, @Nullable byte[] sendConfPdu) {
+        default void onSendMmsComplete(int result, @Nullable byte[] sendConfPdu) {
 
         }
 
@@ -330,43 +328,43 @@
          *               and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
          * @hide
          */
-        public void onDownloadMmsComplete(int result) {
+        default void onDownloadMmsComplete(int result) {
 
         }
     }
 
-    private final class CarrierMessagingCallbackWrapperInternal
+    private final class CarrierMessagingCallbackInternal
             extends ICarrierMessagingCallback.Stub {
-        CarrierMessagingCallbackWrapper mCarrierMessagingCallbackWrapper;
+        CarrierMessagingCallback mCarrierMessagingCallback;
 
-        CarrierMessagingCallbackWrapperInternal(CarrierMessagingCallbackWrapper callback) {
-            mCarrierMessagingCallbackWrapper = callback;
+        CarrierMessagingCallbackInternal(CarrierMessagingCallback callback) {
+            mCarrierMessagingCallback = callback;
         }
 
         @Override
         public void onFilterComplete(int result) throws RemoteException {
-            mCarrierMessagingCallbackWrapper.onFilterComplete(result);
+            mCarrierMessagingCallback.onFilterComplete(result);
         }
 
         @Override
         public void onSendSmsComplete(int result, int messageRef) throws RemoteException {
-            mCarrierMessagingCallbackWrapper.onSendSmsComplete(result, messageRef);
+            mCarrierMessagingCallback.onSendSmsComplete(result, messageRef);
         }
 
         @Override
         public void onSendMultipartSmsComplete(int result, int[] messageRefs)
                 throws RemoteException {
-            mCarrierMessagingCallbackWrapper.onSendMultipartSmsComplete(result, messageRefs);
+            mCarrierMessagingCallback.onSendMultipartSmsComplete(result, messageRefs);
         }
 
         @Override
         public void onSendMmsComplete(int result, byte[] sendConfPdu) throws RemoteException {
-            mCarrierMessagingCallbackWrapper.onSendMmsComplete(result, sendConfPdu);
+            mCarrierMessagingCallback.onSendMmsComplete(result, sendConfPdu);
         }
 
         @Override
         public void onDownloadMmsComplete(int result) throws RemoteException {
-            mCarrierMessagingCallbackWrapper.onDownloadMmsComplete(result);
+            mCarrierMessagingCallback.onDownloadMmsComplete(result);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index f19e7d2..bac7c6c 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -18,6 +18,7 @@
 
 import android.util.TimeFormatException;
 
+import com.android.i18n.timezone.WallTime;
 import com.android.i18n.timezone.ZoneInfoData;
 import com.android.i18n.timezone.ZoneInfoDb;
 
@@ -1070,7 +1071,7 @@
      * to the enclosing object, but others do not: thus separate state is retained.
      */
     private static class TimeCalculator {
-        public final ZoneInfoData.WallTime wallTime;
+        public final WallTime wallTime;
         public String timezone;
 
         // Information about the current timezone.
@@ -1078,7 +1079,7 @@
 
         public TimeCalculator(String timezoneId) {
             this.mZoneInfoData = lookupZoneInfoData(timezoneId);
-            this.wallTime = new ZoneInfoData.WallTime();
+            this.wallTime = new WallTime();
         }
 
         public long toMillis(boolean ignoreDst) {
diff --git a/core/java/android/text/format/TimeFormatter.java b/core/java/android/text/format/TimeFormatter.java
index c71dfbb..e42ad63 100644
--- a/core/java/android/text/format/TimeFormatter.java
+++ b/core/java/android/text/format/TimeFormatter.java
@@ -24,6 +24,7 @@
 import android.icu.text.DateFormatSymbols;
 import android.icu.text.DecimalFormatSymbols;
 
+import com.android.i18n.timezone.WallTime;
 import com.android.i18n.timezone.ZoneInfoData;
 
 import java.nio.CharBuffer;
@@ -149,7 +150,7 @@
     /**
      * Format the specified {@code wallTime} using {@code pattern}. The output is returned.
      */
-    public String format(String pattern, ZoneInfoData.WallTime wallTime,
+    public String format(String pattern, WallTime wallTime,
             ZoneInfoData zoneInfoData) {
         try {
             StringBuilder stringBuilder = new StringBuilder();
@@ -192,7 +193,7 @@
      * Format the specified {@code wallTime} using {@code pattern}. The output is written to
      * {@link #outputBuilder}.
      */
-    private void formatInternal(String pattern, ZoneInfoData.WallTime wallTime,
+    private void formatInternal(String pattern, WallTime wallTime,
             ZoneInfoData zoneInfoData) {
         CharBuffer formatBuffer = CharBuffer.wrap(pattern);
         while (formatBuffer.remaining() > 0) {
@@ -208,7 +209,7 @@
         }
     }
 
-    private boolean handleToken(CharBuffer formatBuffer, ZoneInfoData.WallTime wallTime,
+    private boolean handleToken(CharBuffer formatBuffer, WallTime wallTime,
             ZoneInfoData zoneInfoData) {
 
         // The char at formatBuffer.position() is expected to be '%' at this point.
diff --git a/core/java/android/timezone/TzDataSetVersion.java b/core/java/android/timezone/TzDataSetVersion.java
index edcbbb3..4031ff8 100644
--- a/core/java/android/timezone/TzDataSetVersion.java
+++ b/core/java/android/timezone/TzDataSetVersion.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 
+import com.android.i18n.timezone.TimeZoneDataFiles;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.IOException;
@@ -76,8 +77,7 @@
     @NonNull
     public static TzDataSetVersion read() throws IOException, TzDataSetException {
         try {
-            return new TzDataSetVersion(
-                    com.android.i18n.timezone.TzDataSetVersion.readTimeZoneModuleVersion());
+            return new TzDataSetVersion(TimeZoneDataFiles.readTimeZoneModuleVersion());
         } catch (com.android.i18n.timezone.TzDataSetVersion.TzDataSetException e) {
             throw new TzDataSetException(e.getMessage(), e);
         }
diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java
index c3e2ecc..33bc121 100644
--- a/core/java/android/uwb/AngleMeasurement.java
+++ b/core/java/android/uwb/AngleMeasurement.java
@@ -17,6 +17,10 @@
 package android.uwb;
 
 import android.annotation.FloatRange;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
 
 /**
  * Angle measurement
@@ -26,7 +30,7 @@
  *
  * @hide
  */
-public final class AngleMeasurement {
+public final class AngleMeasurement implements Parcelable {
     private final double mRadians;
     private final double mErrorRadians;
     private final double mConfidenceLevel;
@@ -39,7 +43,7 @@
 
     /**
      * Angle measurement in radians
-    *
+     *
      * @return angle in radians
      */
     @FloatRange(from = -Math.PI, to = +Math.PI)
@@ -74,6 +78,61 @@
     }
 
     /**
+     * @hide
+    */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof AngleMeasurement) {
+            AngleMeasurement other = (AngleMeasurement) obj;
+            return mRadians == other.getRadians()
+                    && mErrorRadians == other.getErrorRadians()
+                    && mConfidenceLevel == other.getConfidenceLevel();
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRadians, mErrorRadians, mConfidenceLevel);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeDouble(mRadians);
+        dest.writeDouble(mErrorRadians);
+        dest.writeDouble(mConfidenceLevel);
+    }
+
+    public static final @android.annotation.NonNull Creator<AngleMeasurement> CREATOR =
+            new Creator<AngleMeasurement>() {
+                @Override
+                public AngleMeasurement createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.setRadians(in.readDouble());
+                    builder.setErrorRadians(in.readDouble());
+                    builder.setConfidenceLevel(in.readDouble());
+                    return builder.build();
+                }
+
+                @Override
+                public AngleMeasurement[] newArray(int size) {
+                    return new AngleMeasurement[size];
+                }
+    };
+
+    /**
      * Builder class for {@link AngleMeasurement}.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java
index a7b5eae..cd5af69 100644
--- a/core/java/android/uwb/AngleOfArrivalMeasurement.java
+++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java
@@ -18,13 +18,17 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
 
 /**
  * Represents an angle of arrival measurement between two devices using Ultra Wideband
  *
  * @hide
  */
-public final class AngleOfArrivalMeasurement {
+public final class AngleOfArrivalMeasurement implements Parcelable {
     private final AngleMeasurement mAzimuthAngleMeasurement;
     private final AngleMeasurement mAltitudeAngleMeasurement;
 
@@ -71,6 +75,63 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof AngleOfArrivalMeasurement) {
+            AngleOfArrivalMeasurement other = (AngleOfArrivalMeasurement) obj;
+            return mAzimuthAngleMeasurement.equals(other.getAzimuth())
+                    && mAltitudeAngleMeasurement.equals(other.getAltitude());
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAzimuthAngleMeasurement, mAltitudeAngleMeasurement);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mAzimuthAngleMeasurement, flags);
+        dest.writeParcelable(mAltitudeAngleMeasurement, flags);
+    }
+
+    public static final @android.annotation.NonNull Creator<AngleOfArrivalMeasurement> CREATOR =
+            new Creator<AngleOfArrivalMeasurement>() {
+                @Override
+                public AngleOfArrivalMeasurement createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+
+                    builder.setAzimuthAngleMeasurement(
+                            in.readParcelable(AngleMeasurement.class.getClassLoader()));
+
+                    builder.setAltitudeAngleMeasurement(
+                            in.readParcelable(AngleMeasurement.class.getClassLoader()));
+
+                    return builder.build();
+                }
+
+                @Override
+                public AngleOfArrivalMeasurement[] newArray(int size) {
+                    return new AngleOfArrivalMeasurement[size];
+                }
+            };
+
+    /**
      * Builder class for {@link AngleOfArrivalMeasurement}.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/DistanceMeasurement.java b/core/java/android/uwb/DistanceMeasurement.java
index 4cd5d83..c959840 100644
--- a/core/java/android/uwb/DistanceMeasurement.java
+++ b/core/java/android/uwb/DistanceMeasurement.java
@@ -17,6 +17,11 @@
 package android.uwb;
 
 import android.annotation.FloatRange;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
 
 /**
  * A data point for the distance measurement
@@ -26,7 +31,7 @@
  *
  * @hide
  */
-public final class DistanceMeasurement {
+public final class DistanceMeasurement implements Parcelable {
     private final double mMeters;
     private final double mErrorMeters;
     private final double mConfidenceLevel;
@@ -70,6 +75,61 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof DistanceMeasurement) {
+            DistanceMeasurement other = (DistanceMeasurement) obj;
+            return mMeters == other.getMeters()
+                    && mErrorMeters == other.getErrorMeters()
+                    && mConfidenceLevel == other.getConfidenceLevel();
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mMeters, mErrorMeters, mConfidenceLevel);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeDouble(mMeters);
+        dest.writeDouble(mErrorMeters);
+        dest.writeDouble(mConfidenceLevel);
+    }
+
+    public static final @android.annotation.NonNull Creator<DistanceMeasurement> CREATOR =
+            new Creator<DistanceMeasurement>() {
+                @Override
+                public DistanceMeasurement createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.setMeters(in.readDouble());
+                    builder.setErrorMeters(in.readDouble());
+                    builder.setConfidenceLevel(in.readDouble());
+                    return builder.build();
+                }
+
+                @Override
+                public DistanceMeasurement[] newArray(int size) {
+                    return new DistanceMeasurement[size];
+                }
+    };
+
+    /**
      * Builder to get a {@link DistanceMeasurement} object.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/RangingMeasurement.java b/core/java/android/uwb/RangingMeasurement.java
index 33a34e3..f1c3162 100644
--- a/core/java/android/uwb/RangingMeasurement.java
+++ b/core/java/android/uwb/RangingMeasurement.java
@@ -20,17 +20,20 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.SystemClock;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
 
 /**
  * Representation of a ranging measurement between the local device and a remote device
  *
  * @hide
  */
-public final class RangingMeasurement {
+public final class RangingMeasurement implements Parcelable {
     private final UwbAddress mRemoteDeviceAddress;
     private final @Status int mStatus;
     private final long mElapsedRealtimeNanos;
@@ -128,6 +131,71 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof RangingMeasurement) {
+            RangingMeasurement other = (RangingMeasurement) obj;
+            return mRemoteDeviceAddress.equals(other.getRemoteDeviceAddress())
+                    && mStatus == other.getStatus()
+                    && mElapsedRealtimeNanos == other.getElapsedRealtimeNanos()
+                    && mDistanceMeasurement.equals(other.getDistance())
+                    && mAngleOfArrivalMeasurement.equals(other.getAngleOfArrival());
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRemoteDeviceAddress, mStatus, mElapsedRealtimeNanos,
+                mDistanceMeasurement, mAngleOfArrivalMeasurement);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mRemoteDeviceAddress, flags);
+        dest.writeInt(mStatus);
+        dest.writeLong(mElapsedRealtimeNanos);
+        dest.writeParcelable(mDistanceMeasurement, flags);
+        dest.writeParcelable(mAngleOfArrivalMeasurement, flags);
+    }
+
+    public static final @android.annotation.NonNull Creator<RangingMeasurement> CREATOR =
+            new Creator<RangingMeasurement>() {
+                @Override
+                public RangingMeasurement createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.setRemoteDeviceAddress(
+                            in.readParcelable(UwbAddress.class.getClassLoader()));
+                    builder.setStatus(in.readInt());
+                    builder.setElapsedRealtimeNanos(in.readLong());
+                    builder.setDistanceMeasurement(
+                            in.readParcelable(DistanceMeasurement.class.getClassLoader()));
+                    builder.setAngleOfArrivalMeasurement(
+                            in.readParcelable(AngleOfArrivalMeasurement.class.getClassLoader()));
+                    return builder.build();
+                }
+
+                @Override
+                public RangingMeasurement[] newArray(int size) {
+                    return new RangingMeasurement[size];
+                }
+    };
+
+    /**
      * Builder for a {@link RangingMeasurement} object.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/RangingParams.java b/core/java/android/uwb/RangingParams.java
index a50de3e6..f23d9ed 100644
--- a/core/java/android/uwb/RangingParams.java
+++ b/core/java/android/uwb/RangingParams.java
@@ -19,15 +19,18 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.PersistableBundle;
-import android.util.Duration;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -36,7 +39,7 @@
  *
  *  @hide
  */
-public final class RangingParams {
+public final class RangingParams implements Parcelable {
     private final boolean mIsInitiator;
     private final boolean mIsController;
     private final Duration mSamplePeriod;
@@ -200,6 +203,99 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof RangingParams) {
+            RangingParams other = (RangingParams) obj;
+
+            return mIsInitiator == other.mIsInitiator
+                    && mIsController == other.mIsController
+                    && mSamplePeriod.equals(other.mSamplePeriod)
+                    && mLocalDeviceAddress.equals(other.mLocalDeviceAddress)
+                    && mRemoteDeviceAddresses.equals(other.mRemoteDeviceAddresses)
+                    && mChannelNumber == other.mChannelNumber
+                    && mTransmitPreambleCodeIndex == other.mTransmitPreambleCodeIndex
+                    && mReceivePreambleCodeIndex == other.mReceivePreambleCodeIndex
+                    && mStsPhyPacketType == other.mStsPhyPacketType
+                    && mSpecificationParameters.size() == other.mSpecificationParameters.size()
+                    && mSpecificationParameters.kindofEquals(other.mSpecificationParameters);
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mIsInitiator, mIsController, mSamplePeriod, mLocalDeviceAddress,
+                mRemoteDeviceAddresses, mChannelNumber, mTransmitPreambleCodeIndex,
+                mReceivePreambleCodeIndex, mStsPhyPacketType, mSpecificationParameters);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBoolean(mIsInitiator);
+        dest.writeBoolean(mIsController);
+        dest.writeLong(mSamplePeriod.getSeconds());
+        dest.writeInt(mSamplePeriod.getNano());
+        dest.writeParcelable(mLocalDeviceAddress, flags);
+
+        UwbAddress[] remoteAddresses = new UwbAddress[mRemoteDeviceAddresses.size()];
+        mRemoteDeviceAddresses.toArray(remoteAddresses);
+        dest.writeParcelableArray(remoteAddresses, flags);
+
+        dest.writeInt(mChannelNumber);
+        dest.writeInt(mTransmitPreambleCodeIndex);
+        dest.writeInt(mReceivePreambleCodeIndex);
+        dest.writeInt(mStsPhyPacketType);
+        dest.writePersistableBundle(mSpecificationParameters);
+    }
+
+    public static final @android.annotation.NonNull Creator<RangingParams> CREATOR =
+            new Creator<RangingParams>() {
+                @Override
+                public RangingParams createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.setIsInitiator(in.readBoolean());
+                    builder.setIsController(in.readBoolean());
+                    builder.setSamplePeriod(Duration.ofSeconds(in.readLong(), in.readInt()));
+                    builder.setLocalDeviceAddress(
+                            in.readParcelable(UwbAddress.class.getClassLoader()));
+
+                    UwbAddress[] remoteAddresses =
+                            in.readParcelableArray(null, UwbAddress.class);
+                    for (UwbAddress remoteAddress : remoteAddresses) {
+                        builder.addRemoteDeviceAddress(remoteAddress);
+                    }
+
+                    builder.setChannelNumber(in.readInt());
+                    builder.setTransmitPreambleCodeIndex(in.readInt());
+                    builder.setReceivePreambleCodeIndex(in.readInt());
+                    builder.setStsPhPacketType(in.readInt());
+                    builder.setSpecificationParameters(in.readPersistableBundle());
+
+                    return builder.build();
+                }
+
+                @Override
+                public RangingParams[] newArray(int size) {
+                    return new RangingParams[size];
+                }
+    };
+
+    /**
      * Builder class for {@link RangingParams}.
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/RangingReport.java b/core/java/android/uwb/RangingReport.java
index 5aca12a..45180bf 100644
--- a/core/java/android/uwb/RangingReport.java
+++ b/core/java/android/uwb/RangingReport.java
@@ -17,16 +17,20 @@
 package android.uwb;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * This class contains the UWB ranging data
  *
  * @hide
  */
-public final class RangingReport {
+public final class RangingReport implements Parcelable {
     private final List<RangingMeasurement> mRangingMeasurements;
 
     private RangingReport(@NonNull List<RangingMeasurement> rangingMeasurements) {
@@ -49,6 +53,56 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof RangingReport) {
+            RangingReport other = (RangingReport) obj;
+            return mRangingMeasurements.equals(other.getMeasurements());
+        }
+
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRangingMeasurements);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeTypedList(mRangingMeasurements);
+    }
+
+    public static final @android.annotation.NonNull Creator<RangingReport> CREATOR =
+            new Creator<RangingReport>() {
+                @Override
+                public RangingReport createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    builder.addMeasurements(in.createTypedArrayList(RangingMeasurement.CREATOR));
+                    return builder.build();
+                }
+
+                @Override
+                public RangingReport[] newArray(int size) {
+                    return new RangingReport[size];
+                }
+    };
+
+    /**
      * Builder for {@link RangingReport} object
      */
     public static final class Builder {
diff --git a/core/java/android/uwb/TEST_MAPPING b/core/java/android/uwb/TEST_MAPPING
new file mode 100644
index 0000000..9e50bd6
--- /dev/null
+++ b/core/java/android/uwb/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "UwbManagerTests"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/core/java/android/uwb/UwbAddress.java b/core/java/android/uwb/UwbAddress.java
index 48fcb10e..828324c 100644
--- a/core/java/android/uwb/UwbAddress.java
+++ b/core/java/android/uwb/UwbAddress.java
@@ -18,16 +18,26 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
 
 /**
  * A class representing a UWB address
  *
  * @hide
  */
-public final class UwbAddress {
+public final class UwbAddress implements Parcelable {
     public static final int SHORT_ADDRESS_BYTE_LENGTH = 2;
     public static final int EXTENDED_ADDRESS_BYTE_LENGTH = 8;
 
+    private final byte[] mAddressBytes;
+
+    private UwbAddress(byte[] address) {
+        mAddressBytes = address;
+    }
+
     /**
      * Create a {@link UwbAddress} from a byte array.
      *
@@ -37,12 +47,16 @@
      *
      * @param address a byte array to convert to a {@link UwbAddress}
      * @return a {@link UwbAddress} created from the input byte array
-     * @throw IllegableArumentException when the length is not one of
+     * @throws IllegalArgumentException when the length is not one of
      *       {@link #SHORT_ADDRESS_BYTE_LENGTH} or {@link #EXTENDED_ADDRESS_BYTE_LENGTH} bytes
      */
     @NonNull
-    public static UwbAddress fromBytes(byte[] address) throws IllegalArgumentException {
-        throw new UnsupportedOperationException();
+    public static UwbAddress fromBytes(@NonNull byte[] address) throws IllegalArgumentException {
+        if (address.length != SHORT_ADDRESS_BYTE_LENGTH
+                && address.length != EXTENDED_ADDRESS_BYTE_LENGTH) {
+            throw new IllegalArgumentException("Invalid UwbAddress length " + address.length);
+        }
+        return new UwbAddress(address);
     }
 
     /**
@@ -52,7 +66,7 @@
      */
     @NonNull
     public byte[] toBytes() {
-        throw new UnsupportedOperationException();
+        return mAddressBytes;
     }
 
     /**
@@ -61,22 +75,55 @@
      * {@link #EXTENDED_ADDRESS_BYTE_LENGTH}.
      */
     public int size() {
-        throw new UnsupportedOperationException();
+        return mAddressBytes.length;
     }
 
     @NonNull
     @Override
     public String toString() {
-        throw new UnsupportedOperationException();
+        StringBuilder builder = new StringBuilder("0x");
+        for (byte addressByte : mAddressBytes) {
+            builder.append(String.format("%02X", addressByte));
+        }
+        return builder.toString();
     }
 
     @Override
     public boolean equals(@Nullable Object obj) {
-        throw new UnsupportedOperationException();
+        if (obj instanceof UwbAddress) {
+            return Arrays.equals(mAddressBytes, ((UwbAddress) obj).toBytes());
+        }
+        return false;
     }
 
     @Override
     public int hashCode() {
-        throw new UnsupportedOperationException();
+        return Arrays.hashCode(mAddressBytes);
     }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mAddressBytes.length);
+        dest.writeByteArray(mAddressBytes);
+    }
+
+    public static final @android.annotation.NonNull Creator<UwbAddress> CREATOR =
+            new Creator<UwbAddress>() {
+                @Override
+                public UwbAddress createFromParcel(Parcel in) {
+                    byte[] address = new byte[in.readInt()];
+                    in.readByteArray(address);
+                    return UwbAddress.fromBytes(address);
+                }
+
+                @Override
+                public UwbAddress[] newArray(int size) {
+                    return new UwbAddress[size];
+                }
+    };
 }
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 5780d4f..f4d5a7b 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.os.Trace.TRACE_TAG_VIEW;
 import static android.view.ImeInsetsSourceConsumerProto.INSETS_SOURCE_CONSUMER;
 import static android.view.ImeInsetsSourceConsumerProto.IS_REQUESTED_VISIBLE_AWAITING_CONTROL;
 import static android.view.InsetsController.AnimationType;
@@ -24,6 +25,7 @@
 import android.annotation.Nullable;
 import android.inputmethodservice.InputMethodService;
 import android.os.IBinder;
+import android.os.Trace;
 import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl.Transaction;
 import android.view.inputmethod.InputMethodManager;
@@ -105,6 +107,7 @@
     @Override
     void notifyHidden() {
         getImm().notifyImeHidden(mController.getHost().getWindowToken());
+        Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
     }
 
     @Override
diff --git a/core/java/android/view/InputApplicationHandle.java b/core/java/android/view/InputApplicationHandle.java
index 108345e..4abffde 100644
--- a/core/java/android/view/InputApplicationHandle.java
+++ b/core/java/android/view/InputApplicationHandle.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.NonNull;
 import android.os.IBinder;
 
 /**
@@ -31,17 +32,20 @@
     private long ptr;
 
     // Application name.
-    public String name;
+    public final @NonNull String name;
 
     // Dispatching timeout.
-    public long dispatchingTimeoutMillis;
+    public final long dispatchingTimeoutMillis;
 
-    public final IBinder token;
+    public final @NonNull IBinder token;
 
     private native void nativeDispose();
 
-    public InputApplicationHandle(IBinder token) {
+    public InputApplicationHandle(@NonNull IBinder token, @NonNull String name,
+            long dispatchingTimeoutMillis) {
         this.token = token;
+        this.name = name;
+        this.dispatchingTimeoutMillis = dispatchingTimeoutMillis;
     }
 
     public InputApplicationHandle(InputApplicationHandle handle) {
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index d1a9a05..5a34a92 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -37,7 +37,7 @@
     private long ptr;
 
     // The input application handle.
-    public final InputApplicationHandle inputApplicationHandle;
+    public InputApplicationHandle inputApplicationHandle;
 
     // The token associates input data with a window and its input channel. The client input
     // channel and the server input channel will both contain this token.
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index b5bf084..fbee833 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.os.Trace.TRACE_TAG_VIEW;
 import static android.view.InsetsControllerProto.CONTROL;
 import static android.view.InsetsControllerProto.STATE;
 import static android.view.InsetsState.ITYPE_CAPTION_BAR;
@@ -829,6 +830,11 @@
     public void show(@InsetsType int types, boolean fromIme) {
         if (fromIme) {
             ImeTracing.getInstance().triggerDump();
+            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
+            Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.showRequestFromIme", 0);
+        } else {
+            Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0);
+            Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
         }
         // Handle pending request ready in case there was one set.
         if (fromIme && mPendingImeControlRequest != null) {
@@ -880,6 +886,9 @@
     void hide(@InsetsType int types, boolean fromIme) {
         if (fromIme) {
             ImeTracing.getInstance().triggerDump();
+            Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.hideRequestFromIme", 0);
+        } else {
+            Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
         }
         int typesReady = 0;
         final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
@@ -989,6 +998,7 @@
                 });
             }
             updateRequestedVisibility();
+            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0);
             return;
         }
 
@@ -1014,11 +1024,13 @@
             cancellationSignal.setOnCancelListener(() -> {
                 cancelAnimation(runner, true /* invokeCallback */);
             });
+        } else {
+            Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.pendingAnim", 0);
         }
         if (layoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN) {
-            showDirectly(types);
+            showDirectly(types, fromIme);
         } else {
-            hideDirectly(types, false /* animationFinished */, animationType);
+            hideDirectly(types, false /* animationFinished */, animationType, fromIme);
         }
         updateRequestedVisibility();
     }
@@ -1141,10 +1153,10 @@
         cancelAnimation(runner, false /* invokeCallback */);
         if (DEBUG) Log.d(TAG, "notifyFinished. shown: " + shown);
         if (shown) {
-            showDirectly(runner.getTypes());
+            showDirectly(runner.getTypes(), true /* fromIme */);
         } else {
             hideDirectly(runner.getTypes(), true /* animationFinished */,
-                    runner.getAnimationType());
+                    runner.getAnimationType(), true /* fromIme */);
         }
     }
 
@@ -1314,11 +1326,11 @@
                 show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
                 show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN,
                 !hasAnimationCallbacks /* useInsetsAnimationThread */);
-
     }
 
     private void hideDirectly(
-            @InsetsType int types, boolean animationFinished, @AnimationType int animationType) {
+            @InsetsType int types, boolean animationFinished, @AnimationType int animationType,
+            boolean fromIme) {
         if ((types & ime()) != 0) {
             ImeTracing.getInstance().triggerDump();
         }
@@ -1327,9 +1339,13 @@
             getSourceConsumer(internalTypes.valueAt(i)).hide(animationFinished, animationType);
         }
         updateRequestedVisibility();
+
+        if (fromIme) {
+            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromIme", 0);
+        }
     }
 
-    private void showDirectly(@InsetsType int types) {
+    private void showDirectly(@InsetsType int types, boolean fromIme) {
         if ((types & ime()) != 0) {
             ImeTracing.getInstance().triggerDump();
         }
@@ -1338,6 +1354,10 @@
             getSourceConsumer(internalTypes.valueAt(i)).show(false /* fromIme */);
         }
         updateRequestedVisibility();
+
+        if (fromIme) {
+            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromIme", 0);
+        }
     }
 
     /**
@@ -1374,7 +1394,7 @@
                 if (WARN) Log.w(TAG, "startAnimation canceled before preDraw");
                 return;
             }
-            Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW,
+            Trace.asyncTraceBegin(TRACE_TAG_VIEW,
                     "InsetsAnimation: " + WindowInsets.Type.toString(types), types);
             for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
                 RunningAnimation runningAnimation = mRunningAnimations.get(i);
@@ -1382,6 +1402,7 @@
                     runningAnimation.startDispatched = true;
                 }
             }
+            Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.pendingAnim", 0);
             mHost.dispatchWindowInsetsAnimationStart(animation, bounds);
             mStartingAnimation = true;
             controller.mReadyDispatched = true;
@@ -1392,7 +1413,7 @@
 
     @VisibleForTesting
     public void dispatchAnimationEnd(WindowInsetsAnimation animation) {
-        Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW,
+        Trace.asyncTraceEnd(TRACE_TAG_VIEW,
                 "InsetsAnimation: " + WindowInsets.Type.toString(animation.getTypeMask()),
                 animation.getTypeMask());
         mHost.dispatchWindowInsetsAnimationEnd(animation);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index d37edaa..af31b81 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -548,6 +548,12 @@
     public static final int METADATA_ACCESSIBILITY_ID = 5;
 
     /**
+     * owner PID.
+     * @hide
+     */
+    public static final int METADATA_OWNER_PID = 6;
+
+    /**
      * A wrapper around HardwareBuffer that contains extra information about how to
      * interpret the screenshot HardwareBuffer.
      *
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 14748f0..15adc5a 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -432,7 +432,7 @@
                  * This gets called on a RenderThread worker thread, so members accessed here must
                  * be protected by a lock.
                  */
-                final boolean useBLAST = viewRoot.useBLAST();
+                final boolean useBLAST = useBLASTSync(viewRoot);
                 viewRoot.registerRtFrameCallback(frame -> {
                     try {
                         synchronized (mSurfaceControlLock) {
@@ -809,7 +809,7 @@
          * This gets called on a RenderThread worker thread, so members accessed here must
          * be protected by a lock.
          */
-        final boolean useBLAST = viewRoot.useBLAST();
+        final boolean useBLAST = useBLASTSync(viewRoot);
         viewRoot.registerRtFrameCallback(frame -> {
             try {
                 synchronized (mSurfaceControlLock) {
@@ -1110,7 +1110,7 @@
 
                 final boolean needBLASTSync =
                     (layoutSizeChanged || positionChanged || visibleChanged) &&
-                        viewRoot.useBLAST();
+                        useBLASTSync(viewRoot);
                 final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
                     translator, creating, sizeChanged, needBLASTSync);
                 final boolean redrawNeeded = sizeChanged || creating ||
@@ -1352,7 +1352,7 @@
     private void applySurfaceTransforms(SurfaceControl surface, SurfaceControl.Transaction t,
             Rect position, long frameNumber) {
         final ViewRootImpl viewRoot = getViewRootImpl();
-        if (frameNumber > 0 && viewRoot != null && !viewRoot.useBLAST()) {
+        if (frameNumber > 0 && viewRoot != null && !useBLASTSync(viewRoot)) {
             t.deferTransactionUntil(surface, viewRoot.getSurfaceControl(),
                     frameNumber);
         }
@@ -1385,7 +1385,7 @@
 
     private void setParentSpaceRectangle(Rect position, long frameNumber) {
         final ViewRootImpl viewRoot = getViewRootImpl();
-        final boolean useBLAST = viewRoot.useBLAST();
+        final boolean useBLAST = useBLASTSync(viewRoot);
 
         if (useBLAST) {
             synchronized (viewRoot.getBlastTransactionLock()) {
@@ -1444,7 +1444,7 @@
         @Override
         public void positionLost(long frameNumber) {
             final ViewRootImpl viewRoot = getViewRootImpl();
-            boolean useBLAST = viewRoot != null && viewRoot.useBLAST();
+            boolean useBLAST = viewRoot != null && useBLASTSync(viewRoot);
             if (DEBUG) {
                 Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
                         System.identityHashCode(this), frameNumber));
@@ -1920,4 +1920,8 @@
                     + "Exception requesting focus on embedded window", e);
         }
     }
+
+    private boolean useBLASTSync(ViewRootImpl viewRoot) {
+        return viewRoot.useBLAST() && mUseBlastAdapter;
+    }
 }
diff --git a/core/java/android/view/VerifiedKeyEvent.java b/core/java/android/view/VerifiedKeyEvent.java
index dc5b7cc..77a7d09 100644
--- a/core/java/android/view/VerifiedKeyEvent.java
+++ b/core/java/android/view/VerifiedKeyEvent.java
@@ -137,11 +137,10 @@
     // 3. add the "super" call for constructor that receives a Parcel
     // 4. add the "super" call to the writeToParcel method
     // 5. Update "equals" and "hashcode" methods to include VerifiedInputEvent fields
-    // 6. Edit "inputSignatures" to ensure KeyEventAction is properly qualified
 
 
 
-    // Code below generated by codegen v1.0.14.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -180,14 +179,13 @@
      *   this is the number of down/up pairs that have occurred.
      * @hide
      */
-    @DataClass.Generated.Member
     public VerifiedKeyEvent(
             int deviceId,
             long eventTimeNanos,
             int source,
             int displayId,
             @KeyEventAction int action,
-            @SuppressLint({"MethodNameUnits"}) long downTimeNanos,
+            @SuppressLint({ "MethodNameUnits" }) long downTimeNanos,
             int flags,
             int keyCode,
             int scanCode,
@@ -198,16 +196,11 @@
         com.android.internal.util.AnnotationValidations.validate(
                 KeyEventAction.class, null, mAction);
         this.mDownTimeNanos = downTimeNanos;
-        com.android.internal.util.AnnotationValidations.validate(
-                SuppressLint.class, null, mDownTimeNanos,
-                "value", "MethodNameUnits");
         this.mFlags = flags;
         this.mKeyCode = keyCode;
         this.mScanCode = scanCode;
         this.mMetaState = metaState;
         this.mRepeatCount = repeatCount;
-
-        // onConstructed(); // You can define this method to get a callback
     }
 
     /**
@@ -229,7 +222,7 @@
      * @see KeyEvent#getDownTime()
      */
     @DataClass.Generated.Member
-    public @SuppressLint({"MethodNameUnits"}) long getDownTimeNanos() {
+    public @SuppressLint({ "MethodNameUnits" }) long getDownTimeNanos() {
         return mDownTimeNanos;
     }
 
@@ -301,10 +294,7 @@
         VerifiedKeyEvent that = (VerifiedKeyEvent) o;
         //noinspection PointlessBooleanExpression
         return true
-                && getDeviceId() == that.getDeviceId()
-                && getEventTimeNanos() == that.getEventTimeNanos()
-                && getSource() == that.getSource()
-                && getDisplayId() == that.getDisplayId()
+                && super.equals(that)
                 && mAction == that.mAction
                 && mDownTimeNanos == that.mDownTimeNanos
                 && mFlags == that.mFlags
@@ -321,10 +311,7 @@
         // int fieldNameHashCode() { ... }
 
         int _hash = 1;
-        _hash = 31 * _hash + getDeviceId();
-        _hash = 31 * _hash + Long.hashCode(getEventTimeNanos());
-        _hash = 31 * _hash + getSource();
-        _hash = 31 * _hash + getDisplayId();
+        _hash = 31 * _hash + super.hashCode();
         _hash = 31 * _hash + mAction;
         _hash = 31 * _hash + Long.hashCode(mDownTimeNanos);
         _hash = 31 * _hash + mFlags;
@@ -341,6 +328,7 @@
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
         super.writeToParcel(dest, flags);
+
         dest.writeInt(mAction);
         dest.writeLong(mDownTimeNanos);
         dest.writeInt(mFlags);
@@ -361,6 +349,7 @@
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
         super(in, VERIFIED_KEY);
+
         int action = in.readInt();
         long downTimeNanos = in.readLong();
         int flags = in.readInt();
@@ -373,9 +362,6 @@
         com.android.internal.util.AnnotationValidations.validate(
                 KeyEventAction.class, null, mAction);
         this.mDownTimeNanos = downTimeNanos;
-        com.android.internal.util.AnnotationValidations.validate(
-                SuppressLint.class, null, mDownTimeNanos,
-                "value", "MethodNameUnits");
         this.mFlags = flags;
         this.mKeyCode = keyCode;
         this.mScanCode = scanCode;
@@ -400,10 +386,10 @@
     };
 
     @DataClass.Generated(
-            time = 1581107066890L,
-            codegenVersion = "1.0.14",
+            time = 1604509197793L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/core/java/android/view/VerifiedKeyEvent.java",
-            inputSignatures = "private static final  java.lang.String TAG\nprivate @android.view.VerifiedKeyEvent.KeyEventAction int mAction\nprivate @android.annotation.SuppressLint({\"MethodNameUnits\"}) long mDownTimeNanos\nprivate  int mFlags\nprivate  int mKeyCode\nprivate  int mScanCode\nprivate  int mMetaState\nprivate  int mRepeatCount\npublic @android.annotation.Nullable java.lang.Boolean getFlag(int)\nclass VerifiedKeyEvent extends android.view.VerifiedInputEvent implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true)")
+            inputSignatures = "private static final  java.lang.String TAG\nprivate @android.view.VerifiedKeyEvent.KeyEventAction int mAction\nprivate @android.annotation.SuppressLint long mDownTimeNanos\nprivate  int mFlags\nprivate  int mKeyCode\nprivate  int mScanCode\nprivate  int mMetaState\nprivate  int mRepeatCount\npublic @android.annotation.Nullable java.lang.Boolean getFlag(int)\nclass VerifiedKeyEvent extends android.view.VerifiedInputEvent implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/VerifiedMotionEvent.java b/core/java/android/view/VerifiedMotionEvent.java
index b4c5d24..7d83459 100644
--- a/core/java/android/view/VerifiedMotionEvent.java
+++ b/core/java/android/view/VerifiedMotionEvent.java
@@ -131,11 +131,10 @@
     // 3. add the "super" call for constructor that receives a Parcel
     // 4. add the "super" call to the writeToParcel method
     // 5. Update "equals" and "hashcode" methods to include VerifiedInputEvent fields
-    // 6. Edit "inputSignatures" to ensure MotionEventAction is properly qualified
 
 
 
-    // Code below generated by codegen v1.0.14.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -174,7 +173,7 @@
             float rawX,
             float rawY,
             @MotionEventAction int actionMasked,
-            @SuppressLint({"MethodNameUnits"}) long downTimeNanos,
+            @SuppressLint({ "MethodNameUnits" }) long downTimeNanos,
             int flags,
             int metaState,
             int buttonState) {
@@ -185,9 +184,6 @@
         com.android.internal.util.AnnotationValidations.validate(
                 MotionEventAction.class, null, mActionMasked);
         this.mDownTimeNanos = downTimeNanos;
-        com.android.internal.util.AnnotationValidations.validate(
-                SuppressLint.class, null, mDownTimeNanos,
-                "value", "MethodNameUnits");
         this.mFlags = flags;
         this.mMetaState = metaState;
         this.mButtonState = buttonState;
@@ -232,7 +228,7 @@
      * @see MotionEvent#getDownTime()
      */
     @DataClass.Generated.Member
-    public @SuppressLint({"MethodNameUnits"}) long getDownTimeNanos() {
+    public @SuppressLint({ "MethodNameUnits" }) long getDownTimeNanos() {
         return mDownTimeNanos;
     }
 
@@ -280,10 +276,7 @@
         VerifiedMotionEvent that = (VerifiedMotionEvent) o;
         //noinspection PointlessBooleanExpression
         return true
-                && getDeviceId() == that.getDeviceId()
-                && getEventTimeNanos() == that.getEventTimeNanos()
-                && getSource() == that.getSource()
-                && getDisplayId() == that.getDisplayId()
+                && super.equals(that)
                 && mRawX == that.mRawX
                 && mRawY == that.mRawY
                 && mActionMasked == that.mActionMasked
@@ -300,10 +293,7 @@
         // int fieldNameHashCode() { ... }
 
         int _hash = 1;
-        _hash = 31 * _hash + getDeviceId();
-        _hash = 31 * _hash + Long.hashCode(getEventTimeNanos());
-        _hash = 31 * _hash + getSource();
-        _hash = 31 * _hash + getDisplayId();
+        _hash = 31 * _hash + super.hashCode();
         _hash = 31 * _hash + Float.hashCode(mRawX);
         _hash = 31 * _hash + Float.hashCode(mRawY);
         _hash = 31 * _hash + mActionMasked;
@@ -320,6 +310,7 @@
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
         super.writeToParcel(dest, flags);
+
         dest.writeFloat(mRawX);
         dest.writeFloat(mRawY);
         dest.writeInt(mActionMasked);
@@ -340,6 +331,7 @@
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
         super(in, VERIFIED_MOTION);
+
         float rawX = in.readFloat();
         float rawY = in.readFloat();
         int actionMasked = in.readInt();
@@ -354,9 +346,6 @@
         com.android.internal.util.AnnotationValidations.validate(
                 MotionEventAction.class, null, mActionMasked);
         this.mDownTimeNanos = downTimeNanos;
-        com.android.internal.util.AnnotationValidations.validate(
-                SuppressLint.class, null, mDownTimeNanos,
-                "value", "MethodNameUnits");
         this.mFlags = flags;
         this.mMetaState = metaState;
         this.mButtonState = buttonState;
@@ -379,10 +368,10 @@
     };
 
     @DataClass.Generated(
-            time = 1581107073238L,
-            codegenVersion = "1.0.14",
+            time = 1604509199368L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/core/java/android/view/VerifiedMotionEvent.java",
-            inputSignatures = "private static final  java.lang.String TAG\nprivate  float mRawX\nprivate  float mRawY\nprivate @android.view.VerifiedMotionEvent.MotionEventAction int mActionMasked\nprivate @android.annotation.SuppressLint({\"MethodNameUnits\"}) long mDownTimeNanos\nprivate  int mFlags\nprivate  int mMetaState\nprivate  int mButtonState\npublic @android.annotation.Nullable java.lang.Boolean getFlag(int)\nclass VerifiedMotionEvent extends android.view.VerifiedInputEvent implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true)")
+            inputSignatures = "private static final  java.lang.String TAG\nprivate  float mRawX\nprivate  float mRawY\nprivate @android.view.VerifiedMotionEvent.MotionEventAction int mActionMasked\nprivate @android.annotation.SuppressLint long mDownTimeNanos\nprivate  int mFlags\nprivate  int mMetaState\nprivate  int mButtonState\npublic @android.annotation.Nullable java.lang.Boolean getFlag(int)\nclass VerifiedMotionEvent extends android.view.VerifiedInputEvent implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0e8cd54..9d24dff1 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1890,8 +1890,10 @@
         mSurface.release();
         mSurfaceControl.release();
 
-        // We should probably add an explicit dispose.
-        mBlastBufferQueue = null;
+        if (mBlastBufferQueue != null) {
+            mBlastBufferQueue.destroy();
+            mBlastBufferQueue = null;
+        }
     }
 
     /**
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f7578ab..b4a841f 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -17,6 +17,27 @@
 package android.view;
 
 import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
+import static android.view.View.STATUS_BAR_DISABLE_BACK;
+import static android.view.View.STATUS_BAR_DISABLE_CLOCK;
+import static android.view.View.STATUS_BAR_DISABLE_EXPAND;
+import static android.view.View.STATUS_BAR_DISABLE_HOME;
+import static android.view.View.STATUS_BAR_DISABLE_NOTIFICATION_ALERTS;
+import static android.view.View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS;
+import static android.view.View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
+import static android.view.View.STATUS_BAR_DISABLE_RECENT;
+import static android.view.View.STATUS_BAR_DISABLE_SEARCH;
+import static android.view.View.STATUS_BAR_DISABLE_SYSTEM_INFO;
+import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
+import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
 import static android.view.WindowInsets.Side.BOTTOM;
 import static android.view.WindowInsets.Side.LEFT;
 import static android.view.WindowInsets.Side.RIGHT;
@@ -2725,6 +2746,38 @@
         public int preferredDisplayModeId;
 
         /**
+         * An internal annotation for flags that can be specified to {@link #systemUiVisibility}
+         * and {@link #subtreeSystemUiVisibility}.
+         *
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, prefix = { "" }, value = {
+            SYSTEM_UI_FLAG_VISIBLE,
+            SYSTEM_UI_FLAG_LOW_PROFILE,
+            SYSTEM_UI_FLAG_HIDE_NAVIGATION,
+            SYSTEM_UI_FLAG_FULLSCREEN,
+            SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+            SYSTEM_UI_FLAG_LAYOUT_STABLE,
+            SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,
+            SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,
+            SYSTEM_UI_FLAG_IMMERSIVE,
+            SYSTEM_UI_FLAG_IMMERSIVE_STICKY,
+            SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
+            STATUS_BAR_DISABLE_EXPAND,
+            STATUS_BAR_DISABLE_NOTIFICATION_ICONS,
+            STATUS_BAR_DISABLE_NOTIFICATION_ALERTS,
+            STATUS_BAR_DISABLE_NOTIFICATION_TICKER,
+            STATUS_BAR_DISABLE_SYSTEM_INFO,
+            STATUS_BAR_DISABLE_HOME,
+            STATUS_BAR_DISABLE_BACK,
+            STATUS_BAR_DISABLE_CLOCK,
+            STATUS_BAR_DISABLE_RECENT,
+            STATUS_BAR_DISABLE_SEARCH,
+        })
+        public @interface SystemUiVisibilityFlags {}
+
+        /**
          * Control the visibility of the status bar.
          *
          * @see View#STATUS_BAR_VISIBLE
@@ -2733,6 +2786,7 @@
          * @deprecated SystemUiVisibility flags are deprecated. Use {@link WindowInsetsController}
          * instead.
          */
+        @SystemUiVisibilityFlags
         @Deprecated
         public int systemUiVisibility;
 
@@ -2741,6 +2795,7 @@
          * The ui visibility as requested by the views in this hierarchy.
          * the combined value should be systemUiVisibility | subtreeSystemUiVisibility.
          */
+        @SystemUiVisibilityFlags
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         public int subtreeSystemUiVisibility;
 
@@ -2754,7 +2809,6 @@
         @UnsupportedAppUsage
         public boolean hasSystemUiListeners;
 
-
         /** @hide */
         @Retention(RetentionPolicy.SOURCE)
         @IntDef(
@@ -2921,6 +2975,19 @@
         public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004;
 
         /**
+         * An internal annotation for flags that can be specified to {@link #inputFeatures}.
+         *
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, prefix = { "INPUT_FEATURE_" }, value = {
+            INPUT_FEATURE_DISABLE_POINTER_GESTURES,
+            INPUT_FEATURE_NO_INPUT_CHANNEL,
+            INPUT_FEATURE_DISABLE_USER_ACTIVITY,
+        })
+        public @interface InputFeatureFlags {}
+
+        /**
          * Control special features of the input subsystem.
          *
          * @see #INPUT_FEATURE_DISABLE_POINTER_GESTURES
@@ -2928,6 +2995,7 @@
          * @see #INPUT_FEATURE_DISABLE_USER_ACTIVITY
          * @hide
          */
+        @InputFeatureFlags
         @UnsupportedAppUsage
         public int inputFeatures;
 
diff --git a/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
index 2343bf3..d0ab004 100644
--- a/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
+++ b/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
@@ -50,4 +50,14 @@
      * @param sourceBounds The magnified bounds in screen coordinates.
      */
     void onSourceBoundsChanged(int displayId, in Rect sourceBounds);
+
+    /**
+     * Called when the accessibility action of scale requests to be performed.
+     * It is invoked from System UI. And the action is provided by the mirror window.
+     *
+     * @param displayId The logical display id.
+     * @param scale the target scale, or {@link Float#NaN} to leave unchanged
+     */
+    void onPerformScaleAction(int displayId, float scale);
+
 }
diff --git a/core/java/android/view/inputmethod/InlineSuggestionInfo.java b/core/java/android/view/inputmethod/InlineSuggestionInfo.java
index 1c703ec..73962d7 100644
--- a/core/java/android/view/inputmethod/InlineSuggestionInfo.java
+++ b/core/java/android/view/inputmethod/InlineSuggestionInfo.java
@@ -88,7 +88,7 @@
 
 
 
-    // Code below generated by codegen v1.0.15.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -346,10 +346,10 @@
     };
 
     @DataClass.Generated(
-            time = 1586992414034L,
-            codegenVersion = "1.0.15",
+            time = 1604456249219L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionInfo.java",
-            inputSignatures = "public static final @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String SOURCE_AUTOFILL\npublic static final @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String SOURCE_PLATFORM\npublic static final @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String TYPE_SUGGESTION\npublic static final @android.annotation.SuppressLint({\"IntentName\"}) @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String TYPE_ACTION\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final @android.annotation.NonNull @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String mSource\nprivate final @android.annotation.Nullable java.lang.String[] mAutofillHints\nprivate final @android.annotation.NonNull @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String mType\nprivate final  boolean mPinned\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo newInlineSuggestionInfo(android.widget.inline.InlinePresentationSpec,java.lang.String,java.lang.String[],java.lang.String,boolean)\nclass InlineSuggestionInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)")
+            inputSignatures = "public static final @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String SOURCE_AUTOFILL\npublic static final @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String SOURCE_PLATFORM\npublic static final @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String TYPE_SUGGESTION\npublic static final @android.annotation.SuppressLint @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String TYPE_ACTION\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final @android.annotation.NonNull @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String mSource\nprivate final @android.annotation.Nullable java.lang.String[] mAutofillHints\nprivate final @android.annotation.NonNull @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String mType\nprivate final  boolean mPinned\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo newInlineSuggestionInfo(android.widget.inline.InlinePresentationSpec,java.lang.String,java.lang.String[],java.lang.String,boolean)\nclass InlineSuggestionInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 0fe47b7..14b5d7c 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -190,7 +190,7 @@
      *
      * @param n The expected length of the text. This must be non-negative.
      * @param flags Supplies additional options controlling how the text is
-     * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
+     * returned. May be either {@code 0} or {@link #GET_TEXT_WITH_STYLES}.
      * @return the text before the cursor position; the length of the
      * returned text might be less than <var>n</var>.
      * @throws IllegalArgumentException if {@code n} is negative.
@@ -234,7 +234,7 @@
      *
      * @param n The expected length of the text. This must be non-negative.
      * @param flags Supplies additional options controlling how the text is
-     * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
+     * returned. May be either {@code 0} or {@link #GET_TEXT_WITH_STYLES}.
      *
      * @return the text after the cursor position; the length of the
      * returned text might be less than <var>n</var>.
@@ -273,7 +273,7 @@
      * consistent with the results of the latest edits.</p>
      *
      * @param flags Supplies additional options controlling how the text is
-     * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
+     * returned. May be either {@code 0} or {@link #GET_TEXT_WITH_STYLES}.
      * @return the text that is currently selected, if any, or null if
      * no text is selected. In {@link android.os.Build.VERSION_CODES#N} and
      * later, returns false when the target application does not implement
@@ -284,7 +284,8 @@
     /**
      * Gets the surrounding text around the current cursor, with <var>beforeLength</var> characters
      * of text before the cursor (start of the selection), <var>afterLength</var> characters of text
-     * after the cursor (end of the selection), and all of the selected text.
+     * after the cursor (end of the selection), and all of the selected text. The range are for java
+     * characters, not glyphs that can be multiple characters.
      *
      * <p>This method may fail either if the input connection has become invalid (such as its
      * process crashing), or the client is taking too long to respond with the text (it is given a
@@ -306,8 +307,8 @@
      *
      * @param beforeLength The expected length of the text before the cursor.
      * @param afterLength The expected length of the text after the cursor.
-     * @param flags Supplies additional options controlling how the text is returned. Defined by the
-     *              constants.
+     * @param flags Supplies additional options controlling how the text is returned. May be either
+     *              {@code 0} or {@link #GET_TEXT_WITH_STYLES}.
      * @return an {@link android.view.inputmethod.SurroundingText} object describing the surrounding
      * text and state of selection, or null if the input connection is no longer valid, or the
      * editor can't comply with the request for some reason, or the application does not implement
@@ -394,7 +395,7 @@
      *
      * @param request Description of how the text should be returned.
      * {@link android.view.inputmethod.ExtractedTextRequest}
-     * @param flags Additional options to control the client, either 0 or
+     * @param flags Additional options to control the client, either {@code 0} or
      * {@link #GET_EXTRACTED_TEXT_MONITOR}.
 
      * @return an {@link android.view.inputmethod.ExtractedText}
diff --git a/core/java/android/view/inputmethod/SurroundingText.java b/core/java/android/view/inputmethod/SurroundingText.java
index 506f95a..94e05a8 100644
--- a/core/java/android/view/inputmethod/SurroundingText.java
+++ b/core/java/android/view/inputmethod/SurroundingText.java
@@ -90,6 +90,10 @@
 
     /**
      * Returns the text offset of the start of the selection in the surrounding text.
+     *
+     * <p>A selection is the current range of the text that is selected by the user, or the current
+     * position of the cursor. A cursor is a selection where the start and end are at the same
+     * offset.<p>
      */
     @IntRange(from = 0)
     public int getSelectionStart() {
@@ -98,6 +102,10 @@
 
     /**
      * Returns the text offset of the end of the selection in the surrounding text.
+     *
+     * <p>A selection is the current range of the text that is selected by the user, or the current
+     * position of the cursor. A cursor is a selection where the start and end are at the same
+     * offset.<p>
      */
     @IntRange(from = 0)
     public int getSelectionEnd() {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 4099c8a..e36243c 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4116,6 +4116,8 @@
         private final boolean mHasSelection;
         private final int mHandleHeight;
         private final Map<MenuItem, OnClickListener> mAssistClickHandlers = new HashMap<>();
+        @Nullable
+        private TextClassification mPrevTextClassification;
 
         TextActionModeCallback(@TextActionMode int mode) {
             mHasSelection = mode == TextActionMode.SELECTION
@@ -4266,15 +4268,19 @@
         }
 
         private void updateAssistMenuItems(Menu menu) {
-            clearAssistMenuItems(menu);
-            if (!shouldEnableAssistMenuItems()) {
-                return;
-            }
             final TextClassification textClassification =
                     getSelectionActionModeHelper().getTextClassification();
+            if (mPrevTextClassification == textClassification) {
+                // Already handled.
+                return;
+            }
+            clearAssistMenuItems(menu);
             if (textClassification == null) {
                 return;
             }
+            if (!shouldEnableAssistMenuItems()) {
+                return;
+            }
             if (!textClassification.getActions().isEmpty()) {
                 // Primary assist action (Always shown).
                 final MenuItem item = addAssistMenuItem(menu,
@@ -4301,6 +4307,7 @@
                         MENU_ITEM_ORDER_SECONDARY_ASSIST_ACTIONS_START + i - 1,
                         MenuItem.SHOW_AS_ACTION_NEVER);
             }
+            mPrevTextClassification = textClassification;
         }
 
         private MenuItem addAssistMenuItem(Menu menu, RemoteAction action, int itemId, int order,
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 32c68bd..e74ce53 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -296,12 +296,12 @@
         } else {
             mTextClassification = null;
         }
+        final SelectionModifierCursorController controller = mEditor.getSelectionController();
+        if (controller != null
+                && (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
+            controller.show();
+        }
         if (mEditor.startActionModeInternal(actionMode)) {
-            final SelectionModifierCursorController controller = mEditor.getSelectionController();
-            if (controller != null
-                    && (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
-                controller.show();
-            }
             if (result != null) {
                 switch (actionMode) {
                     case Editor.TextActionMode.SELECTION:
diff --git a/core/java/android/widget/SmartSelectSprite.java b/core/java/android/widget/SmartSelectSprite.java
index dc472e1..baf92e5 100644
--- a/core/java/android/widget/SmartSelectSprite.java
+++ b/core/java/android/widget/SmartSelectSprite.java
@@ -50,11 +50,9 @@
  */
 final class SmartSelectSprite {
 
-    private static final int EXPAND_DURATION = 300;
-    private static final int CORNER_DURATION = 50;
+    private static final int EXPAND_DURATION = 200;
 
     private final Interpolator mExpandInterpolator;
-    private final Interpolator mCornerInterpolator;
 
     private Animator mActiveAnimator = null;
     private final Runnable mInvalidator;
@@ -337,9 +335,6 @@
         mExpandInterpolator = AnimationUtils.loadInterpolator(
                 context,
                 android.R.interpolator.fast_out_slow_in);
-        mCornerInterpolator = AnimationUtils.loadInterpolator(
-                context,
-                android.R.interpolator.fast_out_linear_in);
         mFillColor = highlightColor;
         mInvalidator = Objects.requireNonNull(invalidator);
     }
@@ -372,7 +367,6 @@
         final int rectangleCount = destinationRectangles.size();
 
         final List<RoundedRectangleShape> shapes = new ArrayList<>(rectangleCount);
-        final List<Animator> cornerAnimators = new ArrayList<>(rectangleCount);
 
         RectangleWithTextSelectionLayout centerRectangle = null;
 
@@ -405,7 +399,6 @@
                     expansionDirections[index],
                     rectangleWithTextSelectionLayout.getTextSelectionLayout()
                             == Layout.TEXT_SELECTION_LAYOUT_RIGHT_TO_LEFT);
-            cornerAnimators.add(createCornerAnimator(shape, updateListener));
             shapes.add(shape);
         }
 
@@ -420,7 +413,7 @@
         mExistingDrawable = shapeDrawable;
 
         mActiveAnimator = createAnimator(rectangleList, startingOffset, startingOffset,
-                cornerAnimators, updateListener, onAnimationEnd);
+                updateListener, onAnimationEnd);
         mActiveAnimator.start();
     }
 
@@ -433,7 +426,6 @@
             final RectangleList rectangleList,
             final float startingOffsetLeft,
             final float startingOffsetRight,
-            final List<Animator> cornerAnimators,
             final ValueAnimator.AnimatorUpdateListener updateListener,
             final Runnable onAnimationEnd) {
         final ObjectAnimator rightBoundaryAnimator = ObjectAnimator.ofFloat(
@@ -457,18 +449,12 @@
         rightBoundaryAnimator.setInterpolator(mExpandInterpolator);
         leftBoundaryAnimator.setInterpolator(mExpandInterpolator);
 
-        final AnimatorSet cornerAnimator = new AnimatorSet();
-        cornerAnimator.playTogether(cornerAnimators);
-
         final AnimatorSet boundaryAnimator = new AnimatorSet();
         boundaryAnimator.playTogether(leftBoundaryAnimator, rightBoundaryAnimator);
 
-        final AnimatorSet animatorSet = new AnimatorSet();
-        animatorSet.playSequentially(boundaryAnimator, cornerAnimator);
+        setUpAnimatorListener(boundaryAnimator, onAnimationEnd);
 
-        setUpAnimatorListener(animatorSet, onAnimationEnd);
-
-        return animatorSet;
+        return boundaryAnimator;
     }
 
     private void setUpAnimatorListener(final Animator animator, final Runnable onAnimationEnd) {
@@ -495,19 +481,6 @@
         });
     }
 
-    private ObjectAnimator createCornerAnimator(
-            final RoundedRectangleShape shape,
-            final ValueAnimator.AnimatorUpdateListener listener) {
-        final ObjectAnimator animator = ObjectAnimator.ofFloat(
-                shape,
-                RoundedRectangleShape.PROPERTY_ROUND_RATIO,
-                shape.getRoundRatio(), 0.0F);
-        animator.setDuration(CORNER_DURATION);
-        animator.addUpdateListener(listener);
-        animator.setInterpolator(mCornerInterpolator);
-        return animator;
-    }
-
     private static @RoundedRectangleShape.ExpansionDirection int[] generateDirections(
             final RectangleWithTextSelectionLayout centerRectangle,
             final List<RectangleWithTextSelectionLayout> rectangles) {
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java
index 6ec093e..bc3e35c 100644
--- a/core/java/android/window/DisplayAreaOrganizer.java
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -88,9 +88,11 @@
     public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1;
 
     /**
-     * Registers a DisplayAreaOrganizer to manage display areas for a given feature.
+     * Registers a DisplayAreaOrganizer to manage display areas for a given feature. A feature can
+     * not be registered by multiple organizers at the same time.
      *
      * @return a list of display areas that should be managed by the organizer.
+     * @throws IllegalStateException if the feature has already been registered.
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
     @CallSuper
diff --git a/core/java/android/window/IDisplayAreaOrganizerController.aidl b/core/java/android/window/IDisplayAreaOrganizerController.aidl
index 8943847..edabcf8 100644
--- a/core/java/android/window/IDisplayAreaOrganizerController.aidl
+++ b/core/java/android/window/IDisplayAreaOrganizerController.aidl
@@ -24,9 +24,11 @@
 interface IDisplayAreaOrganizerController {
 
     /**
-     * Registers a DisplayAreaOrganizer to manage display areas for a given feature.
+     * Registers a DisplayAreaOrganizer to manage display areas for a given feature. A feature can
+     * not be registered by multiple organizers at the same time.
      *
      * @return a list of display areas that should be managed by the organizer.
+     * @throws IllegalStateException if the feature has already been registered.
      */
     ParceledListSlice<DisplayAreaAppearedInfo> registerOrganizer(in IDisplayAreaOrganizer organizer,
         int displayAreaFeature);
diff --git a/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java b/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java
index 6ea9e66..9eab621 100644
--- a/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java
+++ b/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.Path;
@@ -75,7 +76,8 @@
 
     private BackgroundBlurDrawable(Aggregator aggregator) {
         mAggregator = aggregator;
-        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
+        mPaint.setColor(Color.TRANSPARENT);
         mRenderNode = new RenderNode("BackgroundBlurDrawable");
         mRenderNode.addPositionUpdateListener(mPositionUpdateListener);
     }
@@ -85,11 +87,17 @@
         if (mRectPath.isEmpty() || !isVisible() || getAlpha() == 0) {
             return;
         }
+
         canvas.drawPath(mRectPath, mPaint);
         canvas.drawRenderNode(mRenderNode);
     }
 
     @Override
+    public void setTint(int tintColor) {
+        mPaint.setColor(tintColor);
+    }
+
+    @Override
     public boolean setVisible(boolean visible, boolean restart) {
         boolean changed = super.setVisible(visible, restart);
         if (changed) {
diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
index f46626b..ffc7f05 100644
--- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
+++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
@@ -144,7 +144,7 @@
     int HIDE_RECENTS_ANIMATION = 18;
 
     /**
-     * Hide soft input when {@link com.android.systemui.bubbles.BubbleController} is expanding,
+     * Hide soft input when {@link com.android.wm.shell.bubbles.BubbleController} is expanding,
      * switching, or collapsing Bubbles.
      */
     int HIDE_BUBBLES = 19;
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 85dc2ae..c0d46f6 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -176,7 +176,7 @@
      * Trigger the prefetto daemon.
      */
     public void triggerPerfetto() {
-        InteractionJankMonitor.getInstance().trigger();
+        InteractionJankMonitor.getInstance().trigger(mSession);
     }
 
     /**
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 3624f0d..137430b 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -22,7 +22,12 @@
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_RECENTS;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_COLLAPSE_LOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_DISAPPEAR;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_ADD;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_REMOVE;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_QS_EXPAND_COLLAPSE;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_QS_SCROLL_SWIPE;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_EXPAND;
@@ -67,6 +72,11 @@
     public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME = 9;
     public static final int CUJ_LAUNCHER_APP_CLOSE_TO_PIP = 10;
     public static final int CUJ_LAUNCHER_QUICK_SWITCH = 11;
+    public static final int CUJ_NOTIFICATION_HEADS_UP_APPEAR = 12;
+    public static final int CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR = 13;
+    public static final int CUJ_NOTIFICATION_ADD = 14;
+    public static final int CUJ_NOTIFICATION_REMOVE = 15;
+    public static final int CUJ_NOTIFICATION_APP_START = 16;
 
     private static final int NO_STATSD_LOGGING = -1;
 
@@ -87,6 +97,11 @@
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_PIP,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_DISAPPEAR,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_ADD,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_REMOVE,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH,
     };
 
     private static volatile InteractionJankMonitor sInstance;
@@ -112,6 +127,11 @@
             CUJ_LAUNCHER_APP_CLOSE_TO_HOME,
             CUJ_LAUNCHER_APP_CLOSE_TO_PIP,
             CUJ_LAUNCHER_QUICK_SWITCH,
+            CUJ_NOTIFICATION_HEADS_UP_APPEAR,
+            CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR,
+            CUJ_NOTIFICATION_ADD,
+            CUJ_NOTIFICATION_REMOVE,
+            CUJ_NOTIFICATION_APP_START,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {}
@@ -319,11 +339,11 @@
      * Trigger the perfetto daemon to collect and upload data.
      */
     @VisibleForTesting
-    public void trigger() {
+    public void trigger(Session session) {
         synchronized (this) {
             if (!mInitialized) return;
             mWorker.getThreadHandler().post(
-                    () -> PerfettoTrigger.trigger(PerfettoTrigger.TRIGGER_TYPE_JANK));
+                    () -> PerfettoTrigger.trigger(session.getPerfettoTrigger()));
         }
     }
 
@@ -350,9 +370,12 @@
             return getStatsdInteractionType() != NO_STATSD_LOGGING;
         }
 
+        public String getPerfettoTrigger() {
+            return String.format("interaction-jank-monitor-%d", mCujType);
+        }
+
         public String getName() {
             return "Cuj<" + getCuj() + ">";
         }
     }
-
 }
diff --git a/core/java/com/android/internal/jank/PerfettoTrigger.java b/core/java/com/android/internal/jank/PerfettoTrigger.java
index 6c8d3cd..643d24a 100644
--- a/core/java/com/android/internal/jank/PerfettoTrigger.java
+++ b/core/java/com/android/internal/jank/PerfettoTrigger.java
@@ -17,15 +17,12 @@
 //TODO (165884885): Make PerfettoTrigger more generic and move it to another package.
 package com.android.internal.jank;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.util.Log;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 
 /**
  * A trigger implementation with perfetto backend.
@@ -35,23 +32,14 @@
     private static final String TAG = PerfettoTrigger.class.getSimpleName();
     private static final boolean DEBUG = false;
     private static final String TRIGGER_COMMAND = "/system/bin/trigger_perfetto";
-    private static final String[] TRIGGER_TYPE_NAMES = new String[] { "jank-tracker" };
-    public static final int TRIGGER_TYPE_JANK = 0;
-
-    /** @hide */
-    @IntDef({
-            TRIGGER_TYPE_JANK
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TriggerType {}
 
     /**
-     * @param type the trigger type
+     * @param triggerName The name of the trigger. Must match the value defined in the AOT
+     *                    Perfetto config.
      */
-    public static void trigger(@NonNull @TriggerType int type) {
+    public static void trigger(String triggerName) {
         try {
-            Token token = new Token(type, TRIGGER_TYPE_NAMES[type]);
-            ProcessBuilder pb = new ProcessBuilder(TRIGGER_COMMAND, token.getName());
+            ProcessBuilder pb = new ProcessBuilder(TRIGGER_COMMAND, triggerName);
             if (DEBUG) {
                 StringBuilder sb = new StringBuilder();
                 for (String arg : pb.command()) {
@@ -64,7 +52,7 @@
                 readConsoleOutput(process);
             }
         } catch (IOException | InterruptedException e) {
-            Log.w(TAG, "Failed to trigger " + type, e);
+            Log.w(TAG, "Failed to trigger " + triggerName, e);
         }
     }
 
@@ -82,34 +70,4 @@
             Log.d(TAG, "err message=" + errLine.toString());
         }
     }
-
-    /**
-     * Token which is used to trigger perfetto.
-     */
-    public static class Token {
-        private int mType;
-        private String mName;
-
-        Token(@TriggerType int type, String name) {
-            mType = type;
-            mName = name;
-        }
-
-        /**
-         * Get trigger type.
-         * @return trigger type, should be @TriggerType
-         */
-        public int getType() {
-            return mType;
-        }
-
-        /**
-         * Get name of this token as the argument while triggering perfetto.
-         * @return name
-         */
-        public String getName() {
-            return mName;
-        }
-    }
-
 }
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 3d35d2f..f668bba 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -21,8 +21,8 @@
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.StrictMode;
 import android.os.SystemClock;
-import android.system.suspend.ISuspendControlService;
-import android.system.suspend.WakeLockInfo;
+import android.system.suspend.internal.ISuspendControlServiceInternal;
+import android.system.suspend.internal.WakeLockInfo;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -66,7 +66,7 @@
 
     private final String[] mProcWakelocksName = new String[3];
     private final long[] mProcWakelocksData = new long[3];
-    private ISuspendControlService mSuspendControlService = null;
+    private ISuspendControlServiceInternal mSuspendControlService = null;
     private byte[] mKernelWakelockBuffer = new byte[32 * 1024];
 
     /**
@@ -155,11 +155,12 @@
     /**
      * Attempt to wait for suspend_control service if not immediately available.
      */
-    private ISuspendControlService waitForSuspendControlService() throws ServiceNotFoundException {
-        final String name = "suspend_control";
+    private ISuspendControlServiceInternal waitForSuspendControlService()
+            throws ServiceNotFoundException {
+        final String name = "suspend_control_internal";
         final int numRetries = 5;
         for (int i = 0; i < numRetries; i++) {
-            mSuspendControlService = ISuspendControlService.Stub.asInterface(
+            mSuspendControlService = ISuspendControlServiceInternal.Stub.asInterface(
                                         ServiceManager.getService(name));
             if (mSuspendControlService != null) {
                 return mSuspendControlService;
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 633d684..36913b7 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -29,8 +29,8 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-
 import android.widget.PopupWindow;
+
 import com.android.internal.R;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.widget.FloatingToolbar;
@@ -148,16 +148,21 @@
     @Override
     public void invalidateContentRect() {
         mCallback.onGetContentRect(this, mOriginatingView, mContentRect);
-        repositionToolbar();
+        updateViewLocationInWindow(/* forceRepositionToolbar= */ true);
     }
 
     public void updateViewLocationInWindow() {
+        updateViewLocationInWindow(/* forceRepositionToolbar= */ false);
+    }
+
+    private void updateViewLocationInWindow(boolean forceRepositionToolbar) {
         mOriginatingView.getLocationOnScreen(mViewPositionOnScreen);
         mOriginatingView.getRootView().getLocationOnScreen(mRootViewPositionOnScreen);
         mOriginatingView.getGlobalVisibleRect(mViewRectOnScreen);
         mViewRectOnScreen.offset(mRootViewPositionOnScreen[0], mRootViewPositionOnScreen[1]);
 
-        if (!Arrays.equals(mViewPositionOnScreen, mPreviousViewPositionOnScreen)
+        if (forceRepositionToolbar
+                || !Arrays.equals(mViewPositionOnScreen, mPreviousViewPositionOnScreen)
                 || !mViewRectOnScreen.equals(mPreviousViewRectOnScreen)) {
             repositionToolbar();
             mPreviousViewPositionOnScreen[0] = mViewPositionOnScreen[0];
@@ -192,10 +197,15 @@
                             mViewRectOnScreen.bottom + mBottomAllowance));
 
             if (!mContentRectOnScreen.equals(mPreviousContentRectOnScreen)) {
-                // Content rect is moving.
-                mOriginatingView.removeCallbacks(mMovingOff);
-                mFloatingToolbarVisibilityHelper.setMoving(true);
-                mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
+                // Content rect is moving
+                if (!mPreviousContentRectOnScreen.isEmpty()) {
+                    mOriginatingView.removeCallbacks(mMovingOff);
+                    mFloatingToolbarVisibilityHelper.setMoving(true);
+                    mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
+                } else {
+                    // mPreviousContentRectOnScreen is empty. That means we are are showing the
+                    // toolbar rather than moving it. And we should show it right away.
+                }
 
                 mFloatingToolbar.setContentRect(mContentRectOnScreen);
                 mFloatingToolbar.updateLayout();
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index d7611dc..58817a8 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -261,18 +261,14 @@
 
     /**
      * If this is set to true, the action mode view will dismiss itself on touch events outside of
-     * its window. If the toolbar is already showing, it will be re-shown so that this setting takes
-     * effect immediately.
+     * its window. The setting takes effect immediately.
      *
      * @param outsideTouchable whether or not this action mode is "outside touchable"
      * @param onDismiss optional. Sets a callback for when this action mode popup dismisses itself
      */
     public void setOutsideTouchable(
             boolean outsideTouchable, @Nullable PopupWindow.OnDismissListener onDismiss) {
-        if (mPopup.setOutsideTouchable(outsideTouchable, onDismiss) && isShowing()) {
-            dismiss();
-            doShow();
-        }
+        mPopup.setOutsideTouchable(outsideTouchable, onDismiss);
     }
 
     private void doShow() {
@@ -530,7 +526,6 @@
 
         /**
          * Makes this toolbar "outside touchable" and sets the onDismissListener.
-         * This will take effect the next time the toolbar is re-shown.
          *
          * @param outsideTouchable if true, the popup will be made "outside touchable" and
          *      "non focusable". The reverse will happen if false.
@@ -548,6 +543,7 @@
             if (mPopupWindow.isOutsideTouchable() ^ outsideTouchable) {
                 mPopupWindow.setOutsideTouchable(outsideTouchable);
                 mPopupWindow.setFocusable(!outsideTouchable);
+                mPopupWindow.update();
                 ret = true;
             }
             mPopupWindow.setOnDismissListener(onDismiss);
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 1123f20..dd1c87b 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -204,6 +204,9 @@
             ],
 
             shared_libs: [
+                "audioclient-types-aidl-unstable-cpp",
+                "audioflinger-aidl-unstable-cpp",
+                "av-types-aidl-unstable-cpp",
                 "libandroidicu",
                 "libbpf_android",
                 "libnetdbpf",
diff --git a/core/jni/android_hardware_input_InputApplicationHandle.cpp b/core/jni/android_hardware_input_InputApplicationHandle.cpp
index 7756a62..995bfa9 100644
--- a/core/jni/android_hardware_input_InputApplicationHandle.cpp
+++ b/core/jni/android_hardware_input_InputApplicationHandle.cpp
@@ -54,26 +54,28 @@
 
 bool NativeInputApplicationHandle::updateInfo() {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
-    jobject obj = env->NewLocalRef(mObjWeak);
-    if (!obj) {
+    ScopedLocalRef<jobject> obj(env, env->NewLocalRef(mObjWeak));
+    if (!obj.get()) {
         return false;
     }
+    if (mInfo.token.get() != nullptr) {
+        // The java fields are immutable, so it doesn't need to update again.
+        return true;
+    }
 
-    mInfo.name = getStringField(env, obj, gInputApplicationHandleClassInfo.name, "<null>");
+    mInfo.name = getStringField(env, obj.get(), gInputApplicationHandleClassInfo.name, "<null>");
 
     mInfo.dispatchingTimeoutMillis =
-            env->GetLongField(obj, gInputApplicationHandleClassInfo.dispatchingTimeoutMillis);
+            env->GetLongField(obj.get(), gInputApplicationHandleClassInfo.dispatchingTimeoutMillis);
 
-    jobject tokenObj = env->GetObjectField(obj,
-            gInputApplicationHandleClassInfo.token);
-    if (tokenObj) {
-        mInfo.token = ibinderForJavaObject(env, tokenObj);
-        env->DeleteLocalRef(tokenObj);
+    ScopedLocalRef<jobject> tokenObj(env, env->GetObjectField(obj.get(),
+            gInputApplicationHandleClassInfo.token));
+    if (tokenObj.get()) {
+        mInfo.token = ibinderForJavaObject(env, tokenObj.get());
     } else {
         mInfo.token.clear();
     }
 
-    env->DeleteLocalRef(obj);
     return mInfo.token.get() != nullptr;
 }
 
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 355ef0c..f05c6a4 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -252,20 +252,25 @@
     signalExceptionForError(env, clazz, err);
 }
 
-static void android_os_Parcel_writeString8(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val)
-{
+static void android_os_Parcel_writeString8(JNIEnv *env, jclass clazz, jlong nativePtr,
+        jstring val) {
     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
-    if (parcel != NULL) {
-        status_t err = NO_MEMORY;
+    if (parcel != nullptr) {
+        status_t err = NO_ERROR;
         if (val) {
-            const size_t len = env->GetStringUTFLength(val);
-            const char* str = env->GetStringUTFChars(val, 0);
-            if (str) {
-                err = parcel->writeString8(str, len);
-                env->ReleaseStringUTFChars(val, str);
+            // NOTE: Keep this logic in sync with Parcel.cpp
+            const size_t len = env->GetStringLength(val);
+            const size_t allocLen = env->GetStringUTFLength(val);
+            err = parcel->writeInt32(allocLen);
+            char *data = reinterpret_cast<char*>(parcel->writeInplace(allocLen + sizeof(char)));
+            if (data != nullptr) {
+                env->GetStringUTFRegion(val, 0, len, data);
+                *(data + allocLen) = 0;
+            } else {
+                err = NO_MEMORY;
             }
         } else {
-            err = parcel->writeString8(NULL, 0);
+            err = parcel->writeString8(nullptr, 0);
         }
         if (err != NO_ERROR) {
             signalExceptionForError(env, clazz, err);
@@ -273,21 +278,25 @@
     }
 }
 
-static void android_os_Parcel_writeString16(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val)
-{
+static void android_os_Parcel_writeString16(JNIEnv *env, jclass clazz, jlong nativePtr,
+        jstring val) {
     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
-    if (parcel != NULL) {
-        status_t err = NO_MEMORY;
+    if (parcel != nullptr) {
+        status_t err = NO_ERROR;
         if (val) {
-            const jchar* str = env->GetStringCritical(val, 0);
-            if (str) {
-                err = parcel->writeString16(
-                    reinterpret_cast<const char16_t*>(str),
-                    env->GetStringLength(val));
-                env->ReleaseStringCritical(val, str);
+            // NOTE: Keep this logic in sync with Parcel.cpp
+            const size_t len = env->GetStringLength(val);
+            const size_t allocLen = len * sizeof(char16_t);
+            err = parcel->writeInt32(len);
+            char *data = reinterpret_cast<char*>(parcel->writeInplace(allocLen + sizeof(char16_t)));
+            if (data != nullptr) {
+                env->GetStringRegion(val, 0, len, reinterpret_cast<jchar*>(data));
+                *reinterpret_cast<char16_t*>(data + allocLen) = 0;
+            } else {
+                err = NO_MEMORY;
             }
         } else {
-            err = parcel->writeString16(NULL, 0);
+            err = parcel->writeString16(nullptr, 0);
         }
         if (err != NO_ERROR) {
             signalExceptionForError(env, clazz, err);
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index cbce38e..12d8bc6 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -162,7 +162,7 @@
 
 static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jlong ptr) {
     NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
-    return map->getMap()->getKeyboardType();
+    return static_cast<jint>(map->getMap()->getKeyboardType());
 }
 
 static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jlong ptr,
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 45f64f9..d46da87 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -779,6 +779,26 @@
     // CATEGORY: SETTINGS
     // OS: S
     ACTION_COLUMBUS_ACTION_NOTIFICATION_SHADE = 1746;
+
+    // ACTION: Settings > System > Gestures > Double tap > Require harder taps
+    // CATEGORY: SETTINGS
+    // OS: S
+    ACTION_COLUMBUS_LOW_SENSITIVITY = 1747;
+
+    // OPEN: Columbus Gesture training intro in Settings
+    // CATEGORY: SETTINGS
+    // OS: S
+    SETTINGS_COLUMBUS_GESTURE_TRAINING_INTRO = 1748;
+
+    // OPEN: Columbus Gesture training enrolling in Settings
+    // CATEGORY: SETTINGS
+    // OS: S
+    SETTINGS_COLUMBUS_GESTURE_TRAINING_ENROLLING = 1749;
+
+    // OPEN: Columbus Gesture training finished in Settings
+    // CATEGORY: SETTINGS
+    // OS: S
+    SETTINGS_COLUMBUS_GESTURE_TRAINING_FINISHED = 1750;
 }
 
 /**
diff --git a/core/proto/android/app/tvsettings_enums.proto b/core/proto/android/app/tvsettings_enums.proto
index 4a3c594..77bf98f 100644
--- a/core/proto/android/app/tvsettings_enums.proto
+++ b/core/proto/android/app/tvsettings_enums.proto
@@ -149,6 +149,34 @@
     ACCOUNT_SLICE_REG_ACCOUNT = 0x12100000;
 
     // TvSettings > Account & Sign In (Slice) > [A regular account] >
+    // Services
+    ACCOUNT_SLICE_REG_ACCOUNT_SERVICES = 0x12110000;
+
+    // TvSettings > Account & Sign In (Slice) > [A regular account] >
+    // Payment & Purchases
+    ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT = 0x12120000;
+
+    // TvSettings > Account & Sign In (Slice) > [A regular account] >
+    // Payment & Purchases >
+    // Require authentication for purchases (reauth interval)
+    ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH = 0x12121000;
+
+    // TvSettings > Account & Sign In (Slice) > [A regular account] >
+    // Payment & Purchases >
+    // Require authentication for purchases (reauth interval) > Always
+    ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_ALWAYS = 0x12121100;
+
+    // TvSettings > Account & Sign In (Slice) > [A regular account] >
+    // Payment & Purchases >
+    // Require authentication for purchases (reauth interval) > Every 30 minutes
+    ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_30MINS = 0x12121200;
+
+    // TvSettings > Account & Sign In (Slice) > [A regular account] >
+    // Payment & Purchases >
+    // Require authentication for purchases (reauth interval) > Never
+    ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_NEVER = 0x12121300;
+
+    // TvSettings > Account & Sign In (Slice) > [A regular account] >
     // Google Assistant
     ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT = 0x12130000;
 
@@ -220,6 +248,48 @@
     // TvSettings > Account & Sign In (Classic) > Add account
     ACCOUNT_CLASSIC_ADD_ACCOUNT = 0x13A00000;
 
+    // TvSettings > Privacy
+    PRIVACY = 0x14000000;
+
+    // TvSettings > Privacy > Location
+    PRIVACY_LOCATION = 0x14100000;
+
+    // TvSettings > Privacy > Location > Location status (radio button)
+    PRIVACY_LOCATION_STATUS = 0x14110000;
+
+    // TvSettings > Privacy > Location > Location status (radio button) >
+    // Use Wi-Fi to estimate location
+    PRIVACY_LOCATION_STATUS_USE_WIFI = 0x14111000;
+
+    // TvSettings > Privacy > Location > Location status (radio button) > Off
+    PRIVACY_LOCATION_STATUS_OFF = 0x14112000;
+
+    // TvSettings > Privacy > Location > Scanning always available (toggle)
+    PRIVACY_LOCATION_ALWAYS_SCANNING_NETWORKS = 0x14120000;
+
+    // TvSettings > Privacy > Location > [An app that had recent requests]
+    PRIVACY_LOCATION_REQUESTED_APP = 0x14130000;
+
+    // TvSettings > Privacy > Usage & Diagnostics
+    PRIVACY_DIAGNOSTICS = 0x14200000;
+
+    // TvSettings > Privacy > Usage & Diagnostics > On (Toggle)
+    PRIVACY_DIAGNOSTICS_ON_OFF = 0x14210000;
+
+    // TvSettings > Privacy > Ads
+    PRIVACY_ADS = 0x14300000;
+
+    // The following three IDs may not actually be logged as they are within a
+    // GMSCore Activity but we reserve IDs for them.
+    // TvSettings > Privacy > Ads > Reset advertising ID
+    PRIVACY_ADS_RESET_AD_ID = 0x14310000;
+
+    // TvSettings > Privacy > Ads > Opt out of Ads Personalization
+    PRIVACY_ADS_OPT_OUT_PERSONALIZATION = 0x14320000;
+
+    // TvSettings > Privacy > Ads > Ads by Google (WebView)
+    PRIVACY_ADS_ADS_BY_GOOGLE = 0x14330000;
+
     // TvSettings > Display & Sound
     DISPLAY_SOUND = 0x15000000;
 
@@ -540,6 +610,123 @@
     // Cached data (brings up "Clear cached data?" dialog upon click)
     SYSTEM_STORAGE_INTERNAL_STORAGE_CACHED = 0x17512000;
 
+    // TvSettings > System > Ambient mode
+    SYSTEM_AMBIENT = 0x17600000;
+
+    // TvSettings > System > Ambient mode > Start now
+    SYSTEM_AMBIENT_START = 0x17610000;
+
+    // TvSettings > System > Ambient mode > Settings
+    SYSTEM_AMBIENT_SETTINGS = 0x17620000;
+
+    // TvSettings > System > Ambient mode > Settings > Google Photos (Channels)
+    SYSTEM_AMBIENT_SETTINGS_CHANNEL_GP = 0x17621000;
+
+    // TvSettings > System > Ambient mode > Settings > Art gallery (Channels)
+    SYSTEM_AMBIENT_SETTINGS_CHANNEL_AG = 0x17622000;
+
+    // TvSettings > System > Ambient mode > Settings >
+    // Cinematic videos (Channels)
+    SYSTEM_AMBIENT_SETTINGS_CHANNEL_CV = 0x17623000;
+
+    // TvSettings > System > Ambient mode > Settings > Experimental (Channels)
+    SYSTEM_AMBIENT_SETTINGS_CHANNEL_EXP = 0x17624000;
+
+    // TvSettings > System > Ambient mode > Settings > Weather
+    SYSTEM_AMBIENT_SETTINGS_WEATHER = 0x17625000;
+
+    // TvSettings > System > Ambient mode > Settings > Weather > Hide
+    SYSTEM_AMBIENT_SETTINGS_WEATHER_HIDE = 0x17625100;
+
+    // TvSettings > System > Ambient mode > Settings > Weather > Celsius (Unit)
+    SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_C = 0x17625200;
+
+    // TvSettings > System > Ambient mode > Settings > Weather >
+    // Fahrenheit (Unit)
+    SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_F = 0x17625300;
+
+    // TvSettings > System > Ambient mode > Settings > Weather > Both (Unit)
+    SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_BOTH = 0x17625400;
+
+    // TvSettings > System > Ambient mode > Settings > Time
+    SYSTEM_AMBIENT_SETTINGS_TIME = 0x17626000;
+
+    // TvSettings > System > Ambient mode > Settings > Time > Hide
+    SYSTEM_AMBIENT_SETTINGS_TIME_HIDE = 0x17626100;
+
+    // TvSettings > System > Ambient mode > Settings > Time > Show
+    SYSTEM_AMBIENT_SETTINGS_TIME_SHOW = 0x17626200;
+
+    // TvSettings > System > Ambient mode > Settings > Device information
+    SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO = 0x17627000;
+
+    // TvSettings > System > Ambient mode > Settings > Device information > Hide
+    SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO_HIDE = 0x17627100;
+
+    // TvSettings > System > Ambient mode > Settings > Device information > Show
+    SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO_SHOW = 0x17627200;
+
+    // TvSettings > System > Ambient mode > Settings > Personal photo data
+    SYSTEM_AMBIENT_SETTINGS_PPD = 0x17628000;
+
+    // TvSettings > System > Ambient mode > Settings > Personal photo data >
+    // Hide
+    SYSTEM_AMBIENT_SETTINGS_PPD_HIDE = 0x17628100;
+
+    // TvSettings > System > Ambient mode > Settings > Personal photo data >
+    // Show
+    SYSTEM_AMBIENT_SETTINGS_PPD_SHOW = 0x17628200;
+
+    // TvSettings > System > Ambient mode > Settings > Portrait Google Photos
+    SYSTEM_AMBIENT_SETTINGS_PGP = 0x17629000;
+
+    // TvSettings > System > Ambient mode > Settings > Portrait Google Photos >
+    // Hide
+    SYSTEM_AMBIENT_SETTINGS_PGP_HIDE = 0x17629100;
+
+    // TvSettings > System > Ambient mode > Settings > Portrait Google Photos >
+    // Show
+    SYSTEM_AMBIENT_SETTINGS_PGP_SHOW = 0x17629200;
+
+    // TvSettings > System > Ambient mode > Settings > Portrait Google Photos >
+    // Show pairs
+    SYSTEM_AMBIENT_SETTINGS_PGP_SHOW_PAIRS = 0x17629300;
+
+    // TvSettings > System > Ambient mode > Settings > Personal photo curation
+    SYSTEM_AMBIENT_SETTINGS_PPC = 0x1762A000;
+
+    // TvSettings > System > Ambient mode > Settings > Personal photo curation >
+    // All albums
+    SYSTEM_AMBIENT_SETTINGS_PPC_ALL_ALBUMS = 0x1762A100;
+
+    // TvSettings > System > Ambient mode > Settings > Personal photo curation >
+    // Live albums only
+    SYSTEM_AMBIENT_SETTINGS_PPC_LIVE_ALBUMS = 0x1762A200;
+
+    // TvSettings > System > Ambient mode > Settings > Slideshow speed
+    SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED = 0x1762B000;
+
+    // TvSettings > System > Ambient mode > Settings > Slideshow speed > 5s
+    SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_5S = 0x1762B100;
+
+    // TvSettings > System > Ambient mode > Settings > Slideshow speed > 10s
+    SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_10S = 0x1762B200;
+
+    // TvSettings > System > Ambient mode > Settings > Slideshow speed > 30s
+    SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_30S = 0x1762B300;
+
+    // TvSettings > System > Ambient mode > Settings > Slideshow speed > 1m
+    SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_1M = 0x1762B400;
+
+    // TvSettings > System > Ambient mode > Settings > Slideshow speed > 3m
+    SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_3M = 0x1762B500;
+
+    // TvSettings > System > Ambient mode > Settings > Slideshow speed > 5m
+    SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_5M = 0x1762B600;
+
+    // TvSettings > System > Ambient mode > Settings > Slideshow speed > 10m
+    SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_10M = 0x1762B700;
+
     // TvSettings > System > Energy saver
     SYSTEM_ENERGYSAVER = 0x17700000;
 
diff --git a/core/proto/android/server/alarm/alarmmanagerservice.proto b/core/proto/android/server/alarm/alarmmanagerservice.proto
index e1240245..8fe1bfc 100644
--- a/core/proto/android/server/alarm/alarmmanagerservice.proto
+++ b/core/proto/android/server/alarm/alarmmanagerservice.proto
@@ -144,6 +144,8 @@
 
     repeated IdleDispatchEntryProto allow_while_idle_dispatches = 40;
     repeated WakeupEventProto recent_wakeup_history = 41;
+
+    repeated AlarmProto pending_alarms = 42;
 }
 
 // This is a soft wrapper for alarm clock information. It is not representative
diff --git a/core/proto/android/stats/tls/enums.proto b/core/proto/android/stats/tls/enums.proto
index 0ae87ee..a64137d 100644
--- a/core/proto/android/stats/tls/enums.proto
+++ b/core/proto/android/stats/tls/enums.proto
@@ -20,11 +20,11 @@
 // external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java
 enum Protocol {
     UNKNOWN_PROTO = 0;
-    SSLv3 = 1;
-    TLSv1 = 2;
-    TLSv1_1 = 3;
-    TLSv1_2 = 4;
-    TLSv1_3 = 5;
+    SSL_V3 = 1;
+    TLS_V1 = 2;
+    TLS_V1_1 = 3;
+    TLS_V1_2 = 4;
+    TLS_V1_3 = 5;
 }
 
 // Cipher suites' ids are based on IANA's database:
diff --git a/core/proto/android/view/windowlayoutparams.proto b/core/proto/android/view/windowlayoutparams.proto
index 64e6da8..4bb56f8 100644
--- a/core/proto/android/view/windowlayoutparams.proto
+++ b/core/proto/android/view/windowlayoutparams.proto
@@ -35,7 +35,7 @@
     optional int32 height = 5;
     optional float horizontal_margin = 6;
     optional float vertical_margin = 7;
-    optional int32 gravity = 8; // TODO (b/160129453): Add IntDef
+    optional int32 gravity = 8;
     optional int32 soft_input_mode = 9 [(.android.typedef) = "android.view.WindowManager.LayoutParams.SoftInputModeFlags"];
     optional .android.graphics.PixelFormatProto.Format format = 10;
     optional int32 window_animations = 11;
@@ -54,14 +54,14 @@
     optional float preferred_refresh_rate = 16;
     optional int32 preferred_display_mode_id = 17;
     optional bool has_system_ui_listeners = 18;
-    optional uint32 input_feature_flags = 19; // TODO (b/160129453): Add IntDef
+    optional uint32 input_feature_flags = 19 [(.android.typedef) = "android.view.WindowManager.LayoutParams.InputFeatureFlags"];
     optional int64 user_activity_timeout = 20;
 
     optional DisplayProto.ColorMode color_mode = 23;
     optional uint32 flags = 24 [(.android.typedef) = "android.view.WindowManager.LayoutParams.Flags"];
     optional uint32 private_flags = 26 [(.android.typedef) = "android.view.WindowManager.LayoutParams.PrivateFlags"];
-    optional uint32 system_ui_visibility_flags = 27; // TODO (b/160129453): Add IntDef
-    optional uint32 subtree_system_ui_visibility_flags = 28; // TODO (b/160129453): Add IntDef
+    optional uint32 system_ui_visibility_flags = 27 [(.android.typedef) = "android.view.WindowManager.LayoutParams.SystemUiVisibilityFlags"];
+    optional uint32 subtree_system_ui_visibility_flags = 28 [(.android.typedef) = "android.view.WindowManager.LayoutParams.SystemUiVisibilityFlags"];
     optional uint32 appearance = 29 [(.android.typedef) = "android.view.WindowInsetsController.Appearance"];
     optional uint32 behavior = 30 [(.android.typedef) = "android.view.WindowInsetsController.Behavior"];
     optional uint32 fit_insets_types = 31 [(.android.typedef) = "android.view.WindowInsets.Type.InsetsType"];
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4df7d58..a7cf0cf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -349,7 +349,6 @@
     <protected-broadcast android:name="com.android.server.WifiManager.action.START_PNO" />
     <protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" />
     <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" />
-    <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_DISPATCH" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
     <protected-broadcast android:name="com.android.internal.action.EUICC_FACTORY_RESET" />
@@ -2659,6 +2658,14 @@
                 android:description="@string/permdesc_useDataInBackground"
                 android:protectionLevel="normal" />
 
+    <!-- Allows app to request to be associated with a device via
+         {@link android.companion.CompanionDeviceManager}
+         as a "watch"
+         <p>Protection level: normal
+     -->
+    <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_WATCH"
+                android:protectionLevel="normal" />
+
     <!-- Allows a companion app to associate to Wi-Fi.
          <p>Only for use by a single pre-approved app.
          @hide
@@ -3401,6 +3408,12 @@
     <permission android:name="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by any
+         {@link android.companion.CompanionDeviceService}s
+         to ensure that only the system can bind to it. -->
+    <permission android:name="android.permission.BIND_COMPANION_DEVICE_SERVICE"
+                android:protectionLevel="signature" />
+
     <!-- @SystemApi Must be required by the RuntimePermissionPresenterService to ensure
          that only the system can bind to it.
          @hide -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index df03ccc..082397e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -817,6 +817,30 @@
         <!-- B y-intercept --> <item>-0.198650895</item>
     </string-array>
 
+    <string-array name="config_reduceBrightColorsCoefficientsNative">
+        <!-- R a-coefficient --> <item>-0.691218457</item>
+        <!-- R b-coefficient --> <item>0.050135153</item>
+        <!-- R y-intercept --> <item>0.917684143</item>
+        <!-- G a-coefficient --> <item>-0.691218457</item>
+        <!-- G b-coefficient --> <item>0.050135153</item>
+        <!-- G y-intercept --> <item>0.917684143</item>
+        <!-- B a-coefficient --> <item>-0.691218457</item>
+        <!-- B b-coefficient --> <item>0.050135153</item>
+        <!-- B y-intercept --> <item>0.917684143</item>
+    </string-array>
+
+    <string-array name="config_reduceBrightColorsCoefficients">
+        <!-- R a-coefficient --> <item>0.00000000000000154</item>
+        <!-- R b-coefficient --> <item>-1.0</item>
+        <!-- R y-intercept --> <item>1.045977011</item>
+        <!-- G a-coefficient --> <item>0.00000000000000224</item>
+        <!-- G b-coefficient --> <item>-1.0</item>
+        <!-- G y-intercept --> <item>1.045977011</item>
+        <!-- B a-coefficient --> <item>0.0000000000000022</item>
+        <!-- B b-coefficient --> <item>-1.0</item>
+        <!-- B y-intercept --> <item>1.045977011</item>
+    </string-array>
+
     <!-- Boolean indicating whether display white balance is supported. -->
     <bool name="config_displayWhiteBalanceAvailable">false</bool>
 
@@ -1694,7 +1718,7 @@
          to be explicitly declared in this resource to be enabled.
              * SDK level 28 makes the following algorithms mandatory : "cbc(aes)", "hmac(md5)",
                "hmac(sha1)", "hmac(sha256)", "hmac(sha384)", "hmac(sha512)", "rfc4106(gcm(aes))"
-             * SDK level 30 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
+             * SDK level 31 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
                "xcbc(aes)", "rfc7539esp(chacha20,poly1305)"
      -->
     <string-array name="config_optionalIpSecAlgorithms" translatable="false">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a294c9d..4e4e3f8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3158,6 +3158,8 @@
   <java-symbol type="integer" name="config_nightDisplayColorTemperatureMax" />
   <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficients" />
   <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficientsNative" />
+  <java-symbol type="array" name="config_reduceBrightColorsCoefficients" />
+  <java-symbol type="array" name="config_reduceBrightColorsCoefficientsNative" />
   <java-symbol type="array" name="config_availableColorModes" />
   <java-symbol type="integer" name="config_accessibilityColorMode" />
   <java-symbol type="array" name="config_displayCompositionColorModes" />
diff --git a/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java b/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java
index faa67a8..1947c6c 100644
--- a/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java
@@ -26,22 +26,135 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import java.util.Arrays;
+
 @Presubmit
 @RunWith(JUnit4.class)
 public class CombinedVibrationEffectTest {
 
+    private static final VibrationEffect VALID_EFFECT = VibrationEffect.createOneShot(10, 255);
+    private static final VibrationEffect INVALID_EFFECT = new VibrationEffect.OneShot(-1, -1);
+
     @Test
     public void testValidateMono() {
-        CombinedVibrationEffect.createSynced(VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
+        CombinedVibrationEffect.createSynced(VALID_EFFECT);
 
         assertThrows(IllegalArgumentException.class,
-                () -> CombinedVibrationEffect.createSynced(new VibrationEffect.OneShot(-1, -1)));
+                () -> CombinedVibrationEffect.createSynced(INVALID_EFFECT));
+    }
+
+    @Test
+    public void testValidateStereo() {
+        CombinedVibrationEffect.startSynced()
+                .addVibrator(0, VALID_EFFECT)
+                .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+                .combine();
+        CombinedVibrationEffect.startSynced()
+                .addVibrator(0, INVALID_EFFECT)
+                .addVibrator(0, VALID_EFFECT)
+                .combine();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> CombinedVibrationEffect.startSynced()
+                        .addVibrator(0, INVALID_EFFECT)
+                        .combine());
+    }
+
+    @Test
+    public void testValidateSequential() {
+        CombinedVibrationEffect.startSequential()
+                .addNext(0, VALID_EFFECT)
+                .addNext(CombinedVibrationEffect.createSynced(VALID_EFFECT))
+                .combine();
+        CombinedVibrationEffect.startSequential()
+                .addNext(0, VALID_EFFECT)
+                .addNext(0, VALID_EFFECT, 100)
+                .combine();
+        CombinedVibrationEffect.startSequential()
+                .addNext(CombinedVibrationEffect.startSequential()
+                        .addNext(0, VALID_EFFECT)
+                        .combine())
+                .combine();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> CombinedVibrationEffect.startSequential()
+                        .addNext(0, VALID_EFFECT, -1)
+                        .combine());
+        assertThrows(IllegalArgumentException.class,
+                () -> CombinedVibrationEffect.startSequential()
+                        .addNext(0, INVALID_EFFECT)
+                        .combine());
+        assertThrows(IllegalArgumentException.class,
+                () -> new CombinedVibrationEffect.Sequential(
+                        Arrays.asList(CombinedVibrationEffect.startSequential()
+                                .addNext(CombinedVibrationEffect.createSynced(VALID_EFFECT))
+                                .combine()),
+                        Arrays.asList(0))
+                        .validate());
+    }
+
+    @Test
+    public void testNestedSequentialAccumulatesDelays() {
+        CombinedVibrationEffect.Sequential combined =
+                (CombinedVibrationEffect.Sequential) CombinedVibrationEffect.startSequential()
+                        .addNext(CombinedVibrationEffect.startSequential()
+                                        .addNext(0, VALID_EFFECT, /* delay= */ 100)
+                                        .addNext(1, VALID_EFFECT, /* delay= */ 100)
+                                        .combine(),
+                                /* delay= */ 10)
+                        .addNext(CombinedVibrationEffect.startSequential()
+                                .addNext(0, VALID_EFFECT, /* delay= */ 100)
+                                .combine())
+                        .addNext(CombinedVibrationEffect.startSequential()
+                                        .addNext(0, VALID_EFFECT)
+                                        .addNext(0, VALID_EFFECT, /* delay= */ 100)
+                                        .combine(),
+                                /* delay= */ 10)
+                        .combine();
+
+        assertEquals(Arrays.asList(110, 100, 100, 10, 100), combined.getDelays());
+    }
+
+    @Test
+    public void testCombineEmptyFails() {
+        assertThrows(IllegalStateException.class,
+                () -> CombinedVibrationEffect.startSynced().combine());
+        assertThrows(IllegalStateException.class,
+                () -> CombinedVibrationEffect.startSequential().combine());
     }
 
     @Test
     public void testSerializationMono() {
-        CombinedVibrationEffect original = CombinedVibrationEffect.createSynced(
-                VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
+        CombinedVibrationEffect original = CombinedVibrationEffect.createSynced(VALID_EFFECT);
+
+        Parcel parcel = Parcel.obtain();
+        original.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        CombinedVibrationEffect restored = CombinedVibrationEffect.CREATOR.createFromParcel(parcel);
+        assertEquals(original, restored);
+    }
+
+    @Test
+    public void testSerializationStereo() {
+        CombinedVibrationEffect original = CombinedVibrationEffect.startSynced()
+                .addVibrator(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(1, VibrationEffect.createOneShot(10, 255))
+                .combine();
+
+        Parcel parcel = Parcel.obtain();
+        original.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        CombinedVibrationEffect restored = CombinedVibrationEffect.CREATOR.createFromParcel(parcel);
+        assertEquals(original, restored);
+    }
+
+    @Test
+    public void testSerializationSequential() {
+        CombinedVibrationEffect original = CombinedVibrationEffect.startSequential()
+                .addNext(0, VALID_EFFECT)
+                .addNext(CombinedVibrationEffect.createSynced(VALID_EFFECT))
+                .addNext(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 100)
+                .combine();
 
         Parcel parcel = Parcel.obtain();
         original.writeToParcel(parcel, 0);
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
index dc9208d..7306b45 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
@@ -16,14 +16,14 @@
 
 package com.android.internal.os;
 
+import android.system.suspend.internal.WakeLockInfo;
+
 import androidx.test.filters.SmallTest;
 
 import junit.framework.TestCase;
 
 import java.nio.charset.Charset;
 
-import android.system.suspend.WakeLockInfo;
-
 public class KernelWakelockReaderTest extends TestCase {
     /**
      * Helper class that builds the mock Kernel module file /d/wakeup_sources.
diff --git a/core/tests/devicestatetests/Android.bp b/core/tests/devicestatetests/Android.bp
new file mode 100644
index 0000000..409b77b
--- /dev/null
+++ b/core/tests/devicestatetests/Android.bp
@@ -0,0 +1,26 @@
+// 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.
+
+android_test {
+    name: "FrameworksCoreDeviceStateManagerTests",
+    // Include all test java files
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "androidx.test.rules",
+        "frameworks-base-testutils",
+    ],
+    libs: ["android.test.runner"],
+    platform_apis: true,
+    certificate: "platform",
+}
diff --git a/core/tests/devicestatetests/AndroidManifest.xml b/core/tests/devicestatetests/AndroidManifest.xml
new file mode 100644
index 0000000..acd6e7b
--- /dev/null
+++ b/core/tests/devicestatetests/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.frameworks.coretests.devicestate"
+    android:sharedUserId="android.uid.system" >
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.frameworks.coretests.devicestate"
+        android:label="Device State Manager Tests"/>
+
+</manifest>
diff --git a/core/tests/devicestatetests/AndroidTest.xml b/core/tests/devicestatetests/AndroidTest.xml
new file mode 100644
index 0000000..9e38afd
--- /dev/null
+++ b/core/tests/devicestatetests/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+
+<configuration description="Runs Device State Manager Tests.">
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-suite-tag" value="apct-instrumentation"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="FrameworksCoreDeviceStateManagerTests.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.frameworks.coretests.devicestate" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false" />
+    </test>
+</configuration>
diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
new file mode 100644
index 0000000..36f01f9
--- /dev/null
+++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+package android.hardware.devicestate;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.annotation.Nullable;
+import android.os.RemoteException;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.util.ConcurrentUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Unit tests for {@link DeviceStateManagerGlobal}.
+ * <p/>
+ * Run with <code>atest DeviceStateManagerGlobalTest</code>.
+ */
+@RunWith(JUnit4.class)
+@SmallTest
+public final class DeviceStateManagerGlobalTest {
+    private TestDeviceStateManagerService mService;
+    private DeviceStateManagerGlobal mDeviceStateManagerGlobal;
+
+    @Before
+    public void setUp() {
+        mService = new TestDeviceStateManagerService();
+        mDeviceStateManagerGlobal = new DeviceStateManagerGlobal(mService);
+    }
+
+    @Test
+    public void registerListener() {
+        mService.setDeviceState(0);
+
+        TestDeviceStateListener listener1 = new TestDeviceStateListener();
+        TestDeviceStateListener listener2 = new TestDeviceStateListener();
+
+        mDeviceStateManagerGlobal.registerDeviceStateListener(listener1,
+                ConcurrentUtils.DIRECT_EXECUTOR);
+        mDeviceStateManagerGlobal.registerDeviceStateListener(listener2,
+                ConcurrentUtils.DIRECT_EXECUTOR);
+        assertEquals(0, listener1.getLastReportedState().intValue());
+        assertEquals(0, listener2.getLastReportedState().intValue());
+
+        mService.setDeviceState(1);
+        assertEquals(1, listener1.getLastReportedState().intValue());
+        assertEquals(1, listener2.getLastReportedState().intValue());
+    }
+
+    @Test
+    public void unregisterListener() {
+        mService.setDeviceState(0);
+
+        TestDeviceStateListener listener = new TestDeviceStateListener();
+
+        mDeviceStateManagerGlobal.registerDeviceStateListener(listener,
+                ConcurrentUtils.DIRECT_EXECUTOR);
+        assertEquals(0, listener.getLastReportedState().intValue());
+
+        mDeviceStateManagerGlobal.unregisterDeviceStateListener(listener);
+
+        mService.setDeviceState(1);
+        assertEquals(0, listener.getLastReportedState().intValue());
+    }
+
+    private final class TestDeviceStateListener implements DeviceStateManager.DeviceStateListener {
+        @Nullable
+        private Integer mLastReportedDeviceState;
+
+        @Override
+        public void onDeviceStateChanged(int deviceState) {
+            mLastReportedDeviceState = deviceState;
+        }
+
+        @Nullable
+        public Integer getLastReportedState() {
+            return mLastReportedDeviceState;
+        }
+    }
+
+    private final class TestDeviceStateManagerService extends IDeviceStateManager.Stub {
+        private int mDeviceState = DeviceStateManager.INVALID_DEVICE_STATE;
+        private Set<IDeviceStateManagerCallback> mCallbacks = new HashSet<>();
+
+        @Override
+        public void registerCallback(IDeviceStateManagerCallback callback) {
+            if (mCallbacks.contains(callback)) {
+                throw new SecurityException("Callback is already registered.");
+            }
+
+            mCallbacks.add(callback);
+            try {
+                callback.onDeviceStateChanged(mDeviceState);
+            } catch (RemoteException e) {
+                // Do nothing. Should never happen.
+            }
+        }
+
+        public void setDeviceState(int deviceState) {
+            boolean stateChanged = mDeviceState != deviceState;
+            mDeviceState = deviceState;
+            if (stateChanged) {
+                for (IDeviceStateManagerCallback callback : mCallbacks) {
+                    try {
+                        callback.onDeviceStateChanged(mDeviceState);
+                    } catch (RemoteException e) {
+                        // Do nothing. Should never happen.
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
index cc68bb6..4094f83 100644
--- a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
+++ b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
@@ -381,17 +381,31 @@
         }
 
         @Override
-        public List<String> getAllowedCecSettingValues(String name) {
+        public List<String> getAllowedCecSettingStringValues(String name) {
             return new ArrayList<>();
         }
 
         @Override
-        public String getCecSettingValue(String name) {
+        public int[] getAllowedCecSettingIntValues(String name) {
+            return new int[0];
+        }
+
+        @Override
+        public String getCecSettingStringValue(String name) {
             return "";
         }
 
         @Override
-        public void setCecSettingValue(String name, String value) {
+        public void setCecSettingStringValue(String name, String value) {
+        }
+
+        @Override
+        public int getCecSettingIntValue(String name) {
+            return 0;
+        }
+
+        @Override
+        public void setCecSettingIntValue(String name, int value) {
         }
     }
 
diff --git a/core/tests/uwbtests/Android.bp b/core/tests/uwbtests/Android.bp
new file mode 100644
index 0000000..c41c346
--- /dev/null
+++ b/core/tests/uwbtests/Android.bp
@@ -0,0 +1,28 @@
+// Copyright 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.
+
+android_test {
+    name: "UwbManagerTests",
+    static_libs: [
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+    ],
+    libs: [
+        "android.test.runner",
+    ],
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+    test_suites: ["device-tests"],
+}
diff --git a/core/tests/uwbtests/AndroidManifest.xml b/core/tests/uwbtests/AndroidManifest.xml
new file mode 100644
index 0000000..dc991ff
--- /dev/null
+++ b/core/tests/uwbtests/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.uwb">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!-- This is a self-instrumenting test package. -->
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.uwb"
+                     android:label="UWB Manager Tests">
+    </instrumentation>
+
+</manifest>
+
diff --git a/core/tests/uwbtests/AndroidTest.xml b/core/tests/uwbtests/AndroidTest.xml
new file mode 100644
index 0000000..ff4b668
--- /dev/null
+++ b/core/tests/uwbtests/AndroidTest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 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.
+-->
+<configuration description="Config for UWB Manager test cases">
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-suite-tag" value="apct-instrumentation"/>
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="UwbManagerTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-tag" value="UwbManagerTests"/>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.uwb" />
+        <option name="hidden-api-checks" value="false"/>
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
+    </test>
+</configuration>
diff --git a/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java
new file mode 100644
index 0000000..7769c28
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 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.
+ */
+
+package android.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link AngleMeasurement}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AngleMeasurementTest {
+    private static final double EPSILON = 0.00000000001;
+
+    @Test
+    public void testBuilder() {
+        double radians = 0.1234;
+        double errorRadians = 0.5678;
+        double confidence = 0.5;
+
+        AngleMeasurement.Builder builder = new AngleMeasurement.Builder();
+        tryBuild(builder, false);
+
+        builder.setRadians(radians);
+        tryBuild(builder, false);
+
+        builder.setErrorRadians(errorRadians);
+        tryBuild(builder, false);
+
+        builder.setConfidenceLevel(confidence);
+        AngleMeasurement measurement = tryBuild(builder, true);
+
+        assertEquals(measurement.getRadians(), radians, 0);
+        assertEquals(measurement.getErrorRadians(), errorRadians, 0);
+        assertEquals(measurement.getConfidenceLevel(), confidence, 0);
+    }
+
+    private AngleMeasurement tryBuild(AngleMeasurement.Builder builder, boolean expectSuccess) {
+        AngleMeasurement measurement = null;
+        try {
+            measurement = builder.build();
+            if (!expectSuccess) {
+                fail("Expected AngleMeasurement.Builder.build() to fail, but it succeeded");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected AngleMeasurement.Builder.build() to succeed, but it failed");
+            }
+        }
+        return measurement;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        AngleMeasurement measurement = UwbTestUtils.getAngleMeasurement();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AngleMeasurement fromParcel = AngleMeasurement.CREATOR.createFromParcel(parcel);
+        assertEquals(measurement, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
new file mode 100644
index 0000000..077b08f
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 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.
+ */
+
+package android.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link AngleOfArrivalMeasurement}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AngleOfArrivalMeasurementTest {
+
+    @Test
+    public void testBuilder() {
+        AngleMeasurement azimuth = UwbTestUtils.getAngleMeasurement();
+        AngleMeasurement altitude = UwbTestUtils.getAngleMeasurement();
+
+        AngleOfArrivalMeasurement.Builder builder = new AngleOfArrivalMeasurement.Builder();
+        tryBuild(builder, false);
+
+        builder.setAltitudeAngleMeasurement(altitude);
+        tryBuild(builder, false);
+
+        builder.setAzimuthAngleMeasurement(azimuth);
+        AngleOfArrivalMeasurement measurement = tryBuild(builder, true);
+
+        assertEquals(azimuth, measurement.getAzimuth());
+        assertEquals(altitude, measurement.getAltitude());
+    }
+
+    private AngleMeasurement getAngleMeasurement(double radian, double error, double confidence) {
+        return new AngleMeasurement.Builder()
+                .setRadians(radian)
+                .setErrorRadians(error)
+                .setConfidenceLevel(confidence)
+                .build();
+    }
+
+    private AngleOfArrivalMeasurement tryBuild(AngleOfArrivalMeasurement.Builder builder,
+            boolean expectSuccess) {
+        AngleOfArrivalMeasurement measurement = null;
+        try {
+            measurement = builder.build();
+            if (!expectSuccess) {
+                fail("Expected AngleOfArrivalMeasurement.Builder.build() to fail");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected AngleOfArrivalMeasurement.Builder.build() to succeed");
+            }
+        }
+        return measurement;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        AngleOfArrivalMeasurement measurement = UwbTestUtils.getAngleOfArrivalMeasurement();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AngleOfArrivalMeasurement fromParcel =
+                AngleOfArrivalMeasurement.CREATOR.createFromParcel(parcel);
+        assertEquals(measurement, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java
new file mode 100644
index 0000000..439c884
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 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.
+ */
+
+package android.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link DistanceMeasurement}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DistanceMeasurementTest {
+    private static final double EPSILON = 0.00000000001;
+
+    @Test
+    public void testBuilder() {
+        double meters = 0.12;
+        double error = 0.54;
+        double confidence = 0.99;
+
+        DistanceMeasurement.Builder builder = new DistanceMeasurement.Builder();
+        tryBuild(builder, false);
+
+        builder.setMeters(meters);
+        tryBuild(builder, false);
+
+        builder.setErrorMeters(error);
+        tryBuild(builder, false);
+
+        builder.setConfidenceLevel(confidence);
+        DistanceMeasurement measurement = tryBuild(builder, true);
+
+        assertEquals(meters, measurement.getMeters(), 0);
+        assertEquals(error, measurement.getErrorMeters(), 0);
+        assertEquals(confidence, measurement.getConfidenceLevel(), 0);
+    }
+
+    private DistanceMeasurement tryBuild(DistanceMeasurement.Builder builder,
+            boolean expectSuccess) {
+        DistanceMeasurement measurement = null;
+        try {
+            measurement = builder.build();
+            if (!expectSuccess) {
+                fail("Expected DistanceMeasurement.Builder.build() to fail");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected DistanceMeasurement.Builder.build() to succeed");
+            }
+        }
+        return measurement;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        DistanceMeasurement measurement = UwbTestUtils.getDistanceMeasurement();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        DistanceMeasurement fromParcel =
+                DistanceMeasurement.CREATOR.createFromParcel(parcel);
+        assertEquals(measurement, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java
new file mode 100644
index 0000000..a7559d8
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 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.
+ */
+
+package android.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+import android.os.SystemClock;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link RangingMeasurement}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RangingMeasurementTest {
+
+    @Test
+    public void testBuilder() {
+        int status = RangingMeasurement.RANGING_STATUS_SUCCESS;
+        UwbAddress address = UwbTestUtils.getUwbAddress(false);
+        long time = SystemClock.elapsedRealtimeNanos();
+        AngleOfArrivalMeasurement angleMeasurement = UwbTestUtils.getAngleOfArrivalMeasurement();
+        DistanceMeasurement distanceMeasurement = UwbTestUtils.getDistanceMeasurement();
+
+        RangingMeasurement.Builder builder = new RangingMeasurement.Builder();
+
+        builder.setStatus(status);
+        tryBuild(builder, false);
+
+        builder.setElapsedRealtimeNanos(time);
+        tryBuild(builder, false);
+
+        builder.setAngleOfArrivalMeasurement(angleMeasurement);
+        tryBuild(builder, false);
+
+        builder.setDistanceMeasurement(distanceMeasurement);
+        tryBuild(builder, false);
+
+        builder.setRemoteDeviceAddress(address);
+        RangingMeasurement measurement = tryBuild(builder, true);
+
+        assertEquals(status, measurement.getStatus());
+        assertEquals(address, measurement.getRemoteDeviceAddress());
+        assertEquals(time, measurement.getElapsedRealtimeNanos());
+        assertEquals(angleMeasurement, measurement.getAngleOfArrival());
+        assertEquals(distanceMeasurement, measurement.getDistance());
+    }
+
+    private RangingMeasurement tryBuild(RangingMeasurement.Builder builder,
+            boolean expectSuccess) {
+        RangingMeasurement measurement = null;
+        try {
+            measurement = builder.build();
+            if (!expectSuccess) {
+                fail("Expected RangingMeasurement.Builder.build() to fail");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected DistanceMeasurement.Builder.build() to succeed");
+            }
+        }
+        return measurement;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        RangingMeasurement measurement = UwbTestUtils.getRangingMeasurement();
+        measurement.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        RangingMeasurement fromParcel = RangingMeasurement.CREATOR.createFromParcel(parcel);
+        assertEquals(measurement, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java b/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java
new file mode 100644
index 0000000..8095c99
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 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.
+ */
+
+package android.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.os.PersistableBundle;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Duration;
+
+/**
+ * Test of {@link RangingParams}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RangingParamsTest {
+
+    @Test
+    public void testParams_Build() {
+        UwbAddress local = UwbAddress.fromBytes(new byte[] {(byte) 0xA0, (byte) 0x57});
+        UwbAddress remote = UwbAddress.fromBytes(new byte[] {(byte) 0x4D, (byte) 0x8C});
+        int channel = 9;
+        int rxPreamble = 16;
+        int txPreamble = 21;
+        boolean isController = true;
+        boolean isInitiator = false;
+        @RangingParams.StsPhyPacketType int stsPhyType = RangingParams.STS_PHY_PACKET_TYPE_SP2;
+        Duration samplePeriod = Duration.ofSeconds(1, 234);
+        PersistableBundle specParams = new PersistableBundle();
+        specParams.putString("protocol", "some_protocol");
+
+        RangingParams params = new RangingParams.Builder()
+                .setChannelNumber(channel)
+                .setReceivePreambleCodeIndex(rxPreamble)
+                .setTransmitPreambleCodeIndex(txPreamble)
+                .setLocalDeviceAddress(local)
+                .addRemoteDeviceAddress(remote)
+                .setIsController(isController)
+                .setIsInitiator(isInitiator)
+                .setSamplePeriod(samplePeriod)
+                .setStsPhPacketType(stsPhyType)
+                .setSpecificationParameters(specParams)
+                .build();
+
+        assertEquals(params.getLocalDeviceAddress(), local);
+        assertEquals(params.getRemoteDeviceAddresses().size(), 1);
+        assertEquals(params.getRemoteDeviceAddresses().get(0), remote);
+        assertEquals(params.getChannelNumber(), channel);
+        assertEquals(params.isController(), isController);
+        assertEquals(params.isInitiator(), isInitiator);
+        assertEquals(params.getRxPreambleIndex(), rxPreamble);
+        assertEquals(params.getTxPreambleIndex(), txPreamble);
+        assertEquals(params.getStsPhyPacketType(), stsPhyType);
+        assertEquals(params.getSamplingPeriod(), samplePeriod);
+        assertTrue(params.getSpecificationParameters().kindofEquals(specParams));
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        RangingParams params = new RangingParams.Builder()
+                .setChannelNumber(9)
+                .setReceivePreambleCodeIndex(16)
+                .setTransmitPreambleCodeIndex(21)
+                .setLocalDeviceAddress(UwbTestUtils.getUwbAddress(false))
+                .addRemoteDeviceAddress(UwbTestUtils.getUwbAddress(true))
+                .setIsController(false)
+                .setIsInitiator(true)
+                .setSamplePeriod(Duration.ofSeconds(2))
+                .setStsPhPacketType(RangingParams.STS_PHY_PACKET_TYPE_SP1)
+                .build();
+        params.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        RangingParams fromParcel = RangingParams.CREATOR.createFromParcel(parcel);
+        assertEquals(params, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingReportTest.java b/core/tests/uwbtests/src/android/uwb/RangingReportTest.java
new file mode 100644
index 0000000..64c48ba
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/RangingReportTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 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.
+ */
+
+package android.uwb;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * Test of {@link RangingReport}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RangingReportTest {
+
+    @Test
+    public void testBuilder() {
+        List<RangingMeasurement> measurements = UwbTestUtils.getRangingMeasurements(5);
+
+        RangingReport.Builder builder = new RangingReport.Builder();
+        builder.addMeasurements(measurements);
+        RangingReport report = tryBuild(builder, true);
+        verifyMeasurementsEqual(measurements, report.getMeasurements());
+
+
+        builder = new RangingReport.Builder();
+        for (RangingMeasurement measurement : measurements) {
+            builder.addMeasurement(measurement);
+        }
+        report = tryBuild(builder, true);
+        verifyMeasurementsEqual(measurements, report.getMeasurements());
+    }
+
+    private void verifyMeasurementsEqual(List<RangingMeasurement> expected,
+            List<RangingMeasurement> actual) {
+        assertEquals(expected.size(), actual.size());
+        for (int i = 0; i < expected.size(); i++) {
+            assertEquals(expected.get(i), actual.get(i));
+        }
+    }
+
+    private RangingReport tryBuild(RangingReport.Builder builder,
+            boolean expectSuccess) {
+        RangingReport report = null;
+        try {
+            report = builder.build();
+            if (!expectSuccess) {
+                fail("Expected RangingReport.Builder.build() to fail");
+            }
+        } catch (IllegalStateException e) {
+            if (expectSuccess) {
+                fail("Expected RangingReport.Builder.build() to succeed");
+            }
+        }
+        return report;
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        RangingReport report = UwbTestUtils.getRangingReports(5);
+        report.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        RangingReport fromParcel = RangingReport.CREATOR.createFromParcel(parcel);
+        assertEquals(report, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java b/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java
new file mode 100644
index 0000000..ccc88a9
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 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.
+ */
+
+package android.uwb;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link UwbAddress}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class UwbAddressTest {
+
+    @Test
+    public void testFromBytes_Short() {
+        runFromBytes(UwbAddress.SHORT_ADDRESS_BYTE_LENGTH);
+    }
+
+    @Test
+    public void testFromBytes_Extended() {
+        runFromBytes(UwbAddress.EXTENDED_ADDRESS_BYTE_LENGTH);
+    }
+
+    private void runFromBytes(int len) {
+        byte[] addressBytes = getByteArray(len);
+        UwbAddress address = UwbAddress.fromBytes(addressBytes);
+        assertEquals(address.size(), len);
+        assertEquals(addressBytes, address.toBytes());
+    }
+
+    private byte[] getByteArray(int len) {
+        byte[] res = new byte[len];
+        for (int i = 0; i < len; i++) {
+            res[i] = (byte) i;
+        }
+        return res;
+    }
+
+    @Test
+    public void testParcel_Short() {
+        runParcel(true);
+    }
+
+    @Test
+    public void testParcel_Extended() {
+        runParcel(false);
+    }
+
+    private void runParcel(boolean useShortAddress) {
+        Parcel parcel = Parcel.obtain();
+        UwbAddress address = UwbTestUtils.getUwbAddress(useShortAddress);
+        address.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        UwbAddress fromParcel = UwbAddress.CREATOR.createFromParcel(parcel);
+        assertEquals(address, fromParcel);
+    }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
new file mode 100644
index 0000000..62e0b62
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 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.
+ */
+
+package android.uwb;
+
+import android.os.SystemClock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UwbTestUtils {
+    private UwbTestUtils() {}
+
+    public static AngleMeasurement getAngleMeasurement() {
+        return new AngleMeasurement.Builder()
+                .setRadians(getDoubleInRange(-Math.PI, Math.PI))
+                .setErrorRadians(getDoubleInRange(0, Math.PI))
+                .setConfidenceLevel(getDoubleInRange(0, 1))
+                .build();
+    }
+
+    public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() {
+        return new AngleOfArrivalMeasurement.Builder()
+                .setAltitudeAngleMeasurement(getAngleMeasurement())
+                .setAzimuthAngleMeasurement(getAngleMeasurement())
+                .build();
+    }
+
+    public static DistanceMeasurement getDistanceMeasurement() {
+        return new DistanceMeasurement.Builder()
+                .setMeters(getDoubleInRange(0, 100))
+                .setErrorMeters(getDoubleInRange(0, 10))
+                .setConfidenceLevel(getDoubleInRange(0, 1))
+                .build();
+    }
+
+    public static RangingMeasurement getRangingMeasurement() {
+        return getRangingMeasurement(getUwbAddress(false));
+    }
+
+    public static RangingMeasurement getRangingMeasurement(UwbAddress address) {
+        return new RangingMeasurement.Builder()
+                .setDistanceMeasurement(getDistanceMeasurement())
+                .setAngleOfArrivalMeasurement(getAngleOfArrivalMeasurement())
+                .setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos())
+                .setRemoteDeviceAddress(address != null ? address : getUwbAddress(false))
+                .setStatus(RangingMeasurement.RANGING_STATUS_SUCCESS)
+                .build();
+    }
+
+    public static List<RangingMeasurement> getRangingMeasurements(int num) {
+        List<RangingMeasurement> result = new ArrayList<>();
+        for (int i = 0; i < num; i++) {
+            result.add(getRangingMeasurement());
+        }
+        return result;
+    }
+
+    public static RangingReport getRangingReports(int numMeasurements) {
+        RangingReport.Builder builder = new RangingReport.Builder();
+        for (int i = 0; i < numMeasurements; i++) {
+            builder.addMeasurement(getRangingMeasurement());
+        }
+        return builder.build();
+    }
+
+    private static double getDoubleInRange(double min, double max) {
+        return min + (max - min) * Math.random();
+    }
+
+    public static UwbAddress getUwbAddress(boolean isShortAddress) {
+        byte[] addressBytes = new byte[isShortAddress ? UwbAddress.SHORT_ADDRESS_BYTE_LENGTH :
+                UwbAddress.EXTENDED_ADDRESS_BYTE_LENGTH];
+        for (int i = 0; i < addressBytes.length; i++) {
+            addressBytes[i] = (byte) getDoubleInRange(1, 255);
+        }
+        return UwbAddress.fromBytes(addressBytes);
+    }
+}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index b143be7..441c163 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -327,7 +327,7 @@
      * 1) Create Typeface from ttf file.
      * <pre>
      * <code>
-     * Typeface.Builder buidler = new Typeface.Builder("your_font_file.ttf");
+     * Typeface.Builder builder = new Typeface.Builder("your_font_file.ttf");
      * Typeface typeface = builder.build();
      * </code>
      * </pre>
@@ -335,7 +335,7 @@
      * 2) Create Typeface from ttc file in assets directory.
      * <pre>
      * <code>
-     * Typeface.Builder buidler = new Typeface.Builder(getAssets(), "your_font_file.ttc");
+     * Typeface.Builder builder = new Typeface.Builder(getAssets(), "your_font_file.ttc");
      * builder.setTtcIndex(2);  // Set index of font collection.
      * Typeface typeface = builder.build();
      * </code>
@@ -344,7 +344,7 @@
      * 3) Create Typeface with variation settings.
      * <pre>
      * <code>
-     * Typeface.Builder buidler = new Typeface.Builder("your_font_file.ttf");
+     * Typeface.Builder builder = new Typeface.Builder("your_font_file.ttf");
      * builder.setFontVariationSettings("'wght' 700, 'slnt' 20, 'ital' 1");
      * builder.setWeight(700);  // Tell the system that this is a bold font.
      * builder.setItalic(true);  // Tell the system that this is an italic style font.
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 586c512..e7c1582 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -28,6 +28,7 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 import android.util.LongSparseArray;
+import android.util.LongSparseLongArray;
 import android.util.TypedValue;
 
 import com.android.internal.annotations.GuardedBy;
@@ -69,6 +70,11 @@
     private static final LongSparseArray<WeakReference<Font>> FONT_PTR_MAP =
             new LongSparseArray<>();
 
+    private static final Object SOURCE_ID_LOCK = new Object();
+    @GuardedBy("SOURCE_ID_LOCK")
+    private static final LongSparseLongArray FONT_SOURCE_ID_MAP =
+            new LongSparseLongArray(300);  // System font has 200 fonts, so 300 should be enough.
+
     /**
      * A builder class for creating new Font.
      */
@@ -465,13 +471,24 @@
             final String filePath = mFile == null ? "" : mFile.getAbsolutePath();
 
             long ptr;
+            int fontIdentifier;
             if (mFont == null) {
                 ptr = nBuild(builderPtr, readonlyBuffer, filePath, mWeight, italic, mTtcIndex);
+                long fontBufferPtr = nGetFontBufferAddress(ptr);
+                synchronized (SOURCE_ID_LOCK) {
+                    long id = FONT_SOURCE_ID_MAP.get(fontBufferPtr, -1);
+                    if (id == -1) {
+                        id = FONT_SOURCE_ID_MAP.size();
+                        FONT_SOURCE_ID_MAP.put(fontBufferPtr, id);
+                    }
+                    fontIdentifier = (int) id;
+                }
             } else {
                 ptr = nClone(mFont.getNativePtr(), builderPtr, mWeight, italic, mTtcIndex);
+                fontIdentifier = mFont.mSourceIdentifier;
             }
             final Font font = new Font(ptr, readonlyBuffer, mFile,
-                    new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList);
+                    new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList, fontIdentifier);
             sFontRegistry.registerNativeAllocation(font, ptr);
             return font;
         }
@@ -500,13 +517,15 @@
     private final @IntRange(from = 0) int mTtcIndex;
     private final @Nullable FontVariationAxis[] mAxes;
     private final @NonNull String mLocaleList;
+    private final int mSourceIdentifier;  // An identifier of font source data.
 
     /**
      * Use Builder instead
      */
     private Font(long nativePtr, @NonNull ByteBuffer buffer, @Nullable File file,
             @NonNull FontStyle fontStyle, @IntRange(from = 0) int ttcIndex,
-            @Nullable FontVariationAxis[] axes, @NonNull String localeList) {
+            @Nullable FontVariationAxis[] axes, @NonNull String localeList,
+            int sourceIdentifier) {
         mBuffer = buffer;
         mFile = file;
         mFontStyle = fontStyle;
@@ -514,6 +533,7 @@
         mTtcIndex = ttcIndex;
         mAxes = axes;
         mLocaleList = localeList;
+        mSourceIdentifier = sourceIdentifier;
 
         synchronized (MAP_LOCK) {
             FONT_PTR_MAP.append(nGetNativeFontPtr(mNativePtr), new WeakReference<>(this));
@@ -626,6 +646,107 @@
         return mNativePtr;
     }
 
+    /**
+     * Returns the unique ID of the source font data.
+     *
+     * You can use this identifier as a key of the cache or checking if two fonts can be
+     * interpolated with font variation settings.
+     * <pre>
+     * <code>
+     *   // Following three Fonts, fontA, fontB, fontC have the same identifier.
+     *   Font fontA = new Font.Builder("/path/to/font").build();
+     *   Font fontB = new Font.Builder(fontA).setTtcIndex(1).build();
+     *   Font fontC = new Font.Builder(fontB).setFontVariationSettings("'wght' 700).build();
+     *
+     *   // Following fontD has the different identifier from above three.
+     *   Font fontD = new Font.Builder("/path/to/another/font").build();
+     *
+     *   // Following fontE has different identifier from above four even the font path is the same.
+     *   // To get the same identifier, please create new Font instance from existing fonts.
+     *   Font fontE = new Font.Builder("/path/to/font").build();
+     * </code>
+     * </pre>
+     *
+     * Here is an example of caching font object that has
+     * <pre>
+     * <code>
+     *   private LongSparseArray<SparseArray<Font>> mCache = new LongSparseArray<>();
+     *
+     *   private Font getFontWeightVariation(Font font, int weight) {
+     *       // Different collection index is treated as different font.
+     *       long key = ((long) font.getSourceIdentifier()) << 32 | (long) font.getTtcIndex();
+     *
+     *       SparseArray<Font> weightCache = mCache.get(key);
+     *       if (weightCache == null) {
+     *          weightCache = new SparseArray<>();
+     *          mCache.put(key, weightCache);
+     *       }
+     *
+     *       Font cachedFont = weightCache.get(weight);
+     *       if (cachedFont != null) {
+     *         return cachedFont;
+     *       }
+     *
+     *       Font newFont = new Font.Builder(cachedFont)
+     *           .setFontVariationSettings("'wght' " + weight);
+     *           .build();
+     *
+     *       weightCache.put(weight, newFont);
+     *       return newFont;
+     *   }
+     * </code>
+     * </pre>
+     * @return an unique identifier for the font source data.
+     */
+    public int getSourceIdentifier() {
+        return mSourceIdentifier;
+    }
+
+    /**
+     * Returns true if the given font is created from the same source data from this font.
+     *
+     * This method essentially compares {@link ByteBuffer} inside Font, but has some optimization
+     * for faster comparing. This method compares the internal object before going to one-by-one
+     * byte compare with {@link ByteBuffer}. This typically works efficiently if you compares the
+     * font that is created from {@link Builder#Builder(Font)}.
+     *
+     * This API is typically useful for checking if two fonts can be interpolated by font variation
+     * axes. For example, when you call {@link android.text.TextShaper} for the same
+     * string but different style, you may get two font objects which is created from the same
+     * source but have different parameters. You may want to animate between them by interpolating
+     * font variation settings if these fonts are created from the same source.
+     *
+     * @param other a font object to be compared.
+     * @return true if given font is created from the same source from this font. Otherwise false.
+     */
+    private boolean isSameSource(@NonNull Font other) {
+        Objects.requireNonNull(other);
+
+        // Shortcut for the same instance.
+        if (mBuffer == other.mBuffer) {
+            return true;
+        }
+
+        // Shortcut for different font buffer check by comparing size.
+        if (mBuffer.capacity() != other.mBuffer.capacity()) {
+            return false;
+        }
+
+        // ByteBuffer#equals compares all bytes which is not performant for e.g HashMap. Since
+        // underlying native font object holds buffer address, check if this buffer points exactly
+        // the same address as a shortcut of equality. For being compatible with of API30 or before,
+        // check buffer position even if the buffer points the same address.
+        if (mSourceIdentifier == other.mSourceIdentifier
+                && mBuffer.position() == other.mBuffer.position()) {
+            return true;
+        }
+
+        // Unfortunately, need to compare bytes one-by-one since the buffer may be different font
+        // file but has the same file size, or two font has same content but they are allocated
+        // differently. For being compatible with API30 ore before, compare with ByteBuffer#equals.
+        return mBuffer.equals(other.mBuffer);
+    }
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (o == this) {
@@ -643,24 +764,7 @@
             return false;
         }
 
-        // Shortcut for different font buffer check by comparing size.
-        if (mBuffer.capacity() != f.mBuffer.capacity()) {
-            return false;
-        }
-
-        // ByteBuffer#equals compares all bytes which is not performant for e.g HashMap. Since
-        // underlying native font object holds buffer address, check if this buffer points exactly
-        // the same address as a shortcut of equality. For being compatible with of API30 or before,
-        // check buffer position even if the buffer points the same address.
-        if (nIsSameBufferAddress(mNativePtr, f.mNativePtr)
-                && mBuffer.position() == f.mBuffer.position()) {
-            return true;
-        }
-
-        // Unfortunately, need to compare bytes one-by-one since the buffer may be different font
-        // file but has the same file size, or two font has same content but they are allocated
-        // differently. For being compatible with API30 ore before, compare with ByteBuffer#equals.
-        return mBuffer.equals(f.mBuffer);
+        return isSameSource(f);
     }
 
     @Override
@@ -760,5 +864,5 @@
     private static native long nGetNativeFontPtr(long ptr);
 
     @CriticalNative
-    private static native boolean nIsSameBufferAddress(long lFontPtr, long rFontPtr);
+    private static native long nGetFontBufferAddress(long font);
 }
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index c58a123..9050c69 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -496,10 +496,16 @@
      */
     public static final String SIGNATURE_PADDING_RSA_PSS = "PSS";
 
-    static abstract class SignaturePadding {
+    /**
+     * @hide
+     */
+    public abstract static class SignaturePadding {
         private SignaturePadding() {}
 
-        static int toKeymaster(@NonNull @SignaturePaddingEnum String padding) {
+        /**
+         * @hide
+         */
+        public static int toKeymaster(@NonNull @SignaturePaddingEnum String padding) {
             switch (padding.toUpperCase(Locale.US)) {
                 case SIGNATURE_PADDING_RSA_PKCS1:
                     return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN;
@@ -512,7 +518,7 @@
         }
 
         @NonNull
-        static @SignaturePaddingEnum String fromKeymaster(int padding) {
+        public static @SignaturePaddingEnum String fromKeymaster(int padding) {
             switch (padding) {
                 case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN:
                     return SIGNATURE_PADDING_RSA_PKCS1;
@@ -524,7 +530,7 @@
         }
 
         @NonNull
-        static int[] allToKeymaster(@Nullable @SignaturePaddingEnum String[] paddings) {
+        public static int[] allToKeymaster(@Nullable @SignaturePaddingEnum String[] paddings) {
             if ((paddings == null) || (paddings.length == 0)) {
                 return EmptyArray.INT;
             }
@@ -771,4 +777,84 @@
         }
         return result;
     }
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "SECURITY_LEVEL_" }, value = {
+            SECURITY_LEVEL_UNKNOWN,
+            SECURITY_LEVEL_UNKNOWN_SECURE,
+            SECURITY_LEVEL_SOFTWARE,
+            SECURITY_LEVEL_TRUSTED_ENVIRONMENT,
+            SECURITY_LEVEL_STRONGBOX,
+    })
+    public @interface SecurityLevelEnum {}
+
+    /**
+     * This security level indicates that no assumptions can be made about the security level of the
+     * respective key.
+     */
+    public static final int SECURITY_LEVEL_UNKNOWN = -2;
+    /**
+     * This security level indicates that due to the target API level of the caller no exact
+     * statement can be made about the security level of the key, however, the security level
+     * can be considered is at least equivalent to {@link #SECURITY_LEVEL_TRUSTED_ENVIRONMENT}.
+     */
+    public static final int SECURITY_LEVEL_UNKNOWN_SECURE = -1;
+
+    /** Indicates enforcement by system software. */
+    public static final int SECURITY_LEVEL_SOFTWARE = 0;
+
+    /** Indicates enforcement by a trusted execution environment. */
+    public static final int SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1;
+
+    /**
+     * Indicates enforcement by environment meeting the Strongbox security profile,
+     * such as a secure element.
+     */
+    public static final int SECURITY_LEVEL_STRONGBOX = 2;
+
+    /**
+     * @hide
+     */
+    public abstract static class SecurityLevel {
+        private SecurityLevel() {}
+
+        /**
+         * @hide
+         */
+        public static int toKeymaster(int securityLevel) {
+            switch (securityLevel) {
+                case SECURITY_LEVEL_SOFTWARE:
+                    return KeymasterDefs.KM_SECURITY_LEVEL_SOFTWARE;
+                case SECURITY_LEVEL_TRUSTED_ENVIRONMENT:
+                    return KeymasterDefs.KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT;
+                case SECURITY_LEVEL_STRONGBOX:
+                    return KeymasterDefs.KM_SECURITY_LEVEL_STRONGBOX;
+                default:
+                    throw new IllegalArgumentException("Unsupported security level: "
+                            + securityLevel);
+            }
+        }
+
+        /**
+         * @hide
+         */
+        @NonNull
+        public static int fromKeymaster(int securityLevel) {
+            switch (securityLevel) {
+                case KeymasterDefs.KM_SECURITY_LEVEL_SOFTWARE:
+                    return SECURITY_LEVEL_SOFTWARE;
+                case KeymasterDefs.KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT:
+                    return SECURITY_LEVEL_TRUSTED_ENVIRONMENT;
+                case KeymasterDefs.KM_SECURITY_LEVEL_STRONGBOX:
+                    return SECURITY_LEVEL_STRONGBOX;
+                default:
+                    throw new IllegalArgumentException("Unsupported security level: "
+                            + securityLevel);
+            }
+        }
+    }
+
 }
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 0defbd6..39e32c6 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -116,12 +116,15 @@
         "res",
     ],
     static_libs: [
+        "androidx.appcompat_appcompat",
+        "androidx.arch.core_core-runtime",
         "androidx.dynamicanimation_dynamicanimation",
         "kotlinx-coroutines-android",
         "kotlinx-coroutines-core",
+        "iconloader_base",
         "protolog-lib",
+        "SettingsLib",
         "WindowManager-Shell-proto",
-        "androidx.appcompat_appcompat",
     ],
     kotlincflags: ["-Xjvm-default=enable"],
     manifest: "AndroidManifest.xml",
diff --git a/packages/SystemUI/res/layout/bubble_view.xml b/libs/WindowManager/Shell/res/drawable/bubble_dismiss_circle.xml
similarity index 62%
copy from packages/SystemUI/res/layout/bubble_view.xml
copy to libs/WindowManager/Shell/res/drawable/bubble_dismiss_circle.xml
index 78f7cff..2104be4 100644
--- a/packages/SystemUI/res/layout/bubble_view.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_dismiss_circle.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2018 The Android Open Source Project
+  ~ 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.
@@ -12,10 +11,18 @@
   ~ 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
+  ~ limitations under the License.
   -->
-<com.android.systemui.bubbles.BadgedImageView
+<!--
+    The transparent circle outline that encircles the bubbles when they're in the dismiss target.
+-->
+<shape
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/bubble_view"
-    android:layout_width="@dimen/individual_bubble_size"
-    android:layout_height="@dimen/individual_bubble_size"/>
+    android:shape="oval">
+
+    <stroke
+        android:width="1dp"
+        android:color="#66FFFFFF" />
+
+    <solid android:color="#B3000000" />
+</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_dismiss_icon.xml b/libs/WindowManager/Shell/res/drawable/bubble_dismiss_icon.xml
new file mode 100644
index 0000000..ff8fede
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/bubble_dismiss_icon.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ 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.
+  -->
+<!-- The 'X' bubble dismiss icon. This is just ic_close with a stroke. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M19.000000,6.400000l-1.400000,-1.400000 -5.600000,5.600000 -5.600000,-5.600000 -1.400000,1.400000 5.600000,5.600000 -5.600000,5.600000 1.400000,1.400000 5.600000,-5.600000 5.600000,5.600000 1.400000,-1.400000 -5.600000,-5.600000z"
+        android:fillColor="#FFFFFFFF"
+        android:strokeColor="#FF000000"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_ic_create_bubble.xml b/libs/WindowManager/Shell/res/drawable/bubble_ic_create_bubble.xml
new file mode 100644
index 0000000..920671a2
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/bubble_ic_create_bubble.xml
@@ -0,0 +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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="20dp"
+    android:height="20dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M23,5v8h-2V5H3v14h10v2v0H3c-1.1,0 -2,-0.9 -2,-2V5c0,-1.1 0.9,-2 2,-2h18C22.1,3 23,3.9 23,5zM10,8v2.59L5.71,6.29L4.29,7.71L8.59,12H6v2h6V8H10zM19,15c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S20.66,15 19,15z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_empty_bubble_overflow_dark.xml b/libs/WindowManager/Shell/res/drawable/bubble_ic_empty_overflow_dark.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_empty_bubble_overflow_dark.xml
rename to libs/WindowManager/Shell/res/drawable/bubble_ic_empty_overflow_dark.xml
diff --git a/packages/SystemUI/res/drawable/ic_empty_bubble_overflow_light.xml b/libs/WindowManager/Shell/res/drawable/bubble_ic_empty_overflow_light.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_empty_bubble_overflow_light.xml
rename to libs/WindowManager/Shell/res/drawable/bubble_ic_empty_overflow_light.xml
diff --git a/packages/SystemUI/res/drawable/ic_bubble_overflow_button.xml b/libs/WindowManager/Shell/res/drawable/bubble_ic_overflow_button.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_bubble_overflow_button.xml
rename to libs/WindowManager/Shell/res/drawable/bubble_ic_overflow_button.xml
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_ic_stop_bubble.xml b/libs/WindowManager/Shell/res/drawable/bubble_ic_stop_bubble.xml
new file mode 100644
index 0000000..8609576
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/bubble_ic_stop_bubble.xml
@@ -0,0 +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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="20dp"
+    android:height="20dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M11.29,14.71L7,10.41V13H5V7h6v2H8.41l4.29,4.29L11.29,14.71zM21,3H3C1.9,3 1,3.9 1,5v14c0,1.1 0.9,2 2,2h10v0v-2H3V5h18v8h2V5C23,3.9 22.1,3 21,3zM19,15c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S20.66,15 19,15z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/bubble_manage_menu_row.xml b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_row.xml
similarity index 95%
rename from packages/SystemUI/res/drawable/bubble_manage_menu_row.xml
rename to libs/WindowManager/Shell/res/drawable/bubble_manage_menu_row.xml
index a793680..c61ac1c 100644
--- a/packages/SystemUI/res/drawable/bubble_manage_menu_row.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_row.xml
@@ -12,7 +12,7 @@
   ~ 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
+  ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true">
diff --git a/packages/SystemUI/res/drawable/bubble_stack_user_education_bg.xml b/libs/WindowManager/Shell/res/drawable/bubble_stack_user_education_bg.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/bubble_stack_user_education_bg.xml
rename to libs/WindowManager/Shell/res/drawable/bubble_stack_user_education_bg.xml
diff --git a/packages/SystemUI/res/drawable/bubble_stack_user_education_bg_rtl.xml b/libs/WindowManager/Shell/res/drawable/bubble_stack_user_education_bg_rtl.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/bubble_stack_user_education_bg_rtl.xml
rename to libs/WindowManager/Shell/res/drawable/bubble_stack_user_education_bg_rtl.xml
diff --git a/libs/WindowManager/Shell/res/drawable/ic_remove_no_shadow.xml b/libs/WindowManager/Shell/res/drawable/ic_remove_no_shadow.xml
new file mode 100644
index 0000000..265c501
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/ic_remove_no_shadow.xml
@@ -0,0 +1,28 @@
+<?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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorPrimary" >
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M13.41,12l5.29-5.29c0.39-0.39,0.39-1.02,0-1.41c-0.39-0.39-1.02-0.39-1.41,0L12,10.59L6.71,
+        5.29c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41L10.59,12l-5.29,5.29c-0.39,0.39-0.39,1.02,
+        0,1.41c0.39,0.39,1.02,0.39,1.41,0L12,13.41l5.29,5.29c0.39,0.39,1.02,0.39,1.41,0c0.39-0.39,0.39-1.02,0-1.41L13.41,12z"/>
+</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml b/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml
new file mode 100644
index 0000000..e957445
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml
@@ -0,0 +1,26 @@
+<?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.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorBackgroundFloating" />
+    <corners
+        android:bottomLeftRadius="?android:attr/dialogCornerRadius"
+        android:topLeftRadius="?android:attr/dialogCornerRadius"
+        android:bottomRightRadius="?android:attr/dialogCornerRadius"
+        android:topRightRadius="?android:attr/dialogCornerRadius"
+        />
+</shape>
diff --git a/packages/SystemUI/res/layout/bubble_dismiss_target.xml b/libs/WindowManager/Shell/res/layout/bubble_dismiss_target.xml
similarity index 100%
rename from packages/SystemUI/res/layout/bubble_dismiss_target.xml
rename to libs/WindowManager/Shell/res/layout/bubble_dismiss_target.xml
diff --git a/packages/SystemUI/res/layout/bubble_expanded_view.xml b/libs/WindowManager/Shell/res/layout/bubble_expanded_view.xml
similarity index 80%
rename from packages/SystemUI/res/layout/bubble_expanded_view.xml
rename to libs/WindowManager/Shell/res/layout/bubble_expanded_view.xml
index db40c4f..54b08c6 100644
--- a/packages/SystemUI/res/layout/bubble_expanded_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_expanded_view.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2018 The Android Open Source Project
+  ~ 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.
@@ -12,9 +12,9 @@
   ~ 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
+  ~ limitations under the License.
   -->
-<com.android.systemui.bubbles.BubbleExpandedView
+<com.android.wm.shell.bubbles.BubbleExpandedView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
@@ -27,7 +27,7 @@
         android:layout_height="@dimen/bubble_pointer_height"
     />
 
-    <com.android.systemui.statusbar.AlphaOptimizedButton
+    <com.android.wm.shell.common.AlphaOptimizedButton
         style="@android:style/Widget.Material.Button.Borderless"
         android:id="@+id/settings_button"
         android:layout_gravity="start"
@@ -35,7 +35,7 @@
         android:layout_height="wrap_content"
         android:focusable="true"
         android:text="@string/manage_bubbles_text"
-        android:textColor="?attr/wallpaperTextColor"
+        android:textColor="?android:attr/textColorPrimaryInverse"
     />
 
-</com.android.systemui.bubbles.BubbleExpandedView>
+</com.android.wm.shell.bubbles.BubbleExpandedView>
diff --git a/packages/SystemUI/res/layout/bubble_flyout.xml b/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
similarity index 97%
rename from packages/SystemUI/res/layout/bubble_flyout.xml
rename to libs/WindowManager/Shell/res/layout/bubble_flyout.xml
index 22a8135..7fdf290 100644
--- a/packages/SystemUI/res/layout/bubble_flyout.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
@@ -34,7 +34,7 @@
             android:layout_height="30dp"
             android:layout_marginEnd="@dimen/bubble_flyout_avatar_message_space"
             android:scaleType="centerInside"
-            android:src="@drawable/ic_create_bubble"/>
+            android:src="@drawable/bubble_ic_create_bubble"/>
 
         <LinearLayout
             android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
similarity index 95%
rename from packages/SystemUI/res/layout/bubble_manage_menu.xml
rename to libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
index 8494882..3a6aa80 100644
--- a/packages/SystemUI/res/layout/bubble_manage_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
@@ -35,7 +35,7 @@
             android:layout_width="24dp"
             android:layout_height="24dp"
             android:src="@drawable/ic_remove_no_shadow"
-            android:tint="@color/global_actions_text"/>
+            android:tint="@color/bubbles_icon_tint"/>
 
         <TextView
             android:layout_width="wrap_content"
@@ -59,8 +59,8 @@
         <ImageView
             android:layout_width="24dp"
             android:layout_height="24dp"
-            android:src="@drawable/ic_stop_bubble"
-            android:tint="@color/global_actions_text"/>
+            android:src="@drawable/bubble_ic_stop_bubble"
+            android:tint="@color/bubbles_icon_tint"/>
 
         <TextView
             android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/bubble_menu_view.xml b/libs/WindowManager/Shell/res/layout/bubble_menu_view.xml
similarity index 65%
rename from packages/SystemUI/res/layout/bubble_menu_view.xml
rename to libs/WindowManager/Shell/res/layout/bubble_menu_view.xml
index 24608d3..0c1d1a5 100644
--- a/packages/SystemUI/res/layout/bubble_menu_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_menu_view.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<com.android.systemui.bubbles.BubbleMenuView
+<com.android.wm.shell.bubbles.BubbleMenuView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
@@ -30,14 +30,14 @@
 
         <ImageView
             android:id="@*android:id/icon"
-            android:layout_width="@dimen/global_actions_grid_item_icon_width"
-            android:layout_height="@dimen/global_actions_grid_item_icon_height"
-            android:layout_marginTop="@dimen/global_actions_grid_item_icon_top_margin"
-            android:layout_marginBottom="@dimen/global_actions_grid_item_icon_bottom_margin"
-            android:layout_marginLeft="@dimen/global_actions_grid_item_icon_side_margin"
-            android:layout_marginRight="@dimen/global_actions_grid_item_icon_side_margin"
+            android:layout_width="@dimen/bubble_grid_item_icon_width"
+            android:layout_height="@dimen/bubble_grid_item_icon_height"
+            android:layout_marginTop="@dimen/bubble_grid_item_icon_top_margin"
+            android:layout_marginBottom="@dimen/bubble_grid_item_icon_bottom_margin"
+            android:layout_marginLeft="@dimen/bubble_grid_item_icon_side_margin"
+            android:layout_marginRight="@dimen/bubble_grid_item_icon_side_margin"
             android:scaleType="centerInside"
-            android:tint="@color/global_actions_text"
+            android:tint="@color/bubbles_icon_tint"
         />
     </FrameLayout>
-</com.android.systemui.bubbles.BubbleMenuView>
+</com.android.wm.shell.bubbles.BubbleMenuView>
diff --git a/packages/SystemUI/res/layout/bubble_overflow_activity.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_activity.xml
similarity index 100%
rename from packages/SystemUI/res/layout/bubble_overflow_activity.xml
rename to libs/WindowManager/Shell/res/layout/bubble_overflow_activity.xml
diff --git a/packages/SystemUI/res/layout/bubble_overflow_button.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_button.xml
similarity index 89%
rename from packages/SystemUI/res/layout/bubble_overflow_button.xml
rename to libs/WindowManager/Shell/res/layout/bubble_overflow_button.xml
index 8f0fd4f..61000fe 100644
--- a/packages/SystemUI/res/layout/bubble_overflow_button.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_button.xml
@@ -14,9 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<com.android.systemui.bubbles.BadgedImageView
+<com.android.wm.shell.bubbles.BadgedImageView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/bubble_overflow_button"
     android:layout_width="@dimen/individual_bubble_size"
     android:layout_height="@dimen/individual_bubble_size"
-    android:src="@drawable/ic_bubble_overflow_button"/>
+    android:src="@drawable/bubble_ic_overflow_button"/>
diff --git a/packages/SystemUI/res/layout/bubble_overflow_view.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml
similarity index 96%
rename from packages/SystemUI/res/layout/bubble_overflow_view.xml
rename to libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml
index 1218fba..c1f67bd 100644
--- a/packages/SystemUI/res/layout/bubble_overflow_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml
@@ -21,7 +21,7 @@
     android:layout_height="wrap_content"
     android:orientation="vertical">
 
-    <com.android.systemui.bubbles.BadgedImageView
+    <com.android.wm.shell.bubbles.BadgedImageView
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/bubble_view"
         android:layout_gravity="center"
diff --git a/packages/SystemUI/res/layout/bubble_stack_user_education.xml b/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml
similarity index 100%
rename from packages/SystemUI/res/layout/bubble_stack_user_education.xml
rename to libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml
diff --git a/packages/SystemUI/res/layout/bubble_view.xml b/libs/WindowManager/Shell/res/layout/bubble_view.xml
similarity index 94%
rename from packages/SystemUI/res/layout/bubble_view.xml
rename to libs/WindowManager/Shell/res/layout/bubble_view.xml
index 78f7cff..a28bd678 100644
--- a/packages/SystemUI/res/layout/bubble_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_view.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<com.android.systemui.bubbles.BadgedImageView
+<com.android.wm.shell.bubbles.BadgedImageView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/bubble_view"
     android:layout_width="@dimen/individual_bubble_size"
diff --git a/packages/SystemUI/res/layout/bubbles_manage_button_education.xml b/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml
similarity index 92%
rename from packages/SystemUI/res/layout/bubbles_manage_button_education.xml
rename to libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml
index b51dc93..8de06c7 100644
--- a/packages/SystemUI/res/layout/bubbles_manage_button_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml
@@ -64,7 +64,7 @@
         android:id="@+id/button_layout"
         android:orientation="horizontal" >
 
-        <com.android.systemui.statusbar.AlphaOptimizedButton
+        <com.android.wm.shell.common.AlphaOptimizedButton
             style="@android:style/Widget.Material.Button.Borderless"
             android:id="@+id/manage"
             android:layout_gravity="start"
@@ -73,10 +73,10 @@
             android:focusable="true"
             android:clickable="false"
             android:text="@string/manage_bubbles_text"
-            android:textColor="?attr/wallpaperTextColor"
+            android:textColor="?android:attr/textColorPrimaryInverse"
             />
 
-        <com.android.systemui.statusbar.AlphaOptimizedButton
+        <com.android.wm.shell.common.AlphaOptimizedButton
             style="@android:style/Widget.Material.Button.Borderless"
             android:id="@+id/got_it"
             android:layout_gravity="start"
@@ -84,7 +84,7 @@
             android:layout_height="wrap_content"
             android:focusable="true"
             android:text="@string/bubbles_user_education_got_it"
-            android:textColor="?attr/wallpaperTextColor"
+            android:textColor="?android:attr/textColorPrimaryInverse"
             />
     </LinearLayout>
 </LinearLayout>
diff --git a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
index bee9f41..6342c00 100644
--- a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
+++ b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
@@ -79,12 +79,6 @@
       "group": "WM_SHELL_TASK_ORG",
       "at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java"
     },
-    "-712674749": {
-      "message": "Clip description: %s",
-      "level": "VERBOSE",
-      "group": "WM_SHELL_DRAG_AND_DROP",
-      "at": "com\/android\/wm\/shell\/draganddrop\/DragAndDropController.java"
-    },
     "-710770147": {
       "message": "Add target: %s",
       "level": "VERBOSE",
@@ -121,6 +115,12 @@
       "group": "WM_SHELL_DRAG_AND_DROP",
       "at": "com\/android\/wm\/shell\/draganddrop\/DropOutlineDrawable.java"
     },
+    "375908576": {
+      "message": "Clip description: handlingDrag=%b itemCount=%d mimeTypes=%s",
+      "level": "VERBOSE",
+      "group": "WM_SHELL_DRAG_AND_DROP",
+      "at": "com\/android\/wm\/shell\/draganddrop\/DragAndDropController.java"
+    },
     "481673835": {
       "message": "addListenerForTaskId taskId=%s",
       "level": "VERBOSE",
@@ -169,12 +169,6 @@
       "group": "WM_SHELL_DRAG_AND_DROP",
       "at": "com\/android\/wm\/shell\/draganddrop\/DragLayout.java"
     },
-    "1842752748": {
-      "message": "Clip description: handlingDrag=%b mimeTypes=%s",
-      "level": "VERBOSE",
-      "group": "WM_SHELL_DRAG_AND_DROP",
-      "at": "com\/android\/wm\/shell\/draganddrop\/DragAndDropController.java"
-    },
     "1862198614": {
       "message": "Drag event: action=%s x=%f y=%f xOffset=%f yOffset=%f",
       "level": "VERBOSE",
diff --git a/libs/WindowManager/Shell/res/values-land/dimens.xml b/libs/WindowManager/Shell/res/values-land/dimens.xml
index 77a601d..aafba58 100644
--- a/libs/WindowManager/Shell/res/values-land/dimens.xml
+++ b/libs/WindowManager/Shell/res/values-land/dimens.xml
@@ -18,4 +18,8 @@
 <resources>
     <dimen name="docked_divider_handle_width">2dp</dimen>
     <dimen name="docked_divider_handle_height">16dp</dimen>
+
+    <!-- Padding between status bar and bubbles when displayed in expanded state, smaller
+     value in landscape since we have limited vertical space-->
+    <dimen name="bubble_padding_top">4dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/bubble_manage_menu_row.xml b/libs/WindowManager/Shell/res/values-night/colors.xml
similarity index 69%
copy from packages/SystemUI/res/drawable/bubble_manage_menu_row.xml
copy to libs/WindowManager/Shell/res/values-night/colors.xml
index a793680..24b3640 100644
--- a/packages/SystemUI/res/drawable/bubble_manage_menu_row.xml
+++ b/libs/WindowManager/Shell/res/values-night/colors.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
   ~ Copyright (C) 2020 The Android Open Source Project
   ~
@@ -12,10 +11,10 @@
   ~ 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
+  ~ limitations under the License.
   -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true">
-        <ripple android:color="#99999999" />
-    </item>
-</selector>
\ No newline at end of file
+
+<resources>
+    <!-- Bubbles -->
+    <color name="bubbles_icon_tint">@color/GM2_grey_200</color>
+</resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index cc3bf2a..1674d0b 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -25,4 +25,14 @@
 
     <!-- Background for the various drop targets when handling drag and drop. -->
     <color name="drop_outline_background">#330000FF</color>
+
+    <!-- Bubbles -->
+    <color name="bubbles_light">#FFFFFF</color>
+    <color name="bubbles_dark">@color/GM2_grey_800</color>
+    <color name="bubbles_icon_tint">@color/GM2_grey_700</color>
+
+    <!-- GM2 colors -->
+    <color name="GM2_grey_200">#E8EAED</color>
+    <color name="GM2_grey_700">#5F6368</color>
+    <color name="GM2_grey_800">#3C4043</color>
 </resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index b87a642..8a60aaf 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -75,4 +75,94 @@
 
     <!-- The amount to inset the drop target regions from the edge of the display -->
     <dimen name="drop_layout_display_margin">16dp</dimen>
+
+    <!-- The menu grid size for bubble menu. -->
+    <dimen name="bubble_grid_item_icon_width">20dp</dimen>
+    <dimen name="bubble_grid_item_icon_height">20dp</dimen>
+    <dimen name="bubble_grid_item_icon_top_margin">12dp</dimen>
+    <dimen name="bubble_grid_item_icon_bottom_margin">4dp</dimen>
+    <dimen name="bubble_grid_item_icon_side_margin">22dp</dimen>
+
+    <!-- How much each bubble is elevated. -->
+    <dimen name="bubble_elevation">1dp</dimen>
+    <!-- How much the bubble flyout text container is elevated. -->
+    <dimen name="bubble_flyout_elevation">4dp</dimen>
+    <!-- How much padding is around the left and right sides of the flyout text. -->
+    <dimen name="bubble_flyout_padding_x">12dp</dimen>
+    <!-- How much padding is around the top and bottom of the flyout text. -->
+    <dimen name="bubble_flyout_padding_y">10dp</dimen>
+    <!-- Size of the triangle that points from the flyout to the bubble stack. -->
+    <dimen name="bubble_flyout_pointer_size">6dp</dimen>
+    <!-- How much space to leave between the flyout (tip of the arrow) and the bubble stack. -->
+    <dimen name="bubble_flyout_space_from_bubble">8dp</dimen>
+    <!-- How much space to leave between the flyout text and the avatar displayed in the flyout. -->
+    <dimen name="bubble_flyout_avatar_message_space">6dp</dimen>
+    <!-- Padding between status bar and bubbles when displayed in expanded state -->
+    <dimen name="bubble_padding_top">16dp</dimen>
+    <!-- Size of individual bubbles. -->
+    <dimen name="individual_bubble_size">60dp</dimen>
+    <!-- Size of bubble bitmap. -->
+    <dimen name="bubble_bitmap_size">52dp</dimen>
+    <!-- Size of bubble icon bitmap. -->
+    <dimen name="bubble_overflow_icon_bitmap_size">24dp</dimen>
+    <!-- Extra padding added to the touchable rect for bubbles so they are easier to grab. -->
+    <dimen name="bubble_touch_padding">12dp</dimen>
+    <!-- Size of the circle around the bubbles when they're in the dismiss target. -->
+    <dimen name="bubble_dismiss_encircle_size">52dp</dimen>
+    <!-- Padding around the view displayed when the bubble is expanded -->
+    <dimen name="bubble_expanded_view_padding">4dp</dimen>
+    <!-- This should be at least the size of bubble_expanded_view_padding; it is used to include
+         a slight touch slop around the expanded view. -->
+    <dimen name="bubble_expanded_view_slop">8dp</dimen>
+    <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded -->
+    <dimen name="bubble_expanded_default_height">180dp</dimen>
+    <!-- Default height of bubble overflow -->
+    <dimen name="bubble_overflow_height">480dp</dimen>
+    <!-- Bubble overflow padding when there are no bubbles  -->
+    <dimen name="bubble_overflow_empty_state_padding">16dp</dimen>
+    <!-- Padding of container for overflow bubbles -->
+    <dimen name="bubble_overflow_padding">15dp</dimen>
+    <!-- Padding of label for bubble overflow view -->
+    <dimen name="bubble_overflow_text_padding">7dp</dimen>
+    <!-- Height of bubble overflow empty state illustration -->
+    <dimen name="bubble_empty_overflow_image_height">200dp</dimen>
+    <!-- Padding of bubble overflow empty state subtitle -->
+    <dimen name="bubble_empty_overflow_subtitle_padding">50dp</dimen>
+    <!-- Height of the triangle that points to the expanded bubble -->
+    <dimen name="bubble_pointer_height">8dp</dimen>
+    <!-- Width of the triangle that points to the expanded bubble -->
+    <dimen name="bubble_pointer_width">12dp</dimen>
+    <!-- Extra padding around the dismiss target for bubbles -->
+    <dimen name="bubble_dismiss_slop">16dp</dimen>
+    <!-- Height of button allowing users to adjust settings for bubbles. -->
+    <dimen name="bubble_manage_button_height">48dp</dimen>
+    <!-- Max width of the message bubble-->
+    <dimen name="bubble_message_max_width">144dp</dimen>
+    <!-- Min width of the message bubble -->
+    <dimen name="bubble_message_min_width">32dp</dimen>
+    <!-- Interior padding of the message bubble -->
+    <dimen name="bubble_message_padding">4dp</dimen>
+    <!-- Offset between bubbles in their stacked position. -->
+    <dimen name="bubble_stack_offset">10dp</dimen>
+    <!-- Offset between stack y and animation y for bubble swap. -->
+    <dimen name="bubble_swap_animation_offset">15dp</dimen>
+    <!-- How far offscreen the bubble stack rests. Cuts off padding and part of icon bitmap. -->
+    <dimen name="bubble_stack_offscreen">9dp</dimen>
+    <!-- How far down the screen the stack starts. -->
+    <dimen name="bubble_stack_starting_offset_y">120dp</dimen>
+    <!-- Space between the pointer triangle and the bubble expanded view -->
+    <dimen name="bubble_pointer_margin">8dp</dimen>
+    <!-- Padding applied to the bubble dismiss target. Touches in this padding cause the bubbles to
+         snap to the dismiss target. -->
+    <dimen name="bubble_dismiss_target_padding_x">40dp</dimen>
+    <dimen name="bubble_dismiss_target_padding_y">20dp</dimen>
+    <dimen name="bubble_manage_menu_elevation">4dp</dimen>
+
+    <!-- Bubbles user education views -->
+    <dimen name="bubbles_manage_education_width">160dp</dimen>
+    <!-- The inset from the top bound of the manage button to place the user education. -->
+    <dimen name="bubbles_manage_education_top_inset">65dp</dimen>
+    <!-- Size of padding for the user education cling, this should at minimum be larger than
+        individual_bubble_size + some padding. -->
+    <dimen name="bubble_stack_user_education_side_inset">72dp</dimen>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/ids.xml b/libs/WindowManager/Shell/res/values/ids.xml
index fb89238..434a000 100644
--- a/libs/WindowManager/Shell/res/values/ids.xml
+++ b/libs/WindowManager/Shell/res/values/ids.xml
@@ -23,4 +23,21 @@
     <item type="id" name="action_move_tl_50" />
     <item type="id" name="action_move_tl_30" />
     <item type="id" name="action_move_rb_full" />
+
+    <!-- For saving PhysicsAnimationLayout animations/animators as view tags. -->
+    <item type="id" name="translation_x_dynamicanimation_tag"/>
+    <item type="id" name="translation_y_dynamicanimation_tag"/>
+    <item type="id" name="translation_z_dynamicanimation_tag"/>
+    <item type="id" name="alpha_dynamicanimation_tag"/>
+    <item type="id" name="scale_x_dynamicanimation_tag"/>
+    <item type="id" name="scale_y_dynamicanimation_tag"/>
+    <item type="id" name="physics_animator_tag"/>
+    <item type="id" name="target_animator_tag" />
+    <item type="id" name="reorder_animator_tag"/>
+
+    <!-- Accessibility actions for bubbles. -->
+    <item type="id" name="action_move_top_left"/>
+    <item type="id" name="action_move_top_right"/>
+    <item type="id" name="action_move_bottom_left"/>
+    <item type="id" name="action_move_bottom_right"/>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/integers.xml b/libs/WindowManager/Shell/res/values/integers.xml
new file mode 100644
index 0000000..583bf33
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values/integers.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ 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.
+  -->
+<resources>
+    <!-- Maximum number of bubbles to render and animate at one time. While the animations used are
+         lightweight translation animations, this number can be reduced on lower end devices if any
+         performance issues arise. -->
+    <integer name="bubbles_max_rendered">5</integer>
+    <!-- Number of columns in bubble overflow. -->
+    <integer name="bubbles_overflow_columns">4</integer>
+    <!-- Maximum number of bubbles we allow in overflow before we dismiss the oldest one. -->
+    <integer name="bubbles_max_overflow">16</integer>
+</resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index da5965d..30ef72c 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -97,4 +97,53 @@
     <string name="accessibility_action_start_one_handed">Start one-handed mode</string>
     <!-- Accessibility description for stop one-handed mode [CHAR LIMIT=NONE] -->
     <string name="accessibility_action_stop_one_handed">Exit one-handed mode</string>
+
+    <!-- Text used for content description of settings button in the header of expanded bubble
+         view. [CHAR_LIMIT=NONE] -->
+    <string name="bubbles_settings_button_description">Settings for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> bubbles</string>
+    <!-- Content description for button that shows bubble overflow on click [CHAR LIMIT=NONE] -->
+    <string name="bubble_overflow_button_content_description">Overflow</string>
+    <!-- Action to add overflow bubble back to stack. [CHAR LIMIT=NONE] -->
+    <string name="bubble_accessibility_action_add_back">Add back to stack</string>
+    <!-- Content description when a bubble is focused. [CHAR LIMIT=NONE] -->
+    <string name="bubble_content_description_single"><xliff:g id="notification_title" example="some title">%1$s</xliff:g> from <xliff:g id="app_name" example="YouTube">%2$s</xliff:g></string>
+    <!-- Content description when the stack of bubbles is focused. [CHAR LIMIT=NONE] -->
+    <string name="bubble_content_description_stack"><xliff:g id="notification_title" example="some title">%1$s</xliff:g> from <xliff:g id="app_name" example="YouTube">%2$s</xliff:g> and <xliff:g id="bubble_count" example="4">%3$d</xliff:g> more</string>
+    <!-- Action in accessibility menu to move the stack of bubbles to the top left of the screen. [CHAR LIMIT=30] -->
+    <string name="bubble_accessibility_action_move_top_left">Move top left</string>
+    <!-- Action in accessibility menu to move the stack of bubbles to the top right of the screen. [CHAR LIMIT=30] -->
+    <string name="bubble_accessibility_action_move_top_right">Move top right</string>
+    <!-- Action in accessibility menu to move the stack of bubbles to the bottom left of the screen. [CHAR LIMIT=30]-->
+    <string name="bubble_accessibility_action_move_bottom_left">Move bottom left</string>
+    <!-- Action in accessibility menu to move the stack of bubbles to the bottom right of the screen. [CHAR LIMIT=30]-->
+    <string name="bubble_accessibility_action_move_bottom_right">Move bottom right</string>
+    <!-- Label for the button that takes the user to the notification settings for the given app. -->
+    <string name="bubbles_app_settings"><xliff:g id="notification_title" example="Android Messages">%1$s</xliff:g> settings</string>
+    <!-- Text used for the bubble dismiss area. Bubbles dragged to, or flung towards, this area will go away. [CHAR LIMIT=30] -->
+    <string name="bubble_dismiss_text">Dismiss bubble</string>
+    <!-- Button text to stop a conversation from bubbling [CHAR LIMIT=60]-->
+    <string name="bubbles_dont_bubble_conversation">Don\u2019t bubble conversation</string>
+    <!-- Title text for the bubbles feature education cling shown when a bubble is on screen for the first time. [CHAR LIMIT=60]-->
+    <string name="bubbles_user_education_title">Chat using bubbles</string>
+    <!-- Descriptive text for the bubble feature education cling shown when a bubble is on screen for the first time. [CHAR LIMIT=NONE] -->
+    <string name="bubbles_user_education_description">New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it.</string>
+    <!-- Title text for the bubble "manage" button tool tip highlighting where users can go to control bubble settings. [CHAR LIMIT=60]-->
+    <string name="bubbles_user_education_manage_title">Control bubbles anytime</string>
+    <!-- Descriptive text for the bubble "manage" button tool tip highlighting where users can go to control bubble settings. [CHAR LIMIT=80]-->
+    <string name="bubbles_user_education_manage">Tap Manage to turn off bubbles from this app</string>
+    <!-- Button text for dismissing the bubble "manage" button tool tip  [CHAR LIMIT=20]-->
+    <string name="bubbles_user_education_got_it">Got it</string>
+    <!-- [CHAR LIMIT=NONE] Empty overflow title -->
+    <string name="bubble_overflow_empty_title">No recent bubbles</string>
+    <!-- [CHAR LIMIT=NONE] Empty overflow subtitle -->
+    <string name="bubble_overflow_empty_subtitle">Recent bubbles and dismissed bubbles will appear here</string>
+
+    <!-- [CHAR LIMIT=100] Notification Importance title -->
+    <string name="notification_bubble_title">Bubble</string>
+
+    <!-- The text for the manage bubbles link. [CHAR LIMIT=NONE] -->
+    <string name="manage_bubbles_text">Manage</string>
+
+    <!-- Content description to tell the user a bubble has been dismissed. -->
+    <string name="accessibility_bubble_dismissed">Bubble dismissed.</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/bubbles/TaskView.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
index 0a2cfbf..59a765d 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 
@@ -30,26 +30,23 @@
 import android.content.pm.ShortcutInfo;
 import android.graphics.Rect;
 import android.os.Binder;
+import android.util.CloseGuard;
 import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
-import com.android.wm.shell.ShellTaskOrganizer;
-
-import dalvik.system.CloseGuard;
-
 import java.io.PrintWriter;
 import java.util.concurrent.Executor;
 
 /**
  * View that can display a task.
  */
-// TODO: Place in com.android.wm.shell vs. com.android.wm.shell.bubbles on shell migration.
 public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
         ShellTaskOrganizer.TaskListener {
 
+    /** Callback for listening task state. */
     public interface Listener {
         /** Called when the container is ready for launching activities. */
         default void onInitialized() {}
@@ -70,7 +67,7 @@
         default void onBackPressedOnTaskRoot(int taskId) {}
     }
 
-    private final CloseGuard mGuard = CloseGuard.get();
+    private final CloseGuard mGuard = new CloseGuard();
 
     private final ShellTaskOrganizer mTaskOrganizer;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
index a3b720c..8aca01d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
@@ -56,4 +56,10 @@
      * Interpolator to be used when animating a move based on a click. Pair with enough duration.
      */
     public static final Interpolator TOUCH_RESPONSE = new PathInterpolator(0.3f, 0f, 0.1f, 1f);
+
+    /**
+     * Interpolator to be used when animating a panel closing.
+     */
+    public static final Interpolator PANEL_CLOSE_ACCELERATED =
+            new PathInterpolator(0.3f, 0, 0.5f, 1);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
index 8bcffc8..4d06c03 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -13,7 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
+
+import static android.graphics.Paint.DITHER_FLAG;
+import static android.graphics.Paint.FILTER_BITMAP_FLAG;
 
 import android.annotation.Nullable;
 import android.content.Context;
@@ -28,14 +31,11 @@
 import android.widget.ImageView;
 
 import com.android.launcher3.icons.DotRenderer;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.Interpolators;
 
 import java.util.EnumSet;
 
-import static android.graphics.Paint.DITHER_FLAG;
-import static android.graphics.Paint.FILTER_BITMAP_FLAG;
-
 /**
  * View that displays an adaptive icon with an app-badge and a dot.
  *
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 09d9e03..93ed395 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.os.AsyncTask.Status.FINISHED;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 598a604..05acb55 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
@@ -22,8 +22,8 @@
 import static android.view.View.VISIBLE;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
@@ -59,8 +59,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.bubbles.dagger.BubbleModule;
-import com.android.systemui.dagger.qualifiers.Main;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -165,7 +163,7 @@
     private boolean mIsStatusBarShade = true;
 
     /**
-     * Injected constructor. See {@link BubbleModule}.
+     * Injected constructor.
      */
     public static BubbleController create(Context context,
             @Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
@@ -175,7 +173,7 @@
             WindowManagerShellWrapper windowManagerShellWrapper,
             LauncherApps launcherApps,
             UiEventLogger uiEventLogger,
-            @Main Handler mainHandler,
+            Handler mainHandler,
             ShellTaskOrganizer organizer) {
         BubbleLogger logger = new BubbleLogger(uiEventLogger);
         return new BubbleController(context,
@@ -903,7 +901,7 @@
                 }
                 if (!mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
                     if (!mBubbleData.hasOverflowBubbleWithKey(bubble.getKey())
-                        && (!bubble.showInShade()
+                            && (!bubble.showInShade()
                             || reason == DISMISS_NOTIF_CANCEL
                             || reason == DISMISS_GROUP_CANCELLED)) {
                         // The bubble is now gone & the notification is hidden from the shade, so
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 8cacc8f..b6a97e2 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -13,13 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
-import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_DATA;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_DATA;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.annotation.NonNull;
 import android.app.PendingIntent;
@@ -33,8 +33,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FrameworkStatsLog;
-import com.android.systemui.R;
-import com.android.systemui.bubbles.Bubbles.DismissReason;
+import com.android.wm.shell.R;
+import com.android.wm.shell.bubbles.Bubbles.DismissReason;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
index 2ab9e87..fc565f1 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles
+package com.android.wm.shell.bubbles
 
 import android.annotation.SuppressLint
 import android.annotation.UserIdInt
@@ -24,9 +24,9 @@
 import android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER
 import android.os.UserHandle
 import android.util.Log
-import com.android.systemui.bubbles.storage.BubbleEntity
-import com.android.systemui.bubbles.storage.BubblePersistentRepository
-import com.android.systemui.bubbles.storage.BubbleVolatileRepository
+import com.android.wm.shell.bubbles.storage.BubbleEntity
+import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
+import com.android.wm.shell.bubbles.storage.BubbleVolatileRepository
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Job
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
index 3937422..53f4e87 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import android.content.Context;
 import android.provider.Settings;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleEntry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleEntry.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java
index a0d3391..ff68861 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleEntry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static android.app.Notification.FLAG_BUBBLE;
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index ae3c683..74521c7 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
-import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPANDED_VIEW;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.systemui.bubbles.BubbleOverflowActivity.EXTRA_BUBBLE_CONTROLLER;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPANDED_VIEW;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.wm.shell.bubbles.BubbleOverflowActivity.EXTRA_BUBBLE_CONTROLLER;
 
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
@@ -54,10 +54,11 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.systemui.R;
-import com.android.systemui.recents.TriangleShape;
-import com.android.systemui.statusbar.AlphaOptimizedButton;
+import com.android.wm.shell.R;
+import com.android.wm.shell.TaskView;
+import com.android.wm.shell.common.AlphaOptimizedButton;
 import com.android.wm.shell.common.HandlerExecutor;
+import com.android.wm.shell.common.TriangleShape;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
index d8b3250..460e0e7 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static android.graphics.Paint.ANTI_ALIAS_FLAG;
 import static android.graphics.Paint.FILTER_BITMAP_FLAG;
-import static com.android.systemui.Interpolators.ALPHA_IN;
-import static com.android.systemui.Interpolators.ALPHA_OUT;
+
+import static com.android.wm.shell.animation.Interpolators.ALPHA_IN;
+import static com.android.wm.shell.animation.Interpolators.ALPHA_OUT;
 
 import android.animation.ArgbEvaluator;
 import android.content.Context;
@@ -47,8 +48,8 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.systemui.R;
-import com.android.systemui.recents.TriangleShape;
+import com.android.wm.shell.R;
+import com.android.wm.shell.common.TriangleShape;
 
 /**
  * Flyout view that appears as a 'chat bubble' alongside the bubble stack. The flyout can visually
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java
index 371e849..2d9da21 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -26,14 +26,13 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 
 import com.android.launcher3.icons.BaseIconFactory;
 import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.ShadowGenerator;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
 
 /**
  * Factory for creating normalized bubble icons.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleLogger.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java
index a24f5c2..3361c4c 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLogger.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEvent;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index 297144a..686d2d4 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles
+package com.android.wm.shell.bubbles
 
 import android.app.ActivityTaskManager.INVALID_TASK_ID
 import android.content.Context
@@ -31,7 +31,7 @@
 import android.view.LayoutInflater
 import android.view.View
 import android.widget.FrameLayout
-import com.android.systemui.R
+import com.android.wm.shell.R
 
 class BubbleOverflow(
     private val context: Context,
@@ -72,7 +72,7 @@
         updateResources()
         expandedView.applyThemeAttrs()
         // Apply inset and new style to fresh icon drawable.
-        overflowBtn.setImageResource(R.drawable.ic_bubble_overflow_button)
+        overflowBtn.setImageResource(R.drawable.bubble_ic_overflow_button)
         updateBtnTheme()
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java
index bc84173..2759b59 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
-import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_OVERFLOW;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_OVERFLOW;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.app.Activity;
 import android.content.Context;
@@ -43,13 +43,12 @@
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.util.ContrastColorUtil;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Consumer;
 
-
 /**
  * Activity for showing aged out bubbles.
  * Must be public to be accessible to androidx...AppComponentFactory
@@ -168,8 +167,8 @@
         final boolean isNightMode = (mode == Configuration.UI_MODE_NIGHT_YES);
 
         mEmptyStateImage.setImageDrawable(isNightMode
-                ? res.getDrawable(R.drawable.ic_empty_bubble_overflow_dark)
-                : res.getDrawable(R.drawable.ic_empty_bubble_overflow_light));
+                ? res.getDrawable(R.drawable.bubble_ic_empty_overflow_dark)
+                : res.getDrawable(R.drawable.bubble_ic_empty_overflow_light));
 
         findViewById(android.R.id.content)
                 .setBackgroundColor(isNightMode
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubblePositioner.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 029caee..eccd009 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import android.content.Context;
 import android.content.res.Configuration;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 69ed5b7..155f342 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * 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.
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
-import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_STACK_VIEW;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_STACK_VIEW;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -71,13 +71,13 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FrameworkStatsLog;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.bubbles.animation.AnimatableScaleMatrix;
-import com.android.systemui.bubbles.animation.ExpandedAnimationController;
-import com.android.systemui.bubbles.animation.PhysicsAnimationLayout;
-import com.android.systemui.bubbles.animation.StackAnimationController;
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix;
+import com.android.wm.shell.bubbles.animation.ExpandedAnimationController;
+import com.android.wm.shell.bubbles.animation.PhysicsAnimationLayout;
+import com.android.wm.shell.bubbles.animation.StackAnimationController;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
 
@@ -2661,14 +2661,17 @@
                 .floatValue();
     }
 
+    /** Set the start position of the bubble stack. */
     public void setStackStartPosition(RelativeStackPosition position) {
         mStackAnimationController.setStackStartPosition(position);
     }
 
+    /** @return the position of the bubble stack. */
     public PointF getStackPosition() {
         return mStackAnimationController.getStackPosition();
     }
 
+    /** @return the relative position of the bubble stack. */
     public RelativeStackPosition getRelativeStackPosition() {
         return mStackAnimationController.getRelativeStackPosition();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
index a3e6a1e..0b68306 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
-import static com.android.systemui.bubbles.BadgedImageView.DEFAULT_PATH_SIZE;
-import static com.android.systemui.bubbles.BadgedImageView.WHITE_SCRIM_ALPHA;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.wm.shell.bubbles.BadgedImageView.DEFAULT_PATH_SIZE;
+import static com.android.wm.shell.bubbles.BadgedImageView.WHITE_SCRIM_ALPHA;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.annotation.NonNull;
 import android.content.Context;
@@ -42,7 +42,7 @@
 
 import com.android.internal.graphics.ColorUtils;
 import com.android.launcher3.icons.BitmapInfo;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
 
 import java.lang.ref.WeakReference;
 import java.util.Objects;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java
index 5890172..ec900be 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import android.graphics.Bitmap;
 import android.graphics.Path;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/bubbles/Bubbles.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 415edb1..79c42d8 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static java.lang.annotation.ElementType.FIELD;
 import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/DismissView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
similarity index 81%
rename from packages/SystemUI/src/com/android/systemui/bubbles/DismissView.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
index b3c552d..04b5ad6 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/DismissView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
@@ -1,4 +1,20 @@
-package com.android.systemui.bubbles
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.bubbles
 
 import android.content.Context
 import android.graphics.drawable.TransitionDrawable
@@ -9,9 +25,9 @@
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY
 import androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW
-import com.android.systemui.R
-import com.android.wm.shell.common.DismissCircleView
+import com.android.wm.shell.R
 import com.android.wm.shell.animation.PhysicsAnimator
+import com.android.wm.shell.common.DismissCircleView
 
 /*
  * View that handles interactions between DismissCircleView and BubbleStackView.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/ManageEducationView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/bubbles/ManageEducationView.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
index 3db07c2..4cc6702 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/ManageEducationView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles
+package com.android.wm.shell.bubbles
 
 import android.content.Context
 import android.graphics.Color
@@ -24,8 +24,8 @@
 import android.widget.LinearLayout
 import android.widget.TextView
 import com.android.internal.util.ContrastColorUtil
-import com.android.systemui.Interpolators
-import com.android.systemui.R
+import com.android.wm.shell.R
+import com.android.wm.shell.animation.Interpolators
 
 /**
  * User education view to highlight the manage button that allows a user to configure the settings
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/ObjectWrapper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ObjectWrapper.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/bubbles/ObjectWrapper.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ObjectWrapper.java
index f054122..528907f 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/ObjectWrapper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ObjectWrapper.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import android.os.Binder;
 import android.os.IBinder;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/RelativeTouchListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/RelativeTouchListener.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
index b1291a5..b347329 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/RelativeTouchListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles
+package com.android.wm.shell.bubbles
 
 import android.graphics.PointF
 import android.os.Handler
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/StackEducationView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/bubbles/StackEducationView.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
index 216df2e..04c4dfb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/StackEducationView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles
+package com.android.wm.shell.bubbles
 
 import android.content.Context
 import android.graphics.Color
@@ -23,8 +23,8 @@
 import android.widget.LinearLayout
 import android.widget.TextView
 import com.android.internal.util.ContrastColorUtil
-import com.android.systemui.Interpolators
-import com.android.systemui.R
+import com.android.wm.shell.R
+import com.android.wm.shell.animation.Interpolators
 
 /**
  * User education view to highlight the collapsed stack of bubbles.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/AnimatableScaleMatrix.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/AnimatableScaleMatrix.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/animation/AnimatableScaleMatrix.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/AnimatableScaleMatrix.java
index 07acb71..2612b81 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/AnimatableScaleMatrix.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/AnimatableScaleMatrix.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import android.graphics.Matrix;
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
index 5a70401..61fbf81 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -28,10 +28,10 @@
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.bubbles.BubblePositioner;
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.BubblePositioner;
 import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
 
 import com.google.android.collect.Sets;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/OneTimeEndListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/OneTimeEndListener.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/bubbles/animation/OneTimeEndListener.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/OneTimeEndListener.java
index 4e0abc8..37355c4 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/OneTimeEndListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/OneTimeEndListener.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import androidx.dynamicanimation.animation.DynamicAnimation;
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
index 0a596d5..0618d5d 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -35,7 +35,7 @@
 import androidx.dynamicanimation.animation.SpringAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
-import com.android.systemui.R;
+import com.android.wm.shell.R;
 
 import java.util.ArrayList;
 import java.util.HashMap;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
index 43893f2..d7f2e4b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import android.content.ContentResolver;
 import android.content.res.Resources;
@@ -34,11 +34,11 @@
 import androidx.dynamicanimation.animation.SpringAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
-import com.android.systemui.R;
-import com.android.systemui.bubbles.BadgedImageView;
-import com.android.systemui.bubbles.BubblePositioner;
-import com.android.systemui.bubbles.BubbleStackView;
+import com.android.wm.shell.R;
 import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.BadgedImageView;
+import com.android.wm.shell.bubbles.BubblePositioner;
+import com.android.wm.shell.bubbles.BubbleStackView;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleEntity.kt
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleEntity.kt
index 24768cd..aeba302 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleEntity.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
+package com.android.wm.shell.bubbles.storage
 
 import android.annotation.DimenRes
 import android.annotation.UserIdInt
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubblePersistentRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepository.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubblePersistentRepository.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepository.kt
index ce0786d..66a75af 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubblePersistentRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepository.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
+package com.android.wm.shell.bubbles.storage
 
 import android.content.Context
 import android.util.AtomicFile
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepository.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepository.kt
index e0a7c78..7f0b165 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepository.kt
@@ -13,12 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
+package com.android.wm.shell.bubbles.storage
 
 import android.content.pm.LauncherApps
 import android.os.UserHandle
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.bubbles.ShortcutKey
+import com.android.wm.shell.bubbles.ShortcutKey
 
 private const val CAPACITY = 16
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt
index bf163a2..fe72bd3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt
@@ -13,14 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
+package com.android.wm.shell.bubbles.storage
 
-import com.android.internal.util.FastXmlSerializer
-import org.xmlpull.v1.XmlSerializer
-import java.io.IOException
 import android.util.Xml
+import com.android.internal.util.FastXmlSerializer
 import com.android.internal.util.XmlUtils
 import org.xmlpull.v1.XmlPullParser
+import org.xmlpull.v1.XmlSerializer
+import java.io.IOException
 import java.io.InputStream
 import java.io.OutputStream
 import java.nio.charset.StandardCharsets
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/AlphaOptimizedButton.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/AlphaOptimizedButton.java
new file mode 100644
index 0000000..6f0a61b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/AlphaOptimizedButton.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.common;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Button;
+
+/**
+ * A Button which doesn't have overlapping drawing commands
+ *
+ * This is the copy from SystemUI/statusbar.
+ */
+public class AlphaOptimizedButton extends Button {
+    public AlphaOptimizedButton(Context context) {
+        super(context);
+    }
+
+    public AlphaOptimizedButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public AlphaOptimizedButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public AlphaOptimizedButton(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TriangleShape.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TriangleShape.java
new file mode 100644
index 0000000..7079190
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TriangleShape.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.common;
+
+import android.graphics.Outline;
+import android.graphics.Path;
+import android.graphics.drawable.shapes.PathShape;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Wrapper around {@link PathShape}
+ * that creates a shape with a triangular path (pointing up or down).
+ *
+ * This is the copy from SystemUI/recents.
+ */
+public class TriangleShape extends PathShape {
+    private Path mTriangularPath;
+
+    public TriangleShape(Path path, float stdWidth, float stdHeight) {
+        super(path, stdWidth, stdHeight);
+        mTriangularPath = path;
+    }
+
+    public static TriangleShape create(float width, float height, boolean isPointingUp) {
+        Path triangularPath = new Path();
+        if (isPointingUp) {
+            triangularPath.moveTo(0, height);
+            triangularPath.lineTo(width, height);
+            triangularPath.lineTo(width / 2, 0);
+            triangularPath.close();
+        } else {
+            triangularPath.moveTo(0, 0);
+            triangularPath.lineTo(width / 2, height);
+            triangularPath.lineTo(width, 0);
+            triangularPath.close();
+        }
+        return new TriangleShape(triangularPath, width, height);
+    }
+
+    /** Create an arrow TriangleShape that points to the left or the right */
+    public static TriangleShape createHorizontal(
+            float width, float height, boolean isPointingLeft) {
+        Path triangularPath = new Path();
+        if (isPointingLeft) {
+            triangularPath.moveTo(0, height / 2);
+            triangularPath.lineTo(width, height);
+            triangularPath.lineTo(width, 0);
+            triangularPath.close();
+        } else {
+            triangularPath.moveTo(0, height);
+            triangularPath.lineTo(width, height / 2);
+            triangularPath.lineTo(0, 0);
+            triangularPath.close();
+        }
+        return new TriangleShape(triangularPath, width, height);
+    }
+
+    @Override
+    public void getOutline(@NonNull Outline outline) {
+        outline.setPath(mTriangularPath);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index bf5b1d8..c77f594 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -16,17 +16,9 @@
 
 package com.android.wm.shell.draganddrop;
 
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.content.ClipDescription.EXTRA_ACTIVITY_OPTIONS;
-import static android.content.ClipDescription.EXTRA_PENDING_INTENT;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
-import static android.content.Intent.EXTRA_PACKAGE_NAME;
-import static android.content.Intent.EXTRA_SHORTCUT_ID;
-import static android.content.Intent.EXTRA_TASK_ID;
-import static android.content.Intent.EXTRA_USER;
 import static android.view.DragEvent.ACTION_DRAG_ENDED;
 import static android.view.DragEvent.ACTION_DRAG_ENTERED;
 import static android.view.DragEvent.ACTION_DRAG_EXITED;
@@ -42,25 +34,10 @@
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
-import android.app.PendingIntent;
-import android.content.ActivityNotFoundException;
-import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.LauncherApps;
 import android.content.res.Configuration;
 import android.graphics.PixelFormat;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.view.DragEvent;
 import android.view.LayoutInflater;
@@ -76,6 +53,7 @@
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreen;
 
+import java.util.Objects;
 import java.util.Optional;
 
 /**
@@ -91,10 +69,12 @@
     private SplitScreen mSplitScreen;
 
     private final SparseArray<PerDisplay> mDisplayDropTargets = new SparseArray<>();
-    private boolean mIsHandlingDrag;
-    private DragLayout mDragLayout;
     private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
 
+    // A count of the number of active drags in progress to ensure that we only hide the window when
+    // all the drag animations have completed
+    private int mActiveDragCount;
+
     public DragAndDropController(Context context, DisplayController displayController) {
         mContext = context;
         mDisplayController = displayController;
@@ -124,26 +104,31 @@
         layoutParams.setFitInsetsTypes(0);
         layoutParams.setTitle("ShellDropTarget");
 
-        FrameLayout dropTarget = (FrameLayout) LayoutInflater.from(context).inflate(
+        FrameLayout rootView = (FrameLayout) LayoutInflater.from(context).inflate(
                 R.layout.global_drop_target, null);
-        dropTarget.setOnDragListener(this);
-        dropTarget.setVisibility(View.INVISIBLE);
-        wm.addView(dropTarget, layoutParams);
-        mDisplayDropTargets.put(displayId, new PerDisplay(displayId, context, wm, dropTarget));
+        rootView.setOnDragListener(this);
+        rootView.setVisibility(View.INVISIBLE);
+        DragLayout dragLayout = new DragLayout(context, mSplitScreen);
+        rootView.addView(dragLayout,
+                new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+        wm.addView(rootView, layoutParams);
+
+        mDisplayDropTargets.put(displayId,
+                new PerDisplay(displayId, context, wm, rootView, dragLayout));
     }
 
     @Override
     public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Display changed: %d", displayId);
         final PerDisplay pd = mDisplayDropTargets.get(displayId);
-        pd.dropTarget.requestApplyInsets();
+        pd.rootView.requestApplyInsets();
     }
 
     @Override
     public void onDisplayRemoved(int displayId) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Display removed: %d", displayId);
         final PerDisplay pd = mDisplayDropTargets.get(displayId);
-        pd.wm.removeViewImmediate(pd.dropTarget);
+        pd.wm.removeViewImmediate(pd.rootView);
         mDisplayDropTargets.remove(displayId);
     }
 
@@ -158,32 +143,33 @@
         final ClipDescription description = event.getClipDescription();
 
         if (event.getAction() == ACTION_DRAG_STARTED) {
-            final boolean hasValidClipData = description.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY)
-                    || description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT)
-                    || description.hasMimeType(MIMETYPE_APPLICATION_TASK);
-            mIsHandlingDrag = hasValidClipData;
+            final boolean hasValidClipData = event.getClipData().getItemCount() > 0
+                    && (description.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY)
+                            || description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT)
+                            || description.hasMimeType(MIMETYPE_APPLICATION_TASK));
+            pd.isHandlingDrag = hasValidClipData;
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
-                    "Clip description: handlingDrag=%b mimeTypes=%s",
-                    mIsHandlingDrag, getMimeTypes(description));
+                    "Clip description: handlingDrag=%b itemCount=%d mimeTypes=%s",
+                    pd.isHandlingDrag, event.getClipData().getItemCount(),
+                    getMimeTypes(description));
         }
 
-        if (!mIsHandlingDrag) {
+        if (!pd.isHandlingDrag) {
             return false;
         }
 
         switch (event.getAction()) {
             case ACTION_DRAG_STARTED:
-                mDragLayout = new DragLayout(pd.context,
-                        mDisplayController.getDisplayLayout(displayId), mSplitScreen);
-                pd.dropTarget.addView(mDragLayout,
-                        new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+                mActiveDragCount++;
+                pd.dragLayout.prepare(mDisplayController.getDisplayLayout(displayId),
+                        event.getClipData());
                 setDropTargetWindowVisibility(pd, View.VISIBLE);
                 break;
             case ACTION_DRAG_ENTERED:
-                mDragLayout.show(event);
+                pd.dragLayout.show();
                 break;
             case ACTION_DRAG_LOCATION:
-                mDragLayout.update(event);
+                pd.dragLayout.update(event);
                 break;
             case ACTION_DROP: {
                 return handleDrop(event, pd);
@@ -191,20 +177,22 @@
             case ACTION_DRAG_EXITED: {
                 // Either one of DROP or EXITED will happen, and when EXITED we won't consume
                 // the drag surface
-                mDragLayout.hide(event, null);
+                pd.dragLayout.hide(event, null);
                 break;
             }
             case ACTION_DRAG_ENDED:
                 // TODO(b/169894807): Ensure sure it's not possible to get ENDED without DROP
                 // or EXITED
-                if (!mDragLayout.hasDropped()) {
-                    final View dragLayout = mDragLayout;
-                    mDragLayout.hide(event, () -> {
-                        setDropTargetWindowVisibility(pd, View.INVISIBLE);
-                        pd.dropTarget.removeView(dragLayout);
+                if (!pd.dragLayout.hasDropped()) {
+                    mActiveDragCount--;
+                    pd.dragLayout.hide(event, () -> {
+                        if (mActiveDragCount == 0) {
+                            // Hide the window if another drag hasn't been started while animating
+                            // the drag-end
+                            setDropTargetWindowVisibility(pd, View.INVISIBLE);
+                        }
                     });
                 }
-                mDragLayout = null;
                 break;
         }
         return true;
@@ -214,52 +202,14 @@
      * Handles dropping on the drop target.
      */
     private boolean handleDrop(DragEvent event, PerDisplay pd) {
-        final ClipData data = event.getClipData();
-        final ClipDescription description = event.getClipDescription();
         final SurfaceControl dragSurface = event.getDragSurface();
-        final View dragLayout = mDragLayout;
-        final boolean isTask = description.hasMimeType(MIMETYPE_APPLICATION_TASK);
-        final boolean isShortcut = description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT);
-        return mDragLayout.drop(event, dragSurface, (dropTargetBounds) -> {
-            if (dropTargetBounds != null && data.getItemCount() > 0) {
-                final Intent intent = data.getItemAt(0).getIntent();
-                // TODO(b/169894807): Properly handle the drop, for now just launch it
-                if (isTask) {
-                    int taskId = intent.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID);
-                    try {
-                        ActivityTaskManager.getService().startActivityFromRecents(
-                                taskId, null);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Failed to launch task", e);
-                    }
-                } else if (isShortcut) {
-                    try {
-                        Bundle opts = intent.hasExtra(EXTRA_ACTIVITY_OPTIONS)
-                                ? intent.getBundleExtra(EXTRA_ACTIVITY_OPTIONS)
-                                : null;
-                        LauncherApps launcherApps =
-                                mContext.getSystemService(LauncherApps.class);
-                        launcherApps.startShortcut(
-                                intent.getStringExtra(EXTRA_PACKAGE_NAME),
-                                intent.getStringExtra(EXTRA_SHORTCUT_ID),
-                                null /* sourceBounds */, opts,
-                                intent.getParcelableExtra(EXTRA_USER));
-                    } catch (ActivityNotFoundException e) {
-                        Slog.e(TAG, "Failed to launch shortcut", e);
-                    }
-                } else {
-                    PendingIntent pi = intent.getParcelableExtra(EXTRA_PENDING_INTENT);
-                    try {
-                        pi.send();
-                    } catch (PendingIntent.CanceledException e) {
-                        Slog.e(TAG, "Failed to launch activity", e);
-                    }
-                }
+        mActiveDragCount--;
+        return pd.dragLayout.drop(event, dragSurface, () -> {
+            if (mActiveDragCount == 0) {
+                // Hide the window if another drag hasn't been started while animating the drop
+                setDropTargetWindowVisibility(pd, View.INVISIBLE);
             }
 
-            setDropTargetWindowVisibility(pd, View.INVISIBLE);
-            pd.dropTarget.removeView(dragLayout);
-
             // Clean up the drag surface
             mTransaction.reparent(dragSurface, null);
             mTransaction.apply();
@@ -270,9 +220,9 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                 "Set drop target window visibility: displayId=%d visibility=%d",
                 pd.displayId, visibility);
-        pd.dropTarget.setVisibility(visibility);
+        pd.rootView.setVisibility(visibility);
         if (visibility == View.VISIBLE) {
-            pd.dropTarget.requestApplyInsets();
+            pd.rootView.requestApplyInsets();
         }
     }
 
@@ -291,13 +241,17 @@
         final int displayId;
         final Context context;
         final WindowManager wm;
-        final FrameLayout dropTarget;
+        final FrameLayout rootView;
+        final DragLayout dragLayout;
 
-        PerDisplay(int dispId, Context c, WindowManager w, FrameLayout l) {
+        boolean isHandlingDrag;
+
+        PerDisplay(int dispId, Context c, WindowManager w, FrameLayout rv, DragLayout dl) {
             displayId = dispId;
             context = c;
             wm = w;
-            dropTarget = l;
+            rootView = rv;
+            dragLayout = dl;
         }
     }
 }
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
new file mode 100644
index 0000000..25890bc
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -0,0 +1,409 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.draganddrop;
+
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.ClipDescription.EXTRA_ACTIVITY_OPTIONS;
+import static android.content.ClipDescription.EXTRA_PENDING_INTENT;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
+import static android.content.Intent.EXTRA_SHORTCUT_ID;
+import static android.content.Intent.EXTRA_TASK_ID;
+import static android.content.Intent.EXTRA_USER;
+
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_FULLSCREEN;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP;
+
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.IActivityTaskManager;
+import android.app.PendingIntent;
+import android.app.WindowConfiguration;
+import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.LauncherApps;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.splitscreen.SplitScreen;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The policy for handling drag and drop operations to shell.
+ */
+public class DragAndDropPolicy {
+
+    private static final String TAG = DragAndDropPolicy.class.getSimpleName();
+
+    private final Context mContext;
+    private final IActivityTaskManager mIActivityTaskManager;
+    private final Starter mStarter;
+    private final SplitScreen mSplitScreen;
+    private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>();
+
+    private DragSession mSession;
+
+    public DragAndDropPolicy(Context context, SplitScreen splitScreen) {
+        this(context, ActivityTaskManager.getService(), splitScreen,
+                new DefaultStarter(context, splitScreen));
+    }
+
+    @VisibleForTesting
+    DragAndDropPolicy(Context context, IActivityTaskManager activityTaskManager,
+            SplitScreen splitScreen, Starter starter) {
+        mContext = context;
+        mIActivityTaskManager = activityTaskManager;
+        mSplitScreen = splitScreen;
+        mStarter = starter;
+    }
+
+    /**
+     * Starts a new drag session with the given initial drag data.
+     */
+    void start(DisplayLayout displayLayout, ClipData data) {
+        mSession = new DragSession(mContext, mIActivityTaskManager, displayLayout, data);
+        // TODO(b/169894807): Also update the session data with task stack changes
+        mSession.update();
+    }
+
+    /**
+     * Returns the target's regions based on the current state of the device and display.
+     */
+    @NonNull
+    ArrayList<Target> getTargets(Insets insets) {
+        mTargets.clear();
+        if (mSession == null) {
+            // Return early if this isn't an app drag
+            return mTargets;
+        }
+
+        final int w = mSession.displayLayout.width();
+        final int h = mSession.displayLayout.height();
+        final int iw = w - insets.left - insets.right;
+        final int ih = h - insets.top - insets.bottom;
+        final int l = insets.left;
+        final int t = insets.top;
+        final boolean isVerticalSplit = mSession.isPhone && !mSession.displayLayout.isLandscape();
+        if (mSession.dragItemSupportsSplitscreen
+                && mSession.runningTaskActType == ACTIVITY_TYPE_STANDARD
+                && mSession.runningTaskWinMode == WINDOWING_MODE_FULLSCREEN
+                && mSession.runningTaskIsResizeable) {
+            // Allow splitting when there is a fullscreen standard activity running
+            if (isVerticalSplit) {
+                // TODO(b/169894807): For now, only allow splitting to the right/bottom until we
+                //                    have split pairs
+                mTargets.add(new Target(TYPE_FULLSCREEN,
+                        new Rect(0, 0, w, h / 2),
+                        new Rect(l, t, l + iw, t + ih),
+                        new Rect(0, 0, w, h)));
+                mTargets.add(new Target(TYPE_SPLIT_BOTTOM,
+                        new Rect(0, h / 2, w, h),
+                        new Rect(l, t + ih / 2, l + iw, t + ih),
+                        new Rect(0, h / 2, w, h)));
+            } else {
+                mTargets.add(new Target(TYPE_FULLSCREEN,
+                        new Rect(0, 0, w / 2, h),
+                        new Rect(l, t, l + iw, t + ih),
+                        new Rect(0, 0, w, h)));
+                mTargets.add(new Target(TYPE_SPLIT_RIGHT,
+                        new Rect(w / 2, 0, w, h),
+                        new Rect(l + iw / 2, t, l + iw, t + ih),
+                        new Rect(w / 2, 0, w, h)));
+            }
+        } else if (mSession.dragItemSupportsSplitscreen
+                && mSplitScreen != null
+                && mSplitScreen.isDividerVisible()) {
+            // Already split, allow replacing existing split task
+            // TODO(b/169894807): For now, only allow replacing the non-primary task until we have
+            //                    split pairs
+            final Rect secondarySplitRawBounds =
+                    mSplitScreen.getDividerView().getNonMinimizedSplitScreenSecondaryBounds();
+            final Rect secondarySplitBounds = new Rect(secondarySplitRawBounds);
+            secondarySplitBounds.intersect(new Rect(l, t, l + iw, t + ih));
+            if (isVerticalSplit) {
+                mTargets.add(new Target(TYPE_FULLSCREEN,
+                        new Rect(0, 0, w, secondarySplitRawBounds.top),
+                        new Rect(l, t, l + iw, t + ih),
+                        new Rect(0, 0, w, secondarySplitRawBounds.top)));
+            } else {
+                mTargets.add(new Target(TYPE_FULLSCREEN,
+                        new Rect(0, 0, secondarySplitRawBounds.left, h),
+                        new Rect(l, t, l + iw, t + ih),
+                        new Rect(0, 0, w, h)));
+            }
+            mTargets.add(new Target(isVerticalSplit ? TYPE_SPLIT_BOTTOM : TYPE_SPLIT_RIGHT,
+                    new Rect(secondarySplitBounds),
+                    new Rect(secondarySplitBounds),
+                    new Rect(secondarySplitBounds)));
+        } else {
+            // Otherwise only show the fullscreen target
+            mTargets.add(new Target(TYPE_FULLSCREEN,
+                    new Rect(0, 0, w, h),
+                    new Rect(l, t, l + iw, t + ih),
+                    new Rect(0, 0, w, h)));
+        }
+        return mTargets;
+    }
+
+    /**
+     * Returns the target at the given position based on the targets previously calculated.
+     */
+    @Nullable
+    Target getTargetAtLocation(int x, int y) {
+        for (int i = mTargets.size() - 1; i >= 0; i--) {
+            DragAndDropPolicy.Target t = mTargets.get(i);
+            if (t.hitRegion.contains(x, y)) {
+                return t;
+            }
+        }
+        return null;
+    }
+
+    @VisibleForTesting
+    void handleDrop(Target target, ClipData data) {
+        if (target == null || !mTargets.contains(target)) {
+            return;
+        }
+
+        final ClipDescription description = data.getDescription();
+        final boolean isTask = description.hasMimeType(MIMETYPE_APPLICATION_TASK);
+        final boolean isShortcut = description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT);
+        final Intent dragData = mSession.dragData;
+
+        if (target.type == TYPE_FULLSCREEN) {
+            if (mSplitScreen != null && mSplitScreen.isDividerVisible()) {
+                // If in split, remove split and launch fullscreen
+                mStarter.exitSplitScreen(mSession.runningTaskId);
+            } else {
+                // Not in split, fall through to launch
+            }
+        } else {
+            if (mSplitScreen != null && mSplitScreen.isDividerVisible()) {
+                // Split is already visible, just replace the task
+                // TODO(b/169894807): Since we only allow replacing the non-primary target above
+                //                    just fall through and start the activity
+            } else {
+                // Not in split, enter split now
+                mStarter.enterSplitScreen(mSession.runningTaskId,
+                        target.type == TYPE_SPLIT_LEFT || target.type == TYPE_SPLIT_TOP);
+            }
+        }
+
+        Bundle opts = dragData.hasExtra(EXTRA_ACTIVITY_OPTIONS)
+                ? dragData.getBundleExtra(EXTRA_ACTIVITY_OPTIONS)
+                : null;
+        if (isTask) {
+            mStarter.startTask(dragData.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID), opts);
+        } else if (isShortcut) {
+            mStarter.startShortcut(dragData.getStringExtra(EXTRA_PACKAGE_NAME),
+                    dragData.getStringExtra(EXTRA_SHORTCUT_ID),
+                    opts, dragData.getParcelableExtra(EXTRA_USER));
+        } else {
+            mStarter.startIntent(dragData.getParcelableExtra(EXTRA_PENDING_INTENT), opts);
+        }
+    }
+
+    /**
+     * Per-drag session data.
+     */
+    private static class DragSession {
+        private final Context mContext;
+        private final IActivityTaskManager mIActivityTaskManager;
+        private final ClipData mInitialDragData;
+
+        final DisplayLayout displayLayout;
+        Intent dragData;
+        int runningTaskId;
+        @WindowConfiguration.WindowingMode
+        int runningTaskWinMode = WINDOWING_MODE_UNDEFINED;
+        @WindowConfiguration.ActivityType
+        int runningTaskActType = ACTIVITY_TYPE_STANDARD;
+        boolean runningTaskIsResizeable;
+        boolean dragItemSupportsSplitscreen;
+        boolean isPhone;
+
+        DragSession(Context context, IActivityTaskManager activityTaskManager,
+                DisplayLayout dispLayout, ClipData data) {
+            mContext = context;
+            mIActivityTaskManager = activityTaskManager;
+            mInitialDragData = data;
+            displayLayout = dispLayout;
+        }
+
+        /**
+         * Updates the session data based on the current state of the system.
+         */
+        void update() {
+            final ClipDescription description = mInitialDragData.getDescription();
+            try {
+                List<ActivityManager.RunningTaskInfo> tasks =
+                        mIActivityTaskManager.getFilteredTasks(1,
+                                false /* filterOnlyVisibleRecents */);
+                if (!tasks.isEmpty()) {
+                    final ActivityManager.RunningTaskInfo task = tasks.get(0);
+                    runningTaskWinMode = task.getWindowingMode();
+                    runningTaskActType = task.getActivityType();
+                    runningTaskId = task.taskId;
+                    runningTaskIsResizeable = task.isResizeable;
+                }
+            } catch (RemoteException e) {
+                // Fall through
+            }
+
+            final ActivityInfo info = mInitialDragData.getItemAt(0).getActivityInfo();
+            dragItemSupportsSplitscreen = info == null
+                    || ActivityInfo.isResizeableMode(info.resizeMode);
+            isPhone = mContext.getResources().getConfiguration().smallestScreenWidthDp < 600;
+            dragData = mInitialDragData.getItemAt(0).getIntent();
+        }
+    }
+
+    /**
+     * Interface for actually committing the task launches.
+     */
+    @VisibleForTesting
+    interface Starter {
+        void startTask(int taskId, Bundle activityOptions);
+        void startShortcut(String packageName, String shortcutId, Bundle activityOptions,
+                UserHandle user);
+        void startIntent(PendingIntent intent, Bundle activityOptions);
+        void enterSplitScreen(int taskId, boolean leftOrTop);
+        void exitSplitScreen(int taskId);
+    }
+
+    /**
+     * Default implementation of the starter which calls through the system services to launch the
+     * tasks.
+     */
+    private static class DefaultStarter implements Starter {
+        private final Context mContext;
+        private final SplitScreen mSplitScreen;
+
+        public DefaultStarter(Context context, SplitScreen splitScreen) {
+            mContext = context;
+            mSplitScreen = splitScreen;
+        }
+
+        @Override
+        public void startTask(int taskId, Bundle activityOptions) {
+            try {
+                ActivityTaskManager.getService().startActivityFromRecents(taskId, null);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to launch task", e);
+            }
+        }
+
+        @Override
+        public void startShortcut(String packageName, String shortcutId, Bundle activityOptions,
+                UserHandle user) {
+            try {
+                LauncherApps launcherApps =
+                        mContext.getSystemService(LauncherApps.class);
+                launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */,
+                        activityOptions, user);
+            } catch (ActivityNotFoundException e) {
+                Slog.e(TAG, "Failed to launch shortcut", e);
+            }
+        }
+
+        @Override
+        public void startIntent(PendingIntent intent, Bundle activityOptions) {
+            try {
+                intent.send(null, 0, null, null, null, null, activityOptions);
+            } catch (PendingIntent.CanceledException e) {
+                Slog.e(TAG, "Failed to launch activity", e);
+            }
+        }
+
+        @Override
+        public void enterSplitScreen(int taskId, boolean leftOrTop) {
+            mSplitScreen.splitPrimaryTask();
+        }
+
+        @Override
+        public void exitSplitScreen(int taskId) {
+            mSplitScreen.dismissSplitToPrimaryTask();
+        }
+    }
+
+    /**
+     * Represents a drop target.
+     */
+    static class Target {
+        static final int TYPE_FULLSCREEN = 0;
+        static final int TYPE_SPLIT_LEFT = 1;
+        static final int TYPE_SPLIT_TOP = 2;
+        static final int TYPE_SPLIT_RIGHT = 3;
+        static final int TYPE_SPLIT_BOTTOM = 4;
+        @IntDef(value = {
+                TYPE_FULLSCREEN,
+                TYPE_SPLIT_LEFT,
+                TYPE_SPLIT_TOP,
+                TYPE_SPLIT_RIGHT,
+                TYPE_SPLIT_BOTTOM
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        @interface Type{}
+
+        final @Type int type;
+
+        // The actual hit region for this region
+        final Rect hitRegion;
+        // The approximate visual region for where the task will start
+        final Rect drawRegion;
+        // The
+        final Rect dropTargetBounds;
+
+        public Target(@Type int t, Rect hit, Rect draw, Rect drop) {
+            type = t;
+            hitRegion = hit;
+            drawRegion = draw;
+            dropTargetBounds = drop;
+        }
+
+        @Override
+        public String toString() {
+            return "Target {hit=" + hitRegion + " drop=" + dropTargetBounds + "}";
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index b70036b..fa857cdd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -24,6 +24,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
+import android.content.ClipData;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Insets;
@@ -52,20 +53,19 @@
  */
 public class DragLayout extends View {
 
-    private final DisplayLayout mDisplayLayout;
-    private final SplitScreen mSplitScreen;
+    private final DragAndDropPolicy mPolicy;
 
-    private final ArrayList<Target> mTargets = new ArrayList<>();
-    private Target mCurrentTarget = null;
+    private DragAndDropPolicy.Target mCurrentTarget = null;
     private DropOutlineDrawable mDropOutline;
     private int mDisplayMargin;
     private Insets mInsets = Insets.NONE;
+
+    private boolean mIsShowing;
     private boolean mHasDropped;
 
-    public DragLayout(Context context, DisplayLayout displayLayout, SplitScreen splitscreen) {
+    public DragLayout(Context context, SplitScreen splitscreen) {
         super(context);
-        mDisplayLayout = displayLayout;
-        mSplitScreen = splitscreen;
+        mPolicy = new DragAndDropPolicy(context, splitscreen);
         mDisplayMargin = context.getResources().getDimensionPixelSize(
                 R.dimen.drop_layout_display_margin);
         mDropOutline = new DropOutlineDrawable(context);
@@ -76,7 +76,7 @@
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         mInsets = insets.getInsets(Type.systemBars() | Type.displayCutout());
-        calculateDropTargets();
+        recomputeDropTargets();
         return super.onApplyWindowInsets(insets);
     }
 
@@ -100,66 +100,41 @@
         return mHasDropped;
     }
 
-    public void show(DragEvent event) {
-        calculateDropTargets();
+    public void prepare(DisplayLayout displayLayout, ClipData initialData) {
+        mPolicy.start(displayLayout, initialData);
         mHasDropped = false;
+        mCurrentTarget = null;
     }
 
-    private void calculateDropTargets() {
-        // Calculate all the regions based on split and landscape portrait
-        // TODO: Filter based on clip data
-        final float SIDE_MARGIN_PCT = 0.3f;
-        final int w = mDisplayLayout.width();
-        final int h = mDisplayLayout.height();
-        final int iw = w - mInsets.left - mInsets.right;
-        final int ih = h - mInsets.top - mInsets.bottom;
-        final int l = mInsets.left;
-        final int t = mInsets.top;
-        final int r = mInsets.right;
-        final int b = mInsets.bottom;
-        mTargets.clear();
-
-        // Left split
-        addTarget(new Target(
-                new Rect(0, 0,
-                        (int) (w * SIDE_MARGIN_PCT), h),
-                new Rect(l + mDisplayMargin, t + mDisplayMargin,
-                        l + iw / 2 - mDisplayMargin, t + ih - mDisplayMargin),
-                new Rect(0, 0, w / 2, h)));
-
-        // Fullscreen
-        addTarget(new Target(
-                new Rect((int) (w * SIDE_MARGIN_PCT), 0,
-                        w - (int) (w * SIDE_MARGIN_PCT), h),
-                new Rect(l + mDisplayMargin, t + mDisplayMargin,
-                        l + iw - mDisplayMargin, t + ih - mDisplayMargin),
-                new Rect(0, 0, w, h)));
-
-        // Right split
-        addTarget(new Target(
-                new Rect(w - (int) (w * SIDE_MARGIN_PCT), 0,
-                        w, h),
-                new Rect(l + iw / 2 + mDisplayMargin, t + mDisplayMargin,
-                        l + iw - mDisplayMargin, t + ih - mDisplayMargin),
-                new Rect(w / 2, 0, w, h)));
+    public void show() {
+        mIsShowing = true;
+        recomputeDropTargets();
     }
 
-    private void addTarget(Target t) {
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Add target: %s", t);
-        mTargets.add(t);
+    /**
+     * Recalculates the drop targets based on the current policy.
+     */
+    private void recomputeDropTargets() {
+        if (!mIsShowing) {
+            return;
+        }
+        final ArrayList<DragAndDropPolicy.Target> targets = mPolicy.getTargets(mInsets);
+        for (int i = 0; i < targets.size(); i++) {
+            final DragAndDropPolicy.Target target = targets.get(i);
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Add target: %s", target);
+            // Inset the draw region by a little bit
+            target.drawRegion.inset(mDisplayMargin, mDisplayMargin);
+        }
     }
 
+    /**
+     * Updates the visible drop target as the user drags.
+     */
     public void update(DragEvent event) {
         // Find containing region, if the same as mCurrentRegion, then skip, otherwise, animate the
         // visibility of the current region
-        Target target = null;
-        for (int i = mTargets.size() - 1; i >= 0; i--) {
-            Target t = mTargets.get(i);
-            if (t.hitRegion.contains((int) event.getX(), (int) event.getY())) {
-                target = t;
-                break;
-            }
-        }
+        DragAndDropPolicy.Target target = mPolicy.getTargetAtLocation(
+                (int) event.getX(), (int) event.getY());
         if (target != null && mCurrentTarget != target) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Current target: %s", target);
             Interpolator boundsInterpolator = FAST_OUT_SLOW_IN;
@@ -175,7 +150,11 @@
         }
     }
 
+    /**
+     * Hides the drag layout and animates out the visible drop targets.
+     */
     public void hide(DragEvent event, Runnable hideCompleteCallback) {
+        mIsShowing = false;
         ObjectAnimator alphaAnimator = mDropOutline.startVisibilityAnimation(false, LINEAR);
         ObjectAnimator boundsAnimator = null;
         if (mCurrentTarget != null) {
@@ -199,50 +178,19 @@
         mCurrentTarget = null;
     }
 
+    /**
+     * Handles the drop onto a target and animates out the visible drop targets.
+     */
     public boolean drop(DragEvent event, SurfaceControl dragSurface,
-            Consumer<Rect> dropCompleteCallback) {
+            Runnable dropCompleteCallback) {
+        final boolean handledDrop = mCurrentTarget != null;
         mHasDropped = true;
+
+        // Process the drop
+        mPolicy.handleDrop(mCurrentTarget, event.getClipData());
+
         // TODO(b/169894807): Coordinate with dragSurface
-        final Rect dropRegion = mCurrentTarget != null
-                ? mCurrentTarget.dropTargetBounds
-                : null;
-
-        ObjectAnimator alphaAnimator = mDropOutline.startVisibilityAnimation(false, LINEAR);
-        ObjectAnimator boundsAnimator = null;
-        if (dropRegion != null) {
-            Rect finalBounds = new Rect(mCurrentTarget.drawRegion);
-            finalBounds.inset(mDisplayMargin, mDisplayMargin);
-            mDropOutline.startBoundsAnimation(finalBounds, FAST_OUT_LINEAR_IN);
-        }
-
-        if (dropCompleteCallback != null) {
-            ObjectAnimator lastAnim = boundsAnimator != null
-                    ? boundsAnimator
-                    : alphaAnimator;
-            lastAnim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    dropCompleteCallback.accept(dropRegion);
-                }
-            });
-        }
-        return dropRegion != null;
-    }
-
-    private static class Target {
-        final Rect hitRegion;
-        final Rect drawRegion;
-        final Rect dropTargetBounds;
-
-        public Target(Rect hit, Rect draw, Rect drop) {
-            hitRegion = hit;
-            drawRegion = draw;
-            dropTargetBounds = drop;
-        }
-
-        @Override
-        public String toString() {
-            return "Target {hit=" + hitRegion + " drop=" + dropTargetBounds + "}";
-        }
+        hide(event, dropCompleteCallback);
+        return handledDrop;
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropOutlineDrawable.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropOutlineDrawable.java
index 08edc2f..64f7be5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropOutlineDrawable.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropOutlineDrawable.java
@@ -40,7 +40,7 @@
 import com.android.wm.shell.R;
 
 /**
- * Drawable to draw the region of the
+ * Drawable to draw the region that the target will have once it is dropped.
  */
 public class DropOutlineDrawable extends Drawable {
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
index 4a9e28e..7c69c0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
@@ -256,7 +256,8 @@
 
         // Calculate the snap fraction of the current stack along the old movement bounds
         final Rect postChangeStackBounds = new Rect(oldBounds);
-        final float snapFraction = getSnapFraction(postChangeStackBounds);
+        final float snapFraction = mSnapAlgorithm.getSnapFraction(postChangeStackBounds,
+                getMovementBounds(postChangeStackBounds), mPipBoundsState.getStashedState());
 
         // Update the display layout
         mPipBoundsState.getDisplayLayout().rotateTo(context.getResources(), toRotation);
@@ -273,7 +274,8 @@
         final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
                 false /* adjustForIme */);
         mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
-                snapFraction);
+                snapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(),
+                mPipBoundsState.getDisplayBounds());
 
         getInsetBounds(outInsetBounds);
         outBounds.set(postChangeStackBounds);
@@ -321,7 +323,7 @@
             boolean useCurrentMinEdgeSize, boolean useCurrentSize) {
         // Save the snap fraction and adjust the size based on the new aspect ratio.
         final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
-                getMovementBounds(stackBounds));
+                getMovementBounds(stackBounds), mPipBoundsState.getStashedState());
         final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
         final Size size;
         if (useCurrentMinEdgeSize || useCurrentSize) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index fc523aef..57867d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -16,32 +16,69 @@
 
 package com.android.wm.shell.pip;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
+import android.content.Context;
 import android.graphics.Rect;
 import android.util.Size;
 import android.view.DisplayInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
  * Singleton source of truth for the current state of PIP bounds.
  */
 public final class PipBoundsState {
+    public static final int STASH_TYPE_NONE = 0;
+    public static final int STASH_TYPE_LEFT = 1;
+    public static final int STASH_TYPE_RIGHT = 2;
+
+    @IntDef(prefix = { "STASH_TYPE_" }, value =  {
+            STASH_TYPE_NONE,
+            STASH_TYPE_LEFT,
+            STASH_TYPE_RIGHT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface StashType {}
+
     private static final String TAG = PipBoundsState.class.getSimpleName();
 
     private final @NonNull Rect mBounds = new Rect();
+    private final Context mContext;
     private float mAspectRatio;
-    private boolean mIsStashed;
+    private int mStashedState = STASH_TYPE_NONE;
+    private int mStashOffset;
     private PipReentryState mPipReentryState;
     private ComponentName mLastPipComponentName;
     private final DisplayInfo mDisplayInfo = new DisplayInfo();
     private final DisplayLayout mDisplayLayout = new DisplayLayout();
+    private final @NonNull AnimatingBoundsState mAnimatingBoundsState = new AnimatingBoundsState();
+
+    public PipBoundsState(Context context) {
+        mContext = context;
+        reloadResources();
+    }
+
+    /**
+     * Reloads the resources.
+     */
+    public void onConfigurationChanged() {
+        reloadResources();
+    }
+
+    private void reloadResources() {
+        mStashOffset = mContext.getResources()
+                .getDimensionPixelSize(R.dimen.pip_stash_offset);
+    }
 
     /**
      * Set the current PIP bounds.
@@ -56,17 +93,32 @@
     }
 
     /**
-     * Dictate where PiP currently should be stashed or not.
+     * Dictate where PiP currently should be stashed, if at all.
      */
-    public void setStashed(boolean isStashed) {
-        mIsStashed = isStashed;
+    public void setStashed(@StashType int stashedState) {
+        mStashedState = stashedState;
+    }
+
+    /**
+     * Return where the PiP is stashed, if at all.
+     * @return {@code STASH_NONE}, {@code STASH_LEFT} or {@code STASH_RIGHT}.
+     */
+    public @StashType int getStashedState() {
+        return mStashedState;
     }
 
     /**
      * Whether PiP is stashed or not.
      */
     public boolean isStashed() {
-        return mIsStashed;
+        return mStashedState != STASH_TYPE_NONE;
+    }
+
+    /**
+     * Returns the offset from the edge of the screen for PiP stash.
+     */
+    public int getStashOffset() {
+        return mStashOffset;
     }
 
     public void setAspectRatio(float aspectRatio) {
@@ -151,6 +203,60 @@
         mPipReentryState = null;
     }
 
+    public AnimatingBoundsState getAnimatingBoundsState() {
+        return mAnimatingBoundsState;
+    }
+
+    /** Source of truth for the current animation bounds of PIP. */
+    public static class AnimatingBoundsState {
+        /** The bounds used when PIP is being dragged or animated. */
+        private final Rect mTemporaryBounds = new Rect();
+        /** The destination bounds to which PIP is animating. */
+        private final Rect mAnimatingToBounds = new Rect();
+
+        /** Whether PIP is being dragged or animated (e.g. resizing, in fling, etc). */
+        public boolean isAnimating() {
+            return !mTemporaryBounds.isEmpty();
+        }
+
+        /** Set the temporary bounds used to represent the drag or animation bounds of PIP. */
+        public void setTemporaryBounds(Rect bounds) {
+            mTemporaryBounds.set(bounds);
+        }
+
+        /** Set the bounds to which PIP is animating. */
+        public void setAnimatingToBounds(Rect bounds) {
+            mAnimatingToBounds.set(bounds);
+        }
+
+        /** Called when all ongoing dragging and animation operations have ended. */
+        public void onAllAnimationsEnded() {
+            mTemporaryBounds.setEmpty();
+        }
+
+        /** Called when an ongoing physics animation has ended. */
+        public void onPhysicsAnimationEnded() {
+            mAnimatingToBounds.setEmpty();
+        }
+
+        /** Returns the temporary animation bounds. */
+        public Rect getTemporaryBounds() {
+            return mTemporaryBounds;
+        }
+
+        /** Returns the destination bounds to which PIP is currently animating. */
+        public Rect getAnimatingToBounds() {
+            return mAnimatingToBounds;
+        }
+
+        void dump(PrintWriter pw, String prefix) {
+            final String innerPrefix = prefix + "  ";
+            pw.println(prefix + AnimatingBoundsState.class.getSimpleName());
+            pw.println(innerPrefix + "mTemporaryBounds=" + mTemporaryBounds);
+            pw.println(innerPrefix + "mAnimatingToBounds=" + mAnimatingToBounds);
+        }
+    }
+
     static final class PipReentryState {
         private static final String TAG = PipReentryState.class.getSimpleName();
 
@@ -190,10 +296,13 @@
         pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio);
         pw.println(innerPrefix + "mDisplayInfo=" + mDisplayInfo);
         pw.println(innerPrefix + "mDisplayLayout=" + mDisplayLayout);
+        pw.println(innerPrefix + "mStashedState=" + mStashedState);
+        pw.println(innerPrefix + "mStashOffset=" + mStashOffset);
         if (mPipReentryState == null) {
             pw.println(innerPrefix + "mPipReentryState=null");
         } else {
             mPipReentryState.dump(pw, innerPrefix);
         }
+        mAnimatingBoundsState.dump(pw, innerPrefix);
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java
index 820930c..7106075 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java
@@ -16,6 +16,10 @@
 
 package com.android.wm.shell.pip;
 
+import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_LEFT;
+import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE;
+import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT;
+
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.PointF;
@@ -42,9 +46,20 @@
     }
 
     /**
+     * Returns a fraction that describes where the PiP bounds is.
+     * See {@link #getSnapFraction(Rect, Rect, int)}.
+     */
+    public float getSnapFraction(Rect stackBounds, Rect movementBounds) {
+        return getSnapFraction(stackBounds, movementBounds, STASH_TYPE_NONE);
+    }
+
+    /**
      * @return returns a fraction that describes where along the {@param movementBounds} the
      *         {@param stackBounds} are. If the {@param stackBounds} are not currently on the
      *         {@param movementBounds} exactly, then they will be snapped to the movement bounds.
+     *         stashType dictates whether the PiP is stashed (off-screen) or not. If
+     *         that's the case, we will have to do some math to calculate the snap fraction
+     *         correctly.
      *
      *         The fraction is defined in a clockwise fashion against the {@param movementBounds}:
      *
@@ -54,9 +69,10 @@
      *          3 +---+ 2
      *            3   2
      */
-    public float getSnapFraction(Rect stackBounds, Rect movementBounds) {
+    public float getSnapFraction(Rect stackBounds, Rect movementBounds,
+            @PipBoundsState.StashType int stashType) {
         final Rect tmpBounds = new Rect();
-        snapRectToClosestEdge(stackBounds, movementBounds, tmpBounds);
+        snapRectToClosestEdge(stackBounds, movementBounds, tmpBounds, stashType);
         final float widthFraction = (float) (tmpBounds.left - movementBounds.left) /
                 movementBounds.width();
         final float heightFraction = (float) (tmpBounds.top - movementBounds.top) /
@@ -104,6 +120,22 @@
     }
 
     /**
+     * Same as {@link #applySnapFraction(Rect, Rect, float)}, but take stash state into
+     * consideration.
+     */
+    public void applySnapFraction(Rect stackBounds, Rect movementBounds, float snapFraction,
+            @PipBoundsState.StashType int stashType, int stashOffset, Rect displayBounds) {
+        applySnapFraction(stackBounds, movementBounds, snapFraction);
+
+        if (stashType != STASH_TYPE_NONE) {
+            stackBounds.offsetTo(stashType == STASH_TYPE_LEFT
+                            ? stashOffset - stackBounds.width()
+                            : displayBounds.right - stashOffset,
+                    stackBounds.top);
+        }
+    }
+
+    /**
      * Adjusts {@param movementBoundsOut} so that it is the movement bounds for the given
      * {@param stackBounds}.
      */
@@ -178,17 +210,24 @@
      * Snaps the {@param stackBounds} to the closest edge of the {@param movementBounds} and writes
      * the new bounds out to {@param boundsOut}.
      */
-    public void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut) {
+    public void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut,
+            @PipBoundsState.StashType int stashType) {
+        int leftEdge = stackBounds.left;
+        if (stashType == STASH_TYPE_LEFT) {
+            leftEdge = movementBounds.left;
+        } else if (stashType == STASH_TYPE_RIGHT) {
+            leftEdge = movementBounds.right;
+        }
         final int boundedLeft = Math.max(movementBounds.left, Math.min(movementBounds.right,
-                stackBounds.left));
+                leftEdge));
         final int boundedTop = Math.max(movementBounds.top, Math.min(movementBounds.bottom,
                 stackBounds.top));
         boundsOut.set(stackBounds);
 
         // Otherwise, just find the closest edge
-        final int fromLeft = Math.abs(stackBounds.left - movementBounds.left);
+        final int fromLeft = Math.abs(leftEdge - movementBounds.left);
         final int fromTop = Math.abs(stackBounds.top - movementBounds.top);
-        final int fromRight = Math.abs(movementBounds.right - stackBounds.left);
+        final int fromRight = Math.abs(movementBounds.right - leftEdge);
         final int fromBottom = Math.abs(movementBounds.bottom - stackBounds.top);
         final int shortest = Math.min(Math.min(fromLeft, fromRight), Math.min(fromTop, fromBottom));
         if (shortest == fromLeft) {
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 833924c..b2f4b55 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
@@ -135,6 +135,7 @@
     private final Handler mUpdateHandler;
     private final PipBoundsState mPipBoundsState;
     private final PipBoundsHandler mPipBoundsHandler;
+    // TODO(b/172286265): Remove dependency on .pip.PHONE.PipMenuActivityController
     private final PipMenuActivityController mMenuActivityController;
     private final PipAnimationController mPipAnimationController;
     private final PipUiEventLogger mPipUiEventLoggerLogger;
@@ -494,6 +495,8 @@
             mOnDisplayIdChangeCallback.accept(info.displayId);
         }
 
+        mMenuActivityController.onTaskAppeared();
+
         if (mShouldIgnoreEnteringPipTransition) {
             final Rect destinationBounds = mPipBoundsState.getBounds();
             // animation is finished in the Launcher and here we directly apply the final touch.
@@ -665,6 +668,7 @@
         mPictureInPictureParams = null;
         mState = State.UNDEFINED;
         mPipUiEventLoggerLogger.setTaskInfo(null);
+        mMenuActivityController.onTaskVanished();
     }
 
     @Override
@@ -946,10 +950,9 @@
         mSurfaceTransactionHelper
                 .crop(tx, mLeash, destinationBounds)
                 .round(tx, mLeash, mState.isInPip());
-        if (mMenuActivityController.isMenuVisible()) {
-            runOnMainHandler(() -> {
-                mMenuActivityController.resizePipMenu(mLeash, tx, destinationBounds);
-            });
+        if (mMenuActivityController != null && mMenuActivityController.isMenuVisible()) {
+            runOnMainHandler(() ->
+                    mMenuActivityController.resizePipMenu(mLeash, tx, destinationBounds));
         } else {
             tx.apply();
         }
@@ -973,10 +976,9 @@
 
         final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
         mSurfaceTransactionHelper.scale(tx, mLeash, startBounds, destinationBounds);
-        if (mMenuActivityController.isMenuVisible()) {
-            runOnMainHandler(() -> {
-                mMenuActivityController.movePipMenu(mLeash, tx, destinationBounds);
-            });
+        if (mMenuActivityController != null && mMenuActivityController.isMenuVisible()) {
+            runOnMainHandler(() ->
+                    mMenuActivityController.movePipMenu(mLeash, tx, destinationBounds));
         } else {
             tx.apply();
         }
@@ -993,7 +995,8 @@
         if (direction == TRANSITION_DIRECTION_REMOVE_STACK) {
             removePipImmediately();
             return;
-        } else if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) {
+        } else if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA
+                && mMenuActivityController != null) {
             // TODO: Synchronize this correctly in #applyEnterPipSyncTransaction
             finishResizeForMenu(destinationBounds);
             return;
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 37a5919..6e1fc83 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
@@ -196,6 +196,7 @@
             mMainExecutor.execute(() -> {
                 mPipBoundsHandler.onConfigurationChanged(mContext);
                 mTouchHandler.onConfigurationChanged();
+                mPipBoundsState.onConfigurationChanged();
             });
         }
 
@@ -276,7 +277,6 @@
         mMainExecutor.execute(() -> {
             mTouchHandler.onActivityPinned();
             mMediaController.onActivityPinned();
-            mMenuController.onActivityPinned();
             mAppOpsListener.onActivityPinned(packageName);
         });
     }
@@ -284,7 +284,6 @@
     @Override
     public void onActivityUnpinned(ComponentName topActivity) {
         mMainExecutor.execute(() -> {
-            mMenuController.onActivityUnpinned();
             mTouchHandler.onActivityUnpinned(topActivity);
             mAppOpsListener.onActivityUnpinned();
         });
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java
index 24144b2..1d54300 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java
@@ -22,6 +22,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
 import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
 import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP;
 
@@ -134,15 +135,22 @@
         return mPipMenuView != null && mMenuState != MENU_STATE_NONE;
     }
 
-    public void onActivityPinned() {
+    /**
+     * Attach the menu when the PiP task first appears.
+     */
+    public void onTaskAppeared() {
         attachPipMenuView();
     }
 
-    public void onActivityUnpinned() {
+    /**
+     * Detach the menu when the PiP task is gone.
+     */
+    public void onTaskVanished() {
         hideMenu();
         detachPipMenuView();
     }
 
+
     public void onPinnedStackAnimationEnded() {
         if (isMenuVisible()) {
             mPipMenuView.onPipAnimationEnded();
@@ -150,10 +158,11 @@
     }
 
     private void attachPipMenuView() {
-        if (mPipMenuView == null) {
-            mPipMenuView = new PipMenuView(mContext, this);
+        // In case detach was not called (e.g. PIP unexpectedly closed)
+        if (mPipMenuView != null) {
+            detachPipMenuView();
         }
-
+        mPipMenuView = new PipMenuView(mContext, this);
         mSystemWindows.addView(mPipMenuView, getPipMenuLayoutParams(0, 0), 0, SHELL_ROOT_LAYER_PIP);
     }
 
@@ -419,7 +428,7 @@
                 TYPE_APPLICATION_OVERLAY,
                 FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY | FLAG_NOT_TOUCHABLE,
                 PixelFormat.TRANSLUCENT);
-
+        lp.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY;
         lp.setTitle(MENU_WINDOW_TITLE);
         return lp;
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuIconsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuIconsAlgorithm.java
index 985cd0f..6d12752 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuIconsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuIconsAlgorithm.java
@@ -60,6 +60,7 @@
         if (mViewRoot == null || mTopEndContainer == null || mDragHandle == null
                 || mSettingsButton == null || mDismissButton == null) {
             Log.e(TAG, "One if the required views is null.");
+            return;
         }
 
         //We only need to calculate the layout once since it does not change.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index 9247c68..2e3db06 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -16,6 +16,9 @@
 
 package com.android.wm.shell.pip.phone;
 
+import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_LEFT;
+import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
@@ -33,7 +36,6 @@
 import androidx.dynamicanimation.animation.AnimationHandler.FrameCallbackScheduler;
 import androidx.dynamicanimation.animation.SpringForce;
 
-import com.android.wm.shell.R;
 import com.android.wm.shell.animation.FloatProperties;
 import com.android.wm.shell.animation.PhysicsAnimator;
 import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -42,7 +44,6 @@
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 
-import java.io.PrintWriter;
 import java.util.function.Consumer;
 
 import kotlin.Unit;
@@ -80,22 +81,6 @@
     /** The region that all of PIP must stay within. */
     private final Rect mFloatingAllowedArea = new Rect();
 
-    /**
-     * Temporary bounds used when PIP is being dragged or animated. These bounds are applied to PIP
-     * using {@link PipTaskOrganizer#scheduleUserResizePip}, so that we can animate shrinking into
-     * and expanding out of the magnetic dismiss target.
-     *
-     * Once PIP is done being dragged or animated, we set {@link #mBounds} equal to these temporary
-     * bounds, and call {@link PipTaskOrganizer#scheduleFinishResizePip} to 'officially' move PIP to
-     * its new bounds.
-     */
-    private final Rect mTemporaryBounds = new Rect();
-
-    /** The destination bounds to which PIP is animating. */
-    private final Rect mAnimatingToBounds = new Rect();
-
-    private int mStashOffset = 0;
-
     /** Coordinator instance for resolving conflicts with other floating content. */
     private FloatingContentCoordinator mFloatingContentCoordinator;
 
@@ -108,15 +93,15 @@
             });
 
     /**
-     * PhysicsAnimator instance for animating {@link #mTemporaryBounds} using physics animations.
+     * PhysicsAnimator instance for animating {@link PipBoundsState#getAnimatingBoundsState()}
+     * using physics animations.
      */
-    private PhysicsAnimator<Rect> mTemporaryBoundsPhysicsAnimator = PhysicsAnimator.getInstance(
-            mTemporaryBounds);
+    private final PhysicsAnimator<Rect> mTemporaryBoundsPhysicsAnimator;
 
     private MagnetizedObject<Rect> mMagnetizedPip;
 
     /**
-     * Update listener that resizes the PIP to {@link #mTemporaryBounds}.
+     * Update listener that resizes the PIP to {@link PipBoundsState#getAnimatingBoundsState()}.
      */
     private final PhysicsAnimator.UpdateListener<Rect> mResizePipUpdateListener;
 
@@ -189,27 +174,24 @@
         mSnapAlgorithm = snapAlgorithm;
         mFloatingContentCoordinator = floatingContentCoordinator;
         mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback);
+        mTemporaryBoundsPhysicsAnimator = PhysicsAnimator.getInstance(
+                mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds());
         mTemporaryBoundsPhysicsAnimator.setCustomAnimationHandler(
                 mSfAnimationHandlerThreadLocal.get());
-        reloadResources();
 
         mResizePipUpdateListener = (target, values) -> {
-            if (!mTemporaryBounds.isEmpty()) {
-                mPipTaskOrganizer.scheduleUserResizePip(
-                        getBounds(), mTemporaryBounds, null);
+            if (mPipBoundsState.getAnimatingBoundsState().isAnimating()) {
+                mPipTaskOrganizer.scheduleUserResizePip(getBounds(),
+                        mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds(), null);
             }
         };
     }
 
-    void reloadResources() {
-        mStashOffset = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.pip_stash_offset);
-    }
-
     @NonNull
     @Override
     public Rect getFloatingBoundsOnScreen() {
-        return !mAnimatingToBounds.isEmpty() ? mAnimatingToBounds : getBounds();
+        return !mPipBoundsState.getAnimatingBoundsState().getAnimatingToBounds().isEmpty()
+                ? mPipBoundsState.getAnimatingBoundsState().getAnimatingToBounds() : getBounds();
     }
 
     @NonNull
@@ -227,18 +209,14 @@
      * Synchronizes the current bounds with the pinned stack, cancelling any ongoing animations.
      */
     void synchronizePinnedStackBounds() {
-        cancelAnimations();
-        mTemporaryBounds.setEmpty();
+        cancelPhysicsAnimation();
+        mPipBoundsState.getAnimatingBoundsState().onAllAnimationsEnded();
 
         if (mPipTaskOrganizer.isInPip()) {
             mFloatingContentCoordinator.onContentMoved(this);
         }
     }
 
-    boolean isAnimating() {
-        return mTemporaryBoundsPhysicsAnimator.isRunning();
-    }
-
     /**
      * Tries to move the pinned stack to the given {@param bounds}.
      */
@@ -261,14 +239,14 @@
         if (!mSpringingToTouch) {
             // If we are moving PIP directly to the touch event locations, cancel any animations and
             // move PIP to the given bounds.
-            cancelAnimations();
+            cancelPhysicsAnimation();
 
             if (!isDragging) {
                 resizePipUnchecked(toBounds);
                 mPipBoundsState.setBounds(toBounds);
             } else {
-                mTemporaryBounds.set(toBounds);
-                mPipTaskOrganizer.scheduleUserResizePip(getBounds(), mTemporaryBounds,
+                mPipBoundsState.getAnimatingBoundsState().setTemporaryBounds(toBounds);
+                mPipTaskOrganizer.scheduleUserResizePip(getBounds(), toBounds,
                         (Rect newBounds) -> {
                             mMainHandler.post(() -> {
                                 mMenuController.updateMenuLayout(newBounds);
@@ -303,9 +281,9 @@
         final float destinationY = targetCenter.y - (desiredHeight / 2f);
 
         // If we're already in the dismiss target area, then there won't be a move to set the
-        // temporary bounds, so just initialize it to the current bounds
-        if (mTemporaryBounds.isEmpty()) {
-            mTemporaryBounds.set(getBounds());
+        // temporary bounds, so just initialize it to the current bounds.
+        if (!mPipBoundsState.getAnimatingBoundsState().isAnimating()) {
+            mPipBoundsState.getAnimatingBoundsState().setTemporaryBounds(getBounds());
         }
         mTemporaryBoundsPhysicsAnimator
                 .spring(FloatProperties.RECT_X, destinationX, velX, mSpringConfig)
@@ -339,7 +317,7 @@
             Log.d(TAG, "exitPip: skipAnimation=" + skipAnimation
                     + " callers=\n" + Debug.getCallers(5, "    "));
         }
-        cancelAnimations();
+        cancelPhysicsAnimation();
         mMenuController.hideMenuWithoutResize();
         mPipTaskOrganizer.getUpdateHandler().post(() -> {
             mPipTaskOrganizer.exitPip(skipAnimation
@@ -356,7 +334,7 @@
         if (DEBUG) {
             Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, "    "));
         }
-        cancelAnimations();
+        cancelPhysicsAnimation();
         mMenuController.hideMenuWithoutResize();
         mPipTaskOrganizer.removePip();
     }
@@ -383,14 +361,6 @@
     }
 
     /**
-     * Returns the PIP bounds if we're not animating, or the current, temporary animating bounds
-     * otherwise.
-     */
-    Rect getPossiblyAnimatingBounds() {
-        return mTemporaryBounds.isEmpty() ? getBounds() : mTemporaryBounds;
-    }
-
-    /**
      * Flings the PiP to the closest snap target.
      */
     void flingToSnapTarget(
@@ -403,6 +373,7 @@
      */
     void stashToEdge(
             float velocityX, float velocityY, @Nullable Runnable endAction) {
+        mPipBoundsState.setStashed(velocityX < 0 ? STASH_TYPE_LEFT : STASH_TYPE_RIGHT);
         movetoTarget(velocityX, velocityY, endAction, true /* isStash */);
     }
 
@@ -422,15 +393,18 @@
                         FloatProperties.RECT_Y, velocityY, mFlingConfigY, mSpringConfig)
                 .withEndActions(endAction);
 
-        final float leftEdge = isStash ? mStashOffset - mPipBoundsState.getBounds().width()
+        final float leftEdge = isStash
+                ? mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width()
                 : mMovementBounds.left;
-        final float rightEdge = isStash ?  mPipBoundsState.getDisplayBounds().right - mStashOffset
+        final float rightEdge = isStash
+                ?  mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset()
                 : mMovementBounds.right;
 
         final float xEndValue = velocityX < 0 ? leftEdge : rightEdge;
+
+        final int startValueY = mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds().top;
         final float estimatedFlingYEndValue =
-                PhysicsAnimator.estimateFlingEndValue(
-                        mTemporaryBounds.top, velocityY, mFlingConfigY);
+                PhysicsAnimator.estimateFlingEndValue(startValueY, velocityY, mFlingConfigY);
 
         startBoundsAnimator(xEndValue /* toX */, estimatedFlingYEndValue /* toY */,
                 false /* dismiss */);
@@ -443,7 +417,7 @@
     void animateToBounds(Rect bounds, PhysicsAnimator.SpringConfig springConfig) {
         if (!mTemporaryBoundsPhysicsAnimator.isRunning()) {
             // Animate from the current bounds if we're not already animating.
-            mTemporaryBounds.set(getBounds());
+            mPipBoundsState.getAnimatingBoundsState().setTemporaryBounds(getBounds());
         }
 
         mTemporaryBoundsPhysicsAnimator
@@ -493,9 +467,12 @@
         if (savedSnapFraction < 0f) {
             // If there are no saved snap fractions, then just use the current bounds
             savedSnapFraction = mSnapAlgorithm.getSnapFraction(new Rect(getBounds()),
-                    currentMovementBounds);
+                    currentMovementBounds, mPipBoundsState.getStashedState());
         }
-        mSnapAlgorithm.applySnapFraction(normalBounds, normalMovementBounds, savedSnapFraction);
+
+        mSnapAlgorithm.applySnapFraction(normalBounds, normalMovementBounds, savedSnapFraction,
+                mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(),
+                mPipBoundsState.getDisplayBounds());
 
         if (immediate) {
             movePip(normalBounds);
@@ -513,7 +490,7 @@
             Log.d(TAG, "animateToOffset: originalBounds=" + originalBounds + " offset=" + offset
                     + " callers=\n" + Debug.getCallers(5, "    "));
         }
-        cancelAnimations();
+        cancelPhysicsAnimation();
         mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION,
                 mUpdateBoundsCallback);
     }
@@ -521,9 +498,9 @@
     /**
      * Cancels all existing animations.
      */
-    private void cancelAnimations() {
+    private void cancelPhysicsAnimation() {
         mTemporaryBoundsPhysicsAnimator.cancel();
-        mAnimatingToBounds.setEmpty();
+        mPipBoundsState.getAnimatingBoundsState().onPhysicsAnimationEnded();
         mSpringingToTouch = false;
     }
 
@@ -534,8 +511,9 @@
         mFlingConfigY = new PhysicsAnimator.FlingConfig(
                 DEFAULT_FRICTION, mMovementBounds.top, mMovementBounds.bottom);
         mStashConfigX = new PhysicsAnimator.FlingConfig(
-                DEFAULT_FRICTION, mStashOffset - mPipBoundsState.getBounds().width(),
-                mPipBoundsState.getDisplayBounds().right - mStashOffset);
+                DEFAULT_FRICTION,
+                mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width(),
+                mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset());
     }
 
     /**
@@ -547,22 +525,19 @@
      */
     private void startBoundsAnimator(float toX, float toY, boolean dismiss) {
         if (!mSpringingToTouch) {
-            cancelAnimations();
+            cancelPhysicsAnimation();
         }
 
-        // Set animatingToBounds directly to avoid allocating a new Rect, but then call
-        // setAnimatingToBounds to run the normal logic for changing animatingToBounds.
-        mAnimatingToBounds.set(
+        setAnimatingToBounds(new Rect(
                 (int) toX,
                 (int) toY,
                 (int) toX + getBounds().width(),
-                (int) toY + getBounds().height());
-        setAnimatingToBounds(mAnimatingToBounds);
+                (int) toY + getBounds().height()));
 
         if (!mTemporaryBoundsPhysicsAnimator.isRunning()) {
             mTemporaryBoundsPhysicsAnimator
                     .addUpdateListener(mResizePipUpdateListener)
-                    .withEndActions(this::onBoundsAnimationEnd);
+                    .withEndActions(this::onBoundsPhysicsAnimationEnd);
         }
 
         mTemporaryBoundsPhysicsAnimator.start();
@@ -576,31 +551,34 @@
         mDismissalPending = true;
     }
 
-    private void onBoundsAnimationEnd() {
+    private void onBoundsPhysicsAnimationEnd() {
+        // The physics animation ended, though we may not necessarily be done animating, such as
+        // when we're still dragging after moving out of the magnetic target.
         if (!mDismissalPending
                 && !mSpringingToTouch
                 && !mMagnetizedPip.getObjectStuckToTarget()) {
-            mPipBoundsState.setBounds(mTemporaryBounds);
+            // All animations (including dragging) have actually finished.
+            mPipBoundsState.setBounds(
+                    mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds());
+            mPipBoundsState.getAnimatingBoundsState().onAllAnimationsEnded();
             if (!mDismissalPending) {
                 // do not schedule resize if PiP is dismissing, which may cause app re-open to
                 // mBounds instead of it's normal bounds.
                 mPipTaskOrganizer.scheduleFinishResizePip(getBounds());
             }
-            mTemporaryBounds.setEmpty();
         }
-
-        mAnimatingToBounds.setEmpty();
+        mPipBoundsState.getAnimatingBoundsState().onPhysicsAnimationEnded();
         mSpringingToTouch = false;
         mDismissalPending = false;
     }
 
     /**
-     * Notifies the floating coordinator that we're moving, and sets {@link #mAnimatingToBounds} so
+     * Notifies the floating coordinator that we're moving, and sets the animating to bounds so
      * we return these bounds from
      * {@link FloatingContentCoordinator.FloatingContent#getFloatingBoundsOnScreen()}.
      */
     private void setAnimatingToBounds(Rect bounds) {
-        mAnimatingToBounds.set(bounds);
+        mPipBoundsState.getAnimatingBoundsState().setAnimatingToBounds(bounds);
         mFloatingContentCoordinator.onContentMoved(this);
     }
 
@@ -639,7 +617,8 @@
     MagnetizedObject<Rect> getMagnetizedPip() {
         if (mMagnetizedPip == null) {
             mMagnetizedPip = new MagnetizedObject<Rect>(
-                    mContext, mTemporaryBounds, FloatProperties.RECT_X, FloatProperties.RECT_Y) {
+                    mContext, mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds(),
+                    FloatProperties.RECT_X, FloatProperties.RECT_Y) {
                 @Override
                 public float getWidth(@NonNull Rect animatedPipBounds) {
                     return animatedPipBounds.width();
@@ -661,10 +640,4 @@
 
         return mMagnetizedPip;
     }
-
-    public void dump(PrintWriter pw, String prefix) {
-        final String innerPrefix = prefix + "  ";
-        pw.println(prefix + TAG);
-        pw.println(innerPrefix + "mBounds=" + getBounds());
-    }
 }
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 d820e77..9ba4672 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
@@ -221,7 +221,6 @@
                 R.dimen.pip_expanded_shortest_edge_size);
         mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
         mPipDismissTargetHandler.updateMagneticTargetSize();
-        mMotionHelper.reloadResources();
     }
 
     private boolean shouldShowResizeHandle() {
@@ -710,7 +709,7 @@
                 return;
             }
 
-            Rect bounds = mMotionHelper.getPossiblyAnimatingBounds();
+            Rect bounds = getPossiblyAnimatingBounds();
             mDelta.set(0f, 0f);
             mStartPosition.set(bounds.left, bounds.top);
             mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
@@ -730,7 +729,7 @@
             }
 
             if (touchState.startedDragging()) {
-                mPipBoundsState.setStashed(false);
+                mPipBoundsState.setStashed(PipBoundsState.STASH_TYPE_NONE);
                 mSavedSnapFraction = -1f;
                 mPipDismissTargetHandler.showDismissTargetMaybe();
             }
@@ -747,7 +746,7 @@
                 mDelta.x += left - lastX;
                 mDelta.y += top - lastY;
 
-                mTmpBounds.set(mMotionHelper.getPossiblyAnimatingBounds());
+                mTmpBounds.set(getPossiblyAnimatingBounds());
                 mTmpBounds.offsetTo((int) left, (int) top);
                 mMotionHelper.movePip(mTmpBounds, true /* isDragging */);
 
@@ -783,13 +782,12 @@
 
                 // Reset the touch state on up before the fling settles
                 mTouchState.reset();
-                final Rect animatingBounds = mMotionHelper.getPossiblyAnimatingBounds();
+                final Rect animatingBounds = getPossiblyAnimatingBounds();
                 // If User releases the PIP window while it's out of the display bounds, put
                 // PIP into stashed mode.
                 if (mEnableStash
                         && (animatingBounds.right > mPipBoundsState.getDisplayBounds().right
                         || animatingBounds.left < mPipBoundsState.getDisplayBounds().left)) {
-                    mPipBoundsState.setStashed(true);
                     mMotionHelper.stashToEdge(vel.x, vel.y, this::flingEndAction /* endAction */);
                 } else {
                     mMotionHelper.flingToSnapTarget(vel.x, vel.y,
@@ -872,6 +870,16 @@
                 || mExpandedBounds.height() != mNormalBounds.height();
     }
 
+    /**
+     * Returns the PIP bounds if we're not animating, or the current, temporary animating bounds
+     * otherwise.
+     */
+    Rect getPossiblyAnimatingBounds() {
+        return mPipBoundsState.getAnimatingBoundsState().isAnimating()
+                ? mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds()
+                : mPipBoundsState.getBounds();
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
@@ -889,7 +897,6 @@
         pw.println(innerPrefix + "mMovementBoundsExtraOffsets=" + mMovementBoundsExtraOffsets);
         mPipBoundsHandler.dump(pw, innerPrefix);
         mTouchState.dump(pw, innerPrefix);
-        mMotionHelper.dump(pw, innerPrefix);
         if (mPipResizeGestureHandler != null) {
             mPipResizeGestureHandler.dump(pw, innerPrefix);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index 985dff2..d117673 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -83,4 +83,9 @@
      * @return {@code true} if it successes to split the primary task.
      */
     boolean splitPrimaryTask();
+
+    /**
+     * Exits the split to make the primary task fullscreen.
+     */
+    void dismissSplitToPrimaryTask();
 }
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 8b616e8..341a459 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
@@ -501,6 +501,11 @@
         }
     }
 
+    @Override
+    public void dismissSplitToPrimaryTask() {
+        startDismissSplit(true /* toPrimaryTask */);
+    }
+
     /** Notifies the bounds of split screen changed. */
     void notifyBoundsChanged(Rect secondaryWindowBounds, Rect secondaryWindowInsets) {
         synchronized (mBoundsChangedListeners) {
@@ -519,8 +524,8 @@
         mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
     }
 
-    void startDismissSplit() {
-        mWindowManagerProxy.applyDismissSplit(mSplits, mSplitLayout, true /* dismissOrMaximize */);
+    void startDismissSplit(boolean toPrimaryTask) {
+        mWindowManagerProxy.applyDismissSplit(mSplits, mSplitLayout, !toPrimaryTask);
         updateVisibility(false /* visible */);
         mMinimized = false;
         // Resets divider bar position to undefined, so new divider bar will apply default position
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskListener.java
index f709fed..64e9d66 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskListener.java
@@ -271,7 +271,7 @@
                     Log.d(TAG, "    was in split, so this means leave it "
                             + mPrimary.topActivityType + "  " + mSecondary.topActivityType);
                 }
-                mSplitScreenController.startDismissSplit();
+                mSplitScreenController.startDismissSplit(false /* toPrimaryTask */);
             } else if (!primaryIsEmpty && primaryWasEmpty && secondaryWasEmpty) {
                 // Wasn't in split-mode (both were empty), but now that the primary split is
                 // populated, we should fully enter split by moving everything else into secondary.
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
index 8b2f668..9e83309 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
@@ -32,8 +32,21 @@
     <!-- Workaround grant runtime permission exception from b/152733071 -->
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
     <uses-permission android:name="android.permission.READ_LOGS"/>
+    <!-- Force-stop test apps -->
+    <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
+    <!-- Control test app's media session -->
+    <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
     <application>
         <uses-library android:name="android.test.runner"/>
+
+        <service android:name=".NotificationListener"
+                 android:exported="true"
+                 android:label="WMShellTestsNotificationListenerService"
+                 android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.notification.NotificationListenerService" />
+            </intent-filter>
+        </service>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
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
new file mode 100644
index 0000000..ef0390f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.content.ComponentName
+
+const val IME_WINDOW_NAME = "InputMethod"
+const val PIP_WINDOW_NAME = "PipMenuActivity"
+
+// Test App
+const val TEST_APP_PACKAGE_NAME = "com.android.wm.shell.flicker.testapp"
+// Test App > Pip Activity
+val TEST_APP_PIP_ACTIVITY_COMPONENT_NAME: ComponentName = ComponentName.createRelative(
+        TEST_APP_PACKAGE_NAME, ".PipActivity")
+const val TEST_APP_PIP_ACTIVITY_LABEL = "PipApp"
+const val TEST_APP_PIP_ACTIVITY_WINDOW_NAME = "PipActivity"
+// Test App > Ime Activity
+val TEST_APP_IME_ACTIVITY_COMPONENT_NAME: ComponentName = ComponentName.createRelative(
+        TEST_APP_PACKAGE_NAME, ".ImeActivity")
+const val TEST_APP_IME_ACTIVITY_LABEL = "ImeApp"
+
+const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
index 99f824b..75b55c1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.flicker
 
+import android.content.pm.PackageManager
 import android.os.RemoteException
 import android.os.SystemClock
 import android.platform.helpers.IAppHelper
@@ -41,6 +42,9 @@
     val uiDevice by lazy {
         UiDevice.getInstance(instrumentation)
     }
+    val packageManager: PackageManager by lazy {
+        instrumentation.context.getPackageManager()
+    }
 
     /**
      * Build a test tag for the test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NotificationListener.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NotificationListener.kt
new file mode 100644
index 0000000..51f7a18
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NotificationListener.kt
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.service.notification.NotificationListenerService
+import android.service.notification.StatusBarNotification
+import android.util.Log
+import com.android.compatibility.common.util.SystemUtil.runShellCommand
+
+class NotificationListener : NotificationListenerService() {
+    private val notifications: MutableMap<Any, StatusBarNotification> = mutableMapOf()
+
+    override fun onNotificationPosted(sbn: StatusBarNotification) {
+        if (DEBUG) Log.d(TAG, "onNotificationPosted: $sbn")
+        notifications[sbn.key] = sbn
+    }
+
+    override fun onNotificationRemoved(sbn: StatusBarNotification) {
+        if (DEBUG) Log.d(TAG, "onNotificationRemoved: $sbn")
+        notifications.remove(sbn.key)
+    }
+
+    override fun onListenerConnected() {
+        if (DEBUG) Log.d(TAG, "onListenerConnected")
+        instance = this
+    }
+
+    override fun onListenerDisconnected() {
+        if (DEBUG) Log.d(TAG, "onListenerDisconnected")
+        instance = null
+        notifications.clear()
+    }
+
+    companion object {
+        private const val DEBUG = false
+        private const val TAG = "WMShellFlickerTests_NotificationListener"
+
+        private const val CMD_NOTIFICATION_ALLOW_LISTENER = "cmd notification allow_listener %s"
+        private const val CMD_NOTIFICATION_DISALLOW_LISTENER =
+                "cmd notification disallow_listener %s"
+        private const val COMPONENT_NAME = "com.android.wm.shell.flicker/.NotificationListener"
+
+        private var instance: NotificationListener? = null
+
+        fun startNotificationListener(): Boolean {
+            if (instance != null) {
+                return true
+            }
+
+            runShellCommand(CMD_NOTIFICATION_ALLOW_LISTENER.format(COMPONENT_NAME))
+            return wait { instance != null }
+        }
+
+        fun stopNotificationListener(): Boolean {
+            if (instance == null) {
+                return true
+            }
+
+            runShellCommand(CMD_NOTIFICATION_DISALLOW_LISTENER.format(COMPONENT_NAME))
+            return wait { instance == null }
+        }
+
+        fun findNotification(
+            predicate: (StatusBarNotification) -> Boolean
+        ): StatusBarNotification? {
+            instance?.run {
+                return notifications.values.firstOrNull(predicate)
+            } ?: throw IllegalStateException("NotificationListenerService is not connected")
+        }
+
+        fun waitForNotificationToAppear(
+            predicate: (StatusBarNotification) -> Boolean
+        ): StatusBarNotification? {
+            instance?.let {
+                return waitForResult(extractor = {
+                    it.notifications.values.firstOrNull(predicate)
+                }).second
+            } ?: throw IllegalStateException("NotificationListenerService is not connected")
+        }
+
+        fun waitForNotificationToDisappear(
+            predicate: (StatusBarNotification) -> Boolean
+        ): Boolean {
+            return instance?.let {
+                wait { it.notifications.values.none(predicate) }
+            } ?: throw IllegalStateException("NotificationListenerService is not connected")
+        }
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/WaitUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/WaitUtils.kt
new file mode 100644
index 0000000..a6d6735
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/WaitUtils.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.os.SystemClock
+
+private const val DEFAULT_TIMEOUT = 10000L
+private const val DEFAULT_POLL_INTERVAL = 1000L
+
+fun wait(condition: () -> Boolean): Boolean {
+    val (success, _) = waitForResult(extractor = condition, validator = { it })
+    return success
+}
+
+fun <R> waitForResult(
+    timeout: Long = DEFAULT_TIMEOUT,
+    interval: Long = DEFAULT_POLL_INTERVAL,
+    extractor: () -> R,
+    validator: (R) -> Boolean = { it != null }
+): Pair<Boolean, R?> {
+    val startTime = SystemClock.uptimeMillis()
+    do {
+        val result = extractor()
+        if (validator(result)) {
+            return (true to result)
+        }
+        SystemClock.sleep(interval)
+    } while (SystemClock.uptimeMillis() - startTime < timeout)
+
+    return (false to null)
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
new file mode 100644
index 0000000..55796da
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.flicker.helpers
+
+import android.app.ActivityManager
+import android.app.Instrumentation
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager.FEATURE_LEANBACK
+import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY
+import android.support.test.launcherhelper.LauncherStrategyFactory
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import com.android.server.wm.flicker.helpers.StandardAppHelper
+import com.android.wm.shell.flicker.TEST_APP_PACKAGE_NAME
+
+abstract class BaseAppHelper(
+    instrumentation: Instrumentation,
+    launcherName: String,
+    private val launcherActivityComponent: ComponentName
+) : StandardAppHelper(
+        instrumentation,
+        TEST_APP_PACKAGE_NAME,
+        launcherName,
+        LauncherStrategyFactory.getInstance(instrumentation).launcherStrategy
+) {
+    protected val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)
+
+    protected val context: Context
+        get() = mInstrumentation.context
+
+    private val activityManager: ActivityManager?
+        get() = context.getSystemService(ActivityManager::class.java)
+
+    private val appSelector = By.pkg(packageName).depth(0)
+
+    protected val isTelevision: Boolean
+        get() = context.packageManager.run {
+            hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY)
+        }
+
+    val label: String
+        get() = context.packageManager.run {
+            getApplicationLabel(getApplicationInfo(packageName, 0)).toString()
+        }
+
+    fun launchViaIntent() {
+        context.startActivity(openAppIntent)
+
+        uiDevice.wait(Until.hasObject(appSelector), APP_LAUNCH_WAIT_TIME_MS)
+    }
+
+    fun waitUntilClosed(): Boolean {
+        return uiDevice.wait(Until.gone(appSelector), APP_CLOSE_WAIT_TIME_MS)
+    }
+
+    fun forceStop() = activityManager?.forceStopPackage(packageName)
+
+    override fun getOpenAppIntent(): Intent {
+        val intent = Intent()
+        intent.component = launcherActivityComponent
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        return intent
+    }
+
+    companion object {
+        private const val APP_LAUNCH_WAIT_TIME_MS = 10_000L
+        private const val APP_CLOSE_WAIT_TIME_MS = 3_000L
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt
deleted file mode 100644
index 47a62ce..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.wm.shell.flicker.helpers
-
-import android.app.Instrumentation
-import android.support.test.launcherhelper.ILauncherStrategy
-import com.android.server.wm.flicker.helpers.StandardAppHelper
-
-abstract class FlickerAppHelper(
-    instr: Instrumentation,
-    launcherName: String,
-    launcherStrategy: ILauncherStrategy
-) : StandardAppHelper(instr, sFlickerPackage, launcherName, launcherStrategy) {
-    companion object {
-        var sFlickerPackage = "com.android.wm.shell.flicker.testapp"
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
index 0cedc0a..a6650d7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
@@ -17,37 +17,36 @@
 package com.android.wm.shell.flicker.helpers
 
 import android.app.Instrumentation
-import android.support.test.launcherhelper.ILauncherStrategy
-import android.support.test.launcherhelper.LauncherStrategyFactory
 import androidx.test.uiautomator.By
-import androidx.test.uiautomator.UiDevice
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.helpers.FIND_TIMEOUT
 import com.android.server.wm.flicker.helpers.waitForIME
+import com.android.wm.shell.flicker.TEST_APP_IME_ACTIVITY_COMPONENT_NAME
+import com.android.wm.shell.flicker.TEST_APP_IME_ACTIVITY_LABEL
 import org.junit.Assert
 
 open class ImeAppHelper(
-    instr: Instrumentation,
-    launcherName: String = "ImeApp",
-    launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
-            .getInstance(instr)
-            .launcherStrategy
-) : FlickerAppHelper(instr, launcherName, launcherStrategy) {
-    open fun openIME(device: UiDevice) {
-        val editText = device.wait(
+    instrumentation: Instrumentation
+) : BaseAppHelper(
+        instrumentation,
+        TEST_APP_IME_ACTIVITY_LABEL,
+        TEST_APP_IME_ACTIVITY_COMPONENT_NAME
+) {
+    fun openIME() {
+        val editText = uiDevice.wait(
                 Until.findObject(By.res(getPackage(), "plain_text_input")),
                 FIND_TIMEOUT)
         Assert.assertNotNull("Text field not found, this usually happens when the device " +
                 "was left in an unknown state (e.g. in split screen)", editText)
         editText.click()
-        if (!device.waitForIME()) {
+        if (!uiDevice.waitForIME()) {
             Assert.fail("IME did not appear")
         }
     }
 
-    open fun closeIME(device: UiDevice) {
-        device.pressBack()
+    fun closeIME() {
+        uiDevice.pressBack()
         // Using only the AccessibilityInfo it is not possible to identify if the IME is active
-        device.waitForIdle(1000)
+        uiDevice.waitForIdle(1000)
     }
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index 5391702..42686e7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -17,29 +17,79 @@
 package com.android.wm.shell.flicker.helpers
 
 import android.app.Instrumentation
-import android.support.test.launcherhelper.ILauncherStrategy
-import android.support.test.launcherhelper.LauncherStrategyFactory
+import android.media.session.MediaController
+import android.media.session.MediaSessionManager
+import android.os.SystemClock
+import android.view.KeyEvent.KEYCODE_WINDOW
 import androidx.test.uiautomator.By
-import androidx.test.uiautomator.UiDevice
-import com.android.server.wm.flicker.helpers.hasPipWindow
+import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.helpers.closePipWindow
-import org.junit.Assert
+import com.android.server.wm.flicker.helpers.hasPipWindow
+import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
+import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_COMPONENT_NAME
+import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_LABEL
+import org.junit.Assert.assertNotNull
 
 class PipAppHelper(
-    instr: Instrumentation,
-    launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
-            .getInstance(instr)
-            .launcherStrategy
-) : FlickerAppHelper(instr, "PipApp", launcherStrategy) {
-    fun clickEnterPipButton(device: UiDevice) {
-        val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"))
-        Assert.assertNotNull("Pip button not found, this usually happens when the device " +
+    instrumentation: Instrumentation
+) : BaseAppHelper(
+        instrumentation,
+        TEST_APP_PIP_ACTIVITY_LABEL,
+        TEST_APP_PIP_ACTIVITY_COMPONENT_NAME
+) {
+    private val mediaSessionManager: MediaSessionManager
+        get() = context.getSystemService(MediaSessionManager::class.java)
+                ?: error("Could not get MediaSessionManager")
+
+    private val mediaController: MediaController?
+        get() = mediaSessionManager.getActiveSessions(null).firstOrNull {
+            it.packageName == packageName
+        }
+
+    fun clickEnterPipButton() {
+        val enterPipButton = uiDevice.findObject(By.res(packageName, "enter_pip"))
+        assertNotNull("Pip button not found, this usually happens when the device " +
                 "was left in an unknown state (e.g. in split screen)", enterPipButton)
         enterPipButton.click()
-        device.hasPipWindow()
+
+        // TODO(b/172321238): remove this check once hasPipWindow is fixed on TVs
+        if (!isTelevision) {
+            uiDevice.hasPipWindow()
+        } else {
+            // Simply wait for 3 seconds
+            SystemClock.sleep(3_000)
+        }
     }
 
-    fun closePipWindow(device: UiDevice) {
-        device.closePipWindow()
+    fun clickStartMediaSessionButton() {
+        val startButton = uiDevice.findObject(By.res(packageName, "media_session_start"))
+        assertNotNull("Start button not found, this usually happens when the device " +
+                "was left in an unknown state (e.g. in split screen)", startButton)
+        startButton.click()
+    }
+
+    fun pauseMedia() = mediaController?.transportControls?.pause()
+            ?: error("No active media session found")
+
+    fun stopMedia() = mediaController?.transportControls?.stop()
+            ?: error("No active media session found")
+
+    fun closePipWindow() {
+        // TODO(b/172321238): remove this check once and simply call closePipWindow once the TV
+        //  logic is integrated there.
+        if (!isTelevision) {
+            uiDevice.closePipWindow()
+        } else {
+            // Bring up Pip menu
+            uiDevice.pressKeyCode(KEYCODE_WINDOW)
+
+            // Wait for the menu to come up and render the close button
+            val closeButton = uiDevice.wait(
+                    Until.findObject(By.res(SYSTEM_UI_PACKAGE_NAME, "close_button")), 3_000)
+            assertNotNull("Pip menu close button is not found", closeButton)
+            closeButton.click()
+
+            waitUntilClosed()
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 010aa0d..a1da7c9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -31,6 +31,7 @@
 import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
 import com.android.wm.shell.flicker.statusBarLayerRotatesScales
 import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.PIP_WINDOW_NAME
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -79,7 +80,7 @@
                 }
             }
             transitions {
-                testApp.clickEnterPipButton(device)
+                testApp.clickEnterPipButton()
                 device.expandPipWindow()
             }
             assertions {
@@ -89,7 +90,7 @@
                     all("pipWindowBecomesVisible") {
                         this.showsAppWindow(testApp.`package`)
                                 .then()
-                                .showsAppWindow(sPipWindowTitle)
+                                .showsAppWindow(PIP_WINDOW_NAME)
                     }
                 }
 
@@ -103,7 +104,7 @@
                     all("pipLayerBecomesVisible") {
                         this.showsLayer(testApp.launcherName)
                                 .then()
-                                .showsLayer(sPipWindowTitle)
+                                .showsLayer(PIP_WINDOW_NAME)
                     }
                 }
             }
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 43e0225..d343f2a 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
@@ -18,7 +18,6 @@
 
 import android.content.ComponentName
 import android.graphics.Region
-import android.support.test.launcherhelper.LauncherStrategyFactory
 import android.util.Log
 import android.view.Surface
 import android.view.WindowManager
@@ -29,6 +28,9 @@
 import com.android.server.wm.flicker.helpers.closePipWindow
 import com.android.server.wm.flicker.helpers.hasPipWindow
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.wm.shell.flicker.TEST_APP_IME_ACTIVITY_COMPONENT_NAME
+import com.android.wm.shell.flicker.IME_WINDOW_NAME
+import com.android.wm.shell.flicker.TEST_APP_PIP_ACTIVITY_WINDOW_NAME
 import com.android.wm.shell.flicker.helpers.ImeAppHelper
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -51,19 +53,11 @@
     private val windowManager: WindowManager =
             instrumentation.context.getSystemService(WindowManager::class.java)
 
-    private val keyboardApp = ImeAppHelper(instrumentation, "ImeApp",
-            LauncherStrategyFactory.getInstance(instrumentation).launcherStrategy)
-
-    private val KEYBOARD_ACTIVITY: ComponentName = ComponentName.createRelative(
-            "com.android.wm.shell.flicker.testapp", ".ImeActivity")
-    private val PIP_ACTIVITY_WINDOW_NAME = "PipActivity"
-    private val INPUT_METHOD_WINDOW_NAME = "InputMethod"
-
-    private val testRepetitions = 10
+    private val keyboardApp = ImeAppHelper(instrumentation)
 
     private val keyboardScenario: FlickerBuilder
         get() = FlickerBuilder(instrumentation).apply {
-            repeat { testRepetitions }
+            repeat { TEST_REPETITIONS }
             // disable layer tracing
             withLayerTracing { null }
             setup {
@@ -73,11 +67,11 @@
                     // launch our target pip app
                     testApp.open()
                     this.setRotation(rotation)
-                    testApp.clickEnterPipButton(device)
+                    testApp.clickEnterPipButton()
                     // open an app with an input field and a keyboard
                     // UiAutomator doesn't support to launch the multiple Activities in a task.
                     // So use launchActivity() for the Keyboard Activity.
-                    launchActivity(KEYBOARD_ACTIVITY)
+                    launchActivity(TEST_APP_IME_ACTIVITY_COMPONENT_NAME)
                 }
             }
             teardown {
@@ -101,10 +95,10 @@
             withTestName { testTag }
             transitions {
                 // open the soft keyboard
-                keyboardApp.openIME(device)
+                keyboardApp.openIME()
 
                 // then close it again
-                keyboardApp.closeIME(device)
+                keyboardApp.closeIME()
             }
             assertions {
                 windowManagerTrace {
@@ -127,18 +121,18 @@
             withTestName { testTag }
             transitions {
                 // open the soft keyboard
-                keyboardApp.openIME(device)
+                keyboardApp.openIME()
             }
             teardown {
                 eachRun {
                     // close the keyboard
-                    keyboardApp.closeIME(device)
+                    keyboardApp.closeIME()
                 }
             }
             assertions {
                 windowManagerTrace {
                     end {
-                        isAboveWindow(INPUT_METHOD_WINDOW_NAME, PIP_ACTIVITY_WINDOW_NAME)
+                        isAboveWindow(IME_WINDOW_NAME, TEST_APP_PIP_ACTIVITY_WINDOW_NAME)
                     }
                 }
             }
@@ -207,6 +201,8 @@
     }
 
     companion object {
+        private const val TEST_REPETITIONS = 10
+
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
         fun getParams(): Collection<Array<Any>> {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
index 3822d69..c1c34ec 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
@@ -24,8 +24,4 @@
     rotation: Int
 ) : NonRotationTestBase(rotationName, rotation) {
     protected val testApp = PipAppHelper(instrumentation)
-
-    companion object {
-        const val sPipWindowTitle = "PipMenuActivity"
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt
new file mode 100644
index 0000000..1d44658
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.flicker.pip.tv
+
+import android.app.Notification
+import android.app.PendingIntent
+import android.os.Bundle
+import android.service.notification.StatusBarNotification
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.NotificationListener.Companion.findNotification
+import com.android.wm.shell.flicker.NotificationListener.Companion.startNotificationListener
+import com.android.wm.shell.flicker.NotificationListener.Companion.stopNotificationListener
+import com.android.wm.shell.flicker.NotificationListener.Companion.waitForNotificationToAppear
+import com.android.wm.shell.flicker.NotificationListener.Companion.waitForNotificationToDisappear
+import org.junit.After
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+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 Notifications on TV.
+ * To run this test: `atest WMShellFlickerTests:TvPipNotificationTests`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class TvPipNotificationTests(rotationName: String, rotation: Int)
+    : TvPipTestBase(rotationName, rotation) {
+
+    @Before
+    override fun setUp() {
+        super.setUp()
+        val started = startNotificationListener()
+        if (!started) {
+            error("NotificationListener hasn't started")
+        }
+    }
+
+    @After
+    override fun tearDown() {
+        stopNotificationListener()
+        testApp.forceStop()
+        super.tearDown()
+    }
+
+    @Test
+    fun pipNotification_postedAndDismissed() {
+        testApp.launchViaIntent()
+        testApp.clickEnterPipButton()
+
+        assertNotNull("Pip notification should have been posted",
+                waitForNotificationToAppear { it.isPipNotificationWithTitle(testApp.label) })
+
+        testApp.closePipWindow()
+
+        assertTrue("Pip notification should have been dismissed",
+                waitForNotificationToDisappear { it.isPipNotificationWithTitle(testApp.label) })
+    }
+
+    @Test
+    fun pipNotification_closeIntent() {
+        testApp.launchViaIntent()
+        testApp.clickEnterPipButton()
+
+        val notification: StatusBarNotification = waitForNotificationToAppear {
+            it.isPipNotificationWithTitle(testApp.label)
+        } ?: fail("Pip notification should have been posted")
+
+        notification.deleteIntent?.send()
+            ?: fail("Pip notification should contain `delete_intent`")
+
+        assertTrue("Pip should have closed by sending the `delete_intent`",
+                testApp.waitUntilClosed())
+        assertTrue("Pip notification should have been dismissed",
+                waitForNotificationToDisappear { it.isPipNotificationWithTitle(testApp.label) })
+    }
+
+    @Test
+    fun pipNotification_menuIntent() {
+        testApp.launchViaIntent()
+        testApp.clickEnterPipButton()
+
+        val notification: StatusBarNotification = waitForNotificationToAppear {
+            it.isPipNotificationWithTitle(testApp.label)
+        } ?: fail("Pip notification should have been posted")
+
+        notification.contentIntent?.send()
+            ?: fail("Pip notification should contain `content_intent`")
+
+        assertTrue("Pip menu should have been shown after sending `content_intent`",
+                uiDevice.waitForTvPipMenu())
+
+        uiDevice.pressBack()
+        testApp.closePipWindow()
+    }
+
+    @Test
+    fun pipNotification_mediaSessionTitle_isDisplayed() {
+        testApp.launchViaIntent()
+        // Start media session and to PiP
+        testApp.clickStartMediaSessionButton()
+        testApp.clickEnterPipButton()
+
+        // Wait for the correct notification to show up...
+        waitForNotificationToAppear {
+            it.isPipNotificationWithTitle(TITLE_MEDIA_SESSION_PLAYING)
+        } ?: fail("Pip notification with media session title should have been posted")
+        // ... and make sure "regular" PiP notification is now shown
+        assertNull("Regular notification should not have been posted",
+            findNotification { it.isPipNotificationWithTitle(testApp.label) })
+
+        // Pause the media session. When paused the application updates the title for the media
+        // session. This change should be reflected in the notification.
+        testApp.pauseMedia()
+
+        // Wait for the "paused" notification to show up...
+        waitForNotificationToAppear {
+            it.isPipNotificationWithTitle(TITLE_MEDIA_SESSION_PAUSED)
+        } ?: fail("Pip notification with media session title should have been posted")
+        // ... and make sure "playing" PiP notification is gone
+        assertNull("Regular notification should not have been posted",
+                findNotification { it.isPipNotificationWithTitle(TITLE_MEDIA_SESSION_PLAYING) })
+
+        // Now stop the media session, which should revert the title to the "default" one.
+        testApp.stopMedia()
+
+        // Wait for the "regular" notification to show up...
+        waitForNotificationToAppear {
+            it.isPipNotificationWithTitle(testApp.label)
+        } ?: fail("Pip notification with media session title should have been posted")
+        // ... and make sure previous ("paused") notification is gone
+        assertNull("Regular notification should not have been posted",
+                findNotification { it.isPipNotificationWithTitle(TITLE_MEDIA_SESSION_PAUSED) })
+
+        testApp.closePipWindow()
+    }
+
+    private fun fail(message: String): Nothing = throw AssertionError(message)
+
+    companion object {
+        private const val TITLE_MEDIA_SESSION_PLAYING = "TestApp media is playing"
+        private const val TITLE_MEDIA_SESSION_PAUSED = "TestApp media is paused"
+
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<Array<Any>> {
+            val supportedRotations = intArrayOf(Surface.ROTATION_0)
+            return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+        }
+    }
+}
+
+private val StatusBarNotification.extras: Bundle?
+    get() = notification?.extras
+
+private val StatusBarNotification.title: String
+    get() = extras?.getString(Notification.EXTRA_TITLE) ?: ""
+
+/** Get TV extensions with [android.app.Notification.TvExtender.EXTRA_TV_EXTENDER]. */
+private val StatusBarNotification.tvExtensions: Bundle?
+    get() = extras?.getBundle("android.tv.EXTENSIONS")
+
+/** "Content" TV intent with key [android.app.Notification.TvExtender.EXTRA_CONTENT_INTENT]. */
+private val StatusBarNotification.contentIntent: PendingIntent?
+    get() = tvExtensions?.getParcelable("content_intent")
+
+/** "Delete" TV intent with key [android.app.Notification.TvExtender.EXTRA_DELETE_INTENT]. */
+private val StatusBarNotification.deleteIntent: PendingIntent?
+    get() = tvExtensions?.getParcelable("delete_intent")
+
+private fun StatusBarNotification.isPipNotificationWithTitle(expectedTitle: String): Boolean =
+    tag == "PipNotification" && title == expectedTitle
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
new file mode 100644
index 0000000..104248c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.flicker.pip.tv
+
+import android.content.pm.PackageManager.FEATURE_LEANBACK
+import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.wm.shell.flicker.pip.PipTestBase
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+
+abstract class TvPipTestBase(rotationName: String, rotation: Int)
+    : PipTestBase(rotationName, rotation) {
+
+    private val isTelevision: Boolean
+        get() = packageManager.run {
+            hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY)
+        }
+
+    @Before
+    open fun setUp() {
+        Assume.assumeTrue(isTelevision)
+        uiDevice.wakeUpAndGoToHomeScreen()
+    }
+
+    @After
+    open fun tearDown() {
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
similarity index 62%
copy from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
copy to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
index 24768cd..ac9ab13 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
@@ -13,17 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
 
-import android.annotation.DimenRes
-import android.annotation.UserIdInt
+package com.android.wm.shell.flicker.pip.tv
 
-data class BubbleEntity(
-    @UserIdInt val userId: Int,
-    val packageName: String,
-    val shortcutId: String,
-    val key: String,
-    val desiredHeight: Int,
-    @DimenRes val desiredHeightResId: Int,
-    val title: String? = null
-)
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
+
+fun UiDevice.waitForTvPipMenu(): Boolean {
+    return wait(Until.findObject(By.res(SYSTEM_UI_PACKAGE_NAME, "pip_controls")), 3_000) != null
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
index e1870d9..0e79d03c 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
@@ -18,9 +18,36 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:orientation="vertical"
     android:background="@android:color/holo_blue_bright">
-    <Button android:layout_width="wrap_content"
+
+    <Button
+        android:id="@+id/enter_pip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Enter PIP"/>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Media Session"/>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+
+        <Button
+            android:id="@+id/media_session_start"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:id="@+id/enter_pip"
-            android:text="Enter PIP"/>
+            android:text="Start"/>
+
+        <Button
+            android:id="@+id/media_session_stop"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Stop"/>
+
+    </LinearLayout>
+
 </LinearLayout>
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
index 3052816..f70603e 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
@@ -16,30 +16,113 @@
 
 package com.android.wm.shell.flicker.testapp;
 
+import static android.media.MediaMetadata.METADATA_KEY_TITLE;
+import static android.media.session.PlaybackState.ACTION_PLAY_PAUSE;
+import static android.media.session.PlaybackState.ACTION_STOP;
+import static android.media.session.PlaybackState.STATE_PAUSED;
+import static android.media.session.PlaybackState.STATE_PLAYING;
+import static android.media.session.PlaybackState.STATE_STOPPED;
+
 import android.app.Activity;
 import android.app.PictureInPictureParams;
 import android.graphics.Rect;
+import android.media.MediaMetadata;
+import android.media.session.MediaSession;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.util.Rational;
+import android.view.Window;
 import android.view.WindowManager;
-import android.widget.Button;
 
 public class PipActivity extends Activity {
+    /**
+     * A media session title for when the session is in {@link STATE_PLAYING}.
+     * TvPipNotificationTests check whether the actual notification title matches this string.
+     */
+    private static final String TITLE_STATE_PLAYING = "TestApp media is playing";
+    /**
+     * A media session title for when the session is in {@link STATE_PAUSED}.
+     * TvPipNotificationTests check whether the actual notification title matches this string.
+     */
+    private static final String TITLE_STATE_PAUSED = "TestApp media is paused";
+
+    private MediaSession mMediaSession;
+    private final PlaybackState.Builder mPlaybackStateBuilder = new PlaybackState.Builder()
+            .setActions(ACTION_PLAY_PAUSE | ACTION_STOP)
+            .setState(STATE_STOPPED, 0, 1f);
+    private PlaybackState mPlaybackState = mPlaybackStateBuilder.build();
+    private final MediaMetadata.Builder mMediaMetadataBuilder = new MediaMetadata.Builder();
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        WindowManager.LayoutParams p = getWindow().getAttributes();
-        p.layoutInDisplayCutoutMode = WindowManager.LayoutParams
-                .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
-        getWindow().setAttributes(p);
-        setContentView(R.layout.activity_pip);
-        Button enterPip = (Button) findViewById(R.id.enter_pip);
 
-        PictureInPictureParams params = new PictureInPictureParams.Builder()
+        final Window window = getWindow();
+        final WindowManager.LayoutParams layoutParams = window.getAttributes();
+        layoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams
+                .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+        window.setAttributes(layoutParams);
+
+        setContentView(R.layout.activity_pip);
+
+        final PictureInPictureParams pipParams = new PictureInPictureParams.Builder()
                 .setAspectRatio(new Rational(1, 1))
                 .setSourceRectHint(new Rect(0, 0, 100, 100))
                 .build();
+        findViewById(R.id.enter_pip).setOnClickListener(v -> enterPictureInPictureMode(pipParams));
 
-        enterPip.setOnClickListener((v) -> enterPictureInPictureMode(params));
+        findViewById(R.id.media_session_start)
+                .setOnClickListener(v -> updateMediaSessionState(STATE_PLAYING));
+        findViewById(R.id.media_session_stop)
+                .setOnClickListener(v -> updateMediaSessionState(STATE_STOPPED));
+
+        mMediaSession = new MediaSession(this, "WMShell_TestApp");
+        mMediaSession.setPlaybackState(mPlaybackStateBuilder.build());
+        mMediaSession.setCallback(new MediaSession.Callback() {
+            @Override
+            public void onPlay() {
+                updateMediaSessionState(STATE_PLAYING);
+            }
+
+            @Override
+            public void onPause() {
+                updateMediaSessionState(STATE_PAUSED);
+            }
+
+            @Override
+            public void onStop() {
+                updateMediaSessionState(STATE_STOPPED);
+            }
+        });
+    }
+
+    private void updateMediaSessionState(int newState) {
+        if (mPlaybackState.getState() == newState) {
+            return;
+        }
+        final String title;
+        switch (newState) {
+            case STATE_PLAYING:
+                title = TITLE_STATE_PLAYING;
+                break;
+            case STATE_PAUSED:
+                title = TITLE_STATE_PAUSED;
+                break;
+            case STATE_STOPPED:
+                title = "";
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unknown state " + newState);
+        }
+
+        mPlaybackStateBuilder.setState(newState, 0, 1f);
+        mPlaybackState = mPlaybackStateBuilder.build();
+
+        mMediaMetadataBuilder.putText(METADATA_KEY_TITLE, title);
+
+        mMediaSession.setPlaybackState(mPlaybackState);
+        mMediaSession.setMetadata(mMediaMetadataBuilder.build());
+        mMediaSession.setActive(newState != STATE_STOPPED);
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml b/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml
index a8f795e..59d9104 100644
--- a/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml
@@ -22,6 +22,13 @@
     <application android:debuggable="true" android:largeHeap="true">
         <uses-library android:name="android.test.mock" />
         <uses-library android:name="android.test.runner" />
+
+        <activity android:name=".bubbles.BubblesTestActivity"
+            android:allowEmbedded="true"
+            android:documentLaunchMode="always"
+            android:excludeFromRecents="true"
+            android:exported="false"
+            android:resizeableActivity="true" />
     </application>
 
     <instrumentation
diff --git a/libs/WindowManager/Shell/tests/unittest/res/layout/main.xml b/libs/WindowManager/Shell/tests/unittest/res/layout/main.xml
new file mode 100644
index 0000000..0d09f86
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/res/layout/main.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="this is a test activity"
+    />
+    <EditText
+        android:layout_height="wrap_content"
+        android:id="@+id/editText1"
+        android:layout_width="match_parent">
+        <requestFocus></requestFocus>
+    </EditText>
+</LinearLayout>
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
similarity index 79%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTestCase.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
index fdebe4e..5bdf831 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTestCase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTestCase.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.pip;
+package com.android.wm.shell;
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
@@ -24,17 +24,18 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import org.junit.After;
 import org.junit.Before;
 
 /**
- * Base class that does One Handed specific setup.
+ * Base class that does shell test case setup.
  */
-public abstract class PipTestCase {
+public abstract class ShellTestCase {
 
     protected TestableContext mContext;
 
     @Before
-    public void setup() {
+    public void shellSetup() {
         final Context context =
                 InstrumentationRegistry.getInstrumentation().getTargetContext();
         final DisplayManager dm = context.getSystemService(DisplayManager.class);
@@ -47,6 +48,14 @@
                 .adoptShellPermissionIdentity();
     }
 
+    @After
+    public void shellTearDown() {
+        InstrumentationRegistry
+                .getInstrumentation()
+                .getUiAutomation()
+                .dropShellPermissionIdentity();
+    }
+
     protected Context getContext() {
         return mContext;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TaskViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/TaskViewTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
index 5c14859..34f772f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TaskViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 
@@ -30,7 +30,6 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
@@ -45,8 +44,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.SysuiTestCase;
-import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.HandlerExecutor;
 
 import org.junit.After;
@@ -60,8 +57,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-// TODO: Place in com.android.wm.shell vs. com.android.wm.shell.bubbles on shell migration.
-public class TaskViewTest extends SysuiTestCase {
+public class TaskViewTest extends ShellTestCase {
 
     @Mock
     TaskView.Listener mViewListener;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 31c08ae..7adc411 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
@@ -38,8 +38,8 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.BubbleData.TimeSource;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.bubbles.BubbleData.TimeSource;
 
 import com.google.common.collect.ImmutableList;
 
@@ -63,7 +63,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class BubbleDataTest extends SysuiTestCase {
+public class BubbleDataTest extends ShellTestCase {
 
     private BubbleEntry mEntryA1;
     private BubbleEntry mEntryA2;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
similarity index 93%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
index fd6e2ee..5b77e4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleFlyoutViewTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotSame;
@@ -30,8 +30,8 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -42,7 +42,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class BubbleFlyoutViewTest extends SysuiTestCase {
+public class BubbleFlyoutViewTest extends ShellTestCase {
     private BubbleFlyoutView mFlyout;
     private TextView mFlyoutText;
     private TextView mSenderName;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
index 690a1ad..0693052 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -37,8 +37,8 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,7 +49,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-public class BubbleTest extends SysuiTestCase {
+public class BubbleTest extends ShellTestCase {
     @Mock
     private Notification mNotif;
     @Mock
@@ -72,7 +72,7 @@
         Intent target = new Intent(mContext, BubblesTestActivity.class);
         Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder(
                 PendingIntent.getActivity(mContext, 0, target, 0),
-                        Icon.createWithResource(mContext, R.drawable.android))
+                        Icon.createWithResource(mContext, R.drawable.bubble_ic_create_bubble))
                 .build();
         when(mSbn.getNotification()).thenReturn(mNotif);
         when(mNotif.getBubbleMetadata()).thenReturn(metadata);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesTestActivity.java
similarity index 80%
copy from packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
copy to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesTestActivity.java
index 43d2ad1..d5fbe55 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesTestActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,21 +14,20 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.wm.shell.bubbles;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 
-import com.android.systemui.R;
+import com.android.wm.shell.R;
 
 /**
  * Referenced by NotificationTestHelper#makeBubbleMetadata
  */
 public class BubblesTestActivity extends Activity {
 
-    public static final String BUBBLE_ACTIVITY_OPENED =
-            "com.android.systemui.bubbles.BUBBLE_ACTIVITY_OPENED";
+    public static final String BUBBLE_ACTIVITY_OPENED = "BUBBLE_ACTIVITY_OPENED";
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
similarity index 96%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
index a5bb8ea..9c4f341 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
@@ -34,8 +34,8 @@
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
-import com.android.systemui.bubbles.BubblePositioner;
+import com.android.wm.shell.R;
+import com.android.wm.shell.bubbles.BubblePositioner;
 
 import org.junit.Before;
 import org.junit.Ignore;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTest.java
index 498330c..c4edbb2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTestCase.java
similarity index 97%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTestCase.java
index a5f2e8b..a7a7db8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTestCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import static org.mockito.Mockito.when;
 
@@ -30,8 +30,8 @@
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.mockito.Mock;
@@ -50,7 +50,7 @@
  *
  * See physics-animation-testing.md.
  */
-public class PhysicsAnimationLayoutTestCase extends SysuiTestCase {
+public class PhysicsAnimationLayoutTestCase extends ShellTestCase {
     TestablePhysicsAnimationLayout mLayout;
     List<View> mViews = new ArrayList<>();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/StackAnimationControllerTest.java
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/StackAnimationControllerTest.java
index 7d0abec..6b01462 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/StackAnimationControllerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.animation;
+package com.android.wm.shell.bubbles.animation;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
@@ -33,8 +33,8 @@
 import androidx.dynamicanimation.animation.SpringForce;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
-import com.android.systemui.bubbles.BubblePositioner;
+import com.android.wm.shell.R;
+import com.android.wm.shell.bubbles.BubblePositioner;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubblePersistentRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
similarity index 92%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubblePersistentRepositoryTest.kt
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
index 9b8fd11..4160280 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubblePersistentRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.storage
+package com.android.wm.shell.bubbles.storage
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
+import com.android.wm.shell.ShellTestCase
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertNotNull
 import junit.framework.Assert.assertTrue
@@ -28,7 +28,7 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
-class BubblePersistentRepositoryTest : SysuiTestCase() {
+class BubblePersistentRepositoryTest : ShellTestCase() {
 
     private val bubbles = listOf(
             BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
similarity index 96%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
index 7ea611c..4fab9a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.storage
+package com.android.wm.shell.bubbles.storage
 
 import android.content.pm.LauncherApps
 import android.os.UserHandle
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.eq
+import com.android.wm.shell.ShellTestCase
 import junit.framework.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
@@ -32,7 +32,7 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
-class BubbleVolatileRepositoryTest : SysuiTestCase() {
+class BubbleVolatileRepositoryTest : ShellTestCase() {
 
     private val user0 = UserHandle.of(0)
     private val user10 = UserHandle.of(10)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt
index 8cf4534..e0891a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles.storage
+package com.android.wm.shell.bubbles.storage
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
+import com.android.wm.shell.ShellTestCase
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertTrue
 import org.junit.Test
@@ -28,7 +28,7 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
-class BubbleXmlHelperTest : SysuiTestCase() {
+class BubbleXmlHelperTest : ShellTestCase() {
 
     private val bubbles = listOf(
             BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
new file mode 100644
index 0000000..affd736
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
@@ -0,0 +1,358 @@
+/*
+ * 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.
+ */
+
+package com.android.wm.shell.draganddrop;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
+import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
+
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_FULLSCREEN;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
+
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+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.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManager;
+import android.app.IActivityTaskManager;
+import android.app.PendingIntent;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.view.DisplayInfo;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.draganddrop.DragAndDropPolicy.Target;
+import com.android.wm.shell.splitscreen.DividerView;
+import com.android.wm.shell.splitscreen.SplitScreen;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+
+/**
+ * Tests for the drag and drop policy.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DragAndDropPolicyTest {
+
+    @Mock
+    private Context mContext;
+
+    @Mock
+    private IActivityTaskManager mIActivityTaskManager;
+
+    @Mock
+    private SplitScreen mSplitScreen;
+
+    @Mock
+    private DragAndDropPolicy.Starter mStarter;
+
+    private DisplayLayout mDisplayLayout;
+    private Insets mInsets;
+    private DragAndDropPolicy mPolicy;
+
+    private ClipData mActivityClipData;
+    private ClipData mNonResizeableActivityClipData;
+    private ClipData mTaskClipData;
+    private ClipData mShortcutClipData;
+
+    private ActivityManager.RunningTaskInfo mHomeTask;
+    private ActivityManager.RunningTaskInfo mFullscreenAppTask;
+    private ActivityManager.RunningTaskInfo mNonResizeableFullscreenAppTask;
+    private ActivityManager.RunningTaskInfo mSplitPrimaryAppTask;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+
+        Resources res = mock(Resources.class);
+        Configuration config = new Configuration();
+        doReturn(config).when(res).getConfiguration();
+        DisplayInfo info = new DisplayInfo();
+        info.logicalWidth = 100;
+        info.logicalHeight = 100;
+        mDisplayLayout = new DisplayLayout(info, res, false, false);
+        mInsets = Insets.of(0, 0, 0, 0);
+
+        DividerView divider = mock(DividerView.class);
+        doReturn(divider).when(mSplitScreen).getDividerView();
+        doReturn(new Rect(50, 0, 100, 100)).when(divider)
+                .getNonMinimizedSplitScreenSecondaryBounds();
+
+        mPolicy = new DragAndDropPolicy(mContext, mIActivityTaskManager, mSplitScreen, mStarter);
+        mActivityClipData = createClipData(MIMETYPE_APPLICATION_ACTIVITY);
+        mNonResizeableActivityClipData = createClipData(MIMETYPE_APPLICATION_ACTIVITY);
+        setClipDataResizeable(mNonResizeableActivityClipData, false);
+        mTaskClipData = createClipData(MIMETYPE_APPLICATION_TASK);
+        mShortcutClipData = createClipData(MIMETYPE_APPLICATION_SHORTCUT);
+
+        mHomeTask = createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
+        mFullscreenAppTask = createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        mNonResizeableFullscreenAppTask =
+                createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        mNonResizeableFullscreenAppTask.isResizeable = false;
+        mSplitPrimaryAppTask = createTaskInfo(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
+                ACTIVITY_TYPE_STANDARD);
+
+        setIsPhone(false);
+        setInSplitScreen(false);
+        setRunningTask(mFullscreenAppTask);
+    }
+
+    /**
+     * Creates a clip data that is by default resizeable.
+     */
+    private ClipData createClipData(String mimeType) {
+        ClipDescription clipDescription = new ClipDescription(mimeType, new String[] { mimeType });
+        Intent i = new Intent();
+        switch (mimeType) {
+            case MIMETYPE_APPLICATION_SHORTCUT:
+                i.putExtra(Intent.EXTRA_PACKAGE_NAME, "package");
+                i.putExtra(Intent.EXTRA_SHORTCUT_ID, "shortcut_id");
+                break;
+            case MIMETYPE_APPLICATION_TASK:
+                i.putExtra(Intent.EXTRA_TASK_ID, 12345);
+                break;
+            case MIMETYPE_APPLICATION_ACTIVITY:
+                i.putExtra(ClipDescription.EXTRA_PENDING_INTENT, mock(PendingIntent.class));
+                break;
+        }
+        i.putExtra(Intent.EXTRA_USER, android.os.Process.myUserHandle());
+        ClipData.Item item = new ClipData.Item(i);
+        item.setActivityInfo(new ActivityInfo());
+        ClipData data = new ClipData(clipDescription, item);
+        setClipDataResizeable(data, true);
+        return data;
+    }
+
+    private ActivityManager.RunningTaskInfo createTaskInfo(int winMode, int actType) {
+        ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
+        info.configuration.windowConfiguration.setActivityType(actType);
+        info.configuration.windowConfiguration.setWindowingMode(winMode);
+        info.isResizeable = true;
+        return info;
+    }
+
+    private void setRunningTask(ActivityManager.RunningTaskInfo task) throws RemoteException {
+        doReturn(Collections.singletonList(task)).when(mIActivityTaskManager)
+                .getFilteredTasks(anyInt(), anyBoolean());
+    }
+
+    private void setClipDataResizeable(ClipData data, boolean resizeable) {
+        data.getItemAt(0).getActivityInfo().resizeMode = resizeable
+                ? ActivityInfo.RESIZE_MODE_RESIZEABLE
+                : ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+    }
+
+    private void setIsPhone(boolean isPhone) {
+        Resources res = mock(Resources.class);
+        Configuration config = mock(Configuration.class);
+        config.smallestScreenWidthDp = isPhone ? 400 : 800;
+        doReturn(config).when(res).getConfiguration();
+        doReturn(res).when(mContext).getResources();
+    }
+
+    private void setInSplitScreen(boolean inSplitscreen) {
+        doReturn(inSplitscreen).when(mSplitScreen).isDividerVisible();
+    }
+
+    @Test
+    public void testDragAppOverFullscreenHome_expectOnlyFullscreenTarget() throws RemoteException {
+        setRunningTask(mHomeTask);
+        mPolicy.start(mDisplayLayout, mActivityClipData);
+        ArrayList<Target> targets = assertExactTargetTypes(
+                mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+    }
+
+    @Test
+    public void testDragAppOverFullscreenApp_expectSplitScreenAndFullscreenTargets()
+            throws RemoteException {
+        setRunningTask(mFullscreenAppTask);
+        mPolicy.start(mDisplayLayout, mActivityClipData);
+        // TODO(b/169894807): For now, only allow splitting to the right/bottom until we have split
+        //                    pairs
+        ArrayList<Target> targets = assertExactTargetTypes(
+                mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_RIGHT);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+        reset(mStarter);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), mActivityClipData);
+        verify(mStarter).enterSplitScreen(anyInt(), eq(false));
+        verify(mStarter).startIntent(any(), any());
+    }
+
+    @Test
+    public void testDragAppOverFullscreenAppPhone_expectVerticalSplitScreenAndFullscreenTargets()
+            throws RemoteException {
+        setIsPhone(true);
+        setRunningTask(mFullscreenAppTask);
+        mPolicy.start(mDisplayLayout, mActivityClipData);
+        // TODO(b/169894807): For now, only allow splitting to the right/bottom until we have split
+        //                    pairs
+        ArrayList<Target> targets = assertExactTargetTypes(
+                mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_BOTTOM);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+        reset(mStarter);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM), mActivityClipData);
+        verify(mStarter).enterSplitScreen(anyInt(), eq(false));
+        verify(mStarter).startIntent(any(), any());
+    }
+
+    @Test
+    public void testDragAppOverFullscreenNonResizeableApp_expectOnlyFullscreenTargets()
+            throws RemoteException {
+        setRunningTask(mNonResizeableFullscreenAppTask);
+        mPolicy.start(mDisplayLayout, mActivityClipData);
+        ArrayList<Target> targets = assertExactTargetTypes(
+                mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+    }
+
+    @Test
+    public void testDragNonResizeableAppOverFullscreenApp_expectOnlyFullscreenTargets()
+            throws RemoteException {
+        setRunningTask(mFullscreenAppTask);
+        mPolicy.start(mDisplayLayout, mNonResizeableActivityClipData);
+        ArrayList<Target> targets = assertExactTargetTypes(
+                mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+    }
+
+    @Test
+    public void testDragAppOverSplitApp_expectFullscreenAndSplitTargets() throws RemoteException {
+        setInSplitScreen(true);
+        setRunningTask(mSplitPrimaryAppTask);
+        mPolicy.start(mDisplayLayout, mActivityClipData);
+        // TODO(b/169894807): For now, only allow splitting to the right/bottom until we have split
+        //                    pairs
+        ArrayList<Target> targets = assertExactTargetTypes(
+                mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_RIGHT);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+        reset(mStarter);
+
+        // TODO(b/169894807): Just verify starting for the non-docked task until we have app pairs
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+    }
+
+    @Test
+    public void testDragAppOverSplitAppPhone_expectFullscreenAndVerticalSplitTargets()
+            throws RemoteException {
+        setIsPhone(true);
+        setInSplitScreen(true);
+        setRunningTask(mSplitPrimaryAppTask);
+        mPolicy.start(mDisplayLayout, mActivityClipData);
+        // TODO(b/169894807): For now, only allow splitting to the right/bottom until we have split
+        //                    pairs
+        ArrayList<Target> targets = assertExactTargetTypes(
+                mPolicy.getTargets(mInsets), TYPE_FULLSCREEN, TYPE_SPLIT_BOTTOM);
+
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+        reset(mStarter);
+
+        // TODO(b/169894807): Just verify starting for the non-docked task until we have app pairs
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM), mActivityClipData);
+        verify(mStarter).startIntent(any(), any());
+    }
+
+    @Test
+    public void testTargetHitRects() throws RemoteException {
+        setRunningTask(mFullscreenAppTask);
+        mPolicy.start(mDisplayLayout, mActivityClipData);
+        ArrayList<Target> targets = mPolicy.getTargets(mInsets);
+        for (Target t : targets) {
+            assertTrue(mPolicy.getTargetAtLocation(t.hitRegion.left, t.hitRegion.top) == t);
+            assertTrue(mPolicy.getTargetAtLocation(t.hitRegion.right - 1, t.hitRegion.top) == t);
+            assertTrue(mPolicy.getTargetAtLocation(t.hitRegion.right - 1, t.hitRegion.bottom - 1)
+                    == t);
+            assertTrue(mPolicy.getTargetAtLocation(t.hitRegion.left, t.hitRegion.bottom - 1)
+                    == t);
+        }
+    }
+
+    private Target filterTargetByType(ArrayList<Target> targets, int type) {
+        for (Target t : targets) {
+            if (type == t.type) {
+                return t;
+            }
+        }
+        fail("Target with type: " + type + " not found");
+        return null;
+    }
+
+    private ArrayList<Target> assertExactTargetTypes(ArrayList<Target> targets,
+            int... expectedTargetTypes) {
+        HashSet<Integer> expected = new HashSet<>();
+        for (int t : expectedTargetTypes) {
+            expected.add(t);
+        }
+        for (Target t : targets) {
+            if (!expected.contains(t.type)) {
+                fail("Found unexpected target type: " + t.type);
+            }
+            expected.remove(t.type);
+        }
+        assertTrue(expected.isEmpty());
+        return targets;
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
index c7ae2a0..73a9534 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
@@ -46,6 +46,8 @@
 
     @Before
     public void setupSettings() {
+        assumeTrue(SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false));
+
         final Context testContext =
                 InstrumentationRegistry.getInstrumentation().getTargetContext();
         final DisplayManager dm = testContext.getSystemService(DisplayManager.class);
@@ -74,13 +76,13 @@
                 Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 1);
     }
 
-    @Before
-    public void assumeOneHandedModeSupported() {
-        assumeTrue(SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false));
-    }
-
     @After
     public void restoreSettings() {
+        if (mContext == null) {
+            // Return early if one-handed mode is not supported
+            return;
+        }
+
         Settings.Secure.putInt(getContext().getContentResolver(),
                 Settings.Secure.ONE_HANDED_MODE_ENABLED, sOrigEnabled ? 1 : 0);
         Settings.Secure.putInt(mContext.getContentResolver(),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index 255e749..55e7a35 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -32,9 +32,7 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.wm.shell.pip.PipAnimationController;
-import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
-import com.android.wm.shell.pip.PipTestCase;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,7 +47,7 @@
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class PipAnimationControllerTest extends PipTestCase {
+public class PipAnimationControllerTest extends ShellTestCase {
 
     private PipAnimationController mPipAnimationController;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
index 37421d9..a3eaac4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
@@ -30,8 +30,7 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.wm.shell.pip.PipBoundsHandler;
-import com.android.wm.shell.pip.PipTestCase;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,7 +45,7 @@
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class PipBoundsHandlerTest extends PipTestCase {
+public class PipBoundsHandlerTest extends ShellTestCase {
     private static final int ROUNDING_ERROR_MARGIN = 16;
     private static final float ASPECT_RATIO_ERROR_MARGIN = 0.01f;
     private static final float DEFAULT_ASPECT_RATIO = 1f;
@@ -62,7 +61,7 @@
     @Before
     public void setUp() throws Exception {
         initializeMockResources();
-        mPipBoundsState = new PipBoundsState();
+        mPipBoundsState = new PipBoundsState(mContext);
         mPipBoundsHandler = new PipBoundsHandler(mContext, mPipBoundsState);
 
         mPipBoundsState.setDisplayInfo(mDefaultDisplayInfo);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
index dc9399e..5e11de7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
@@ -28,6 +28,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.ShellTestCase;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,7 +40,7 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 @SmallTest
-public class PipBoundsStateTest extends PipTestCase {
+public class PipBoundsStateTest extends ShellTestCase {
 
     private static final Rect DEFAULT_BOUNDS = new Rect(0, 0, 10, 10);
     private static final float DEFAULT_SNAP_FRACTION = 1.0f;
@@ -49,7 +51,7 @@
 
     @Before
     public void setUp() {
-        mPipBoundsState = new PipBoundsState();
+        mPipBoundsState = new PipBoundsState(mContext);
         mTestComponentName1 = new ComponentName(mContext, "component1");
         mTestComponentName2 = new ComponentName(mContext, "component2");
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 39381c6..f4143f6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -40,6 +40,7 @@
 import android.window.WindowContainerToken;
 
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.pip.phone.PipMenuActivityController;
 import com.android.wm.shell.splitscreen.SplitScreen;
@@ -58,7 +59,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-public class PipTaskOrganizerTest extends PipTestCase {
+public class PipTaskOrganizerTest extends ShellTestCase {
     private PipTaskOrganizer mSpiedPipTaskOrganizer;
 
     @Mock private DisplayController mMockdDisplayController;
@@ -78,7 +79,7 @@
         MockitoAnnotations.initMocks(this);
         mComponent1 = new ComponentName(mContext, "component1");
         mComponent2 = new ComponentName(mContext, "component2");
-        mPipBoundsState = new PipBoundsState();
+        mPipBoundsState = new PipBoundsState(mContext);
         mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipBoundsState,
                 mMockPipBoundsHandler, mMenuActivityController, mMockPipSurfaceTransactionHelper,
                 mMockOptionalSplitScreen, mMockdDisplayController, mMockPipUiEventLogger,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 5f0f196..a00a3b6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -35,6 +35,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.ShellExecutor;
@@ -42,7 +43,6 @@
 import com.android.wm.shell.pip.PipBoundsState;
 import com.android.wm.shell.pip.PipMediaController;
 import com.android.wm.shell.pip.PipTaskOrganizer;
-import com.android.wm.shell.pip.PipTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -56,7 +56,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-public class PipControllerTest extends PipTestCase {
+public class PipControllerTest extends ShellTestCase {
     private PipController mPipController;
 
     @Mock private DisplayController mMockDisplayController;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index 3f60cc0..94f3051 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -31,17 +31,13 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.pip.PipBoundsHandler;
 import com.android.wm.shell.pip.PipBoundsState;
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.PipTaskOrganizer;
-import com.android.wm.shell.pip.PipTestCase;
 import com.android.wm.shell.pip.PipUiEventLogger;
-import com.android.wm.shell.pip.phone.PipMenuActivityController;
-import com.android.wm.shell.pip.phone.PipMotionHelper;
-import com.android.wm.shell.pip.phone.PipResizeGestureHandler;
-import com.android.wm.shell.pip.phone.PipTouchHandler;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -59,7 +55,7 @@
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class PipTouchHandlerTest extends PipTestCase {
+public class PipTouchHandlerTest extends ShellTestCase {
 
     private PipTouchHandler mPipTouchHandler;
 
@@ -92,7 +88,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mPipBoundsState = new PipBoundsState();
+        mPipBoundsState = new PipBoundsState(mContext);
         mPipBoundsHandler = new PipBoundsHandler(mContext, mPipBoundsState);
         mPipSnapAlgorithm = mPipBoundsHandler.getSnapAlgorithm();
         mPipSnapAlgorithm = new PipSnapAlgorithm(mContext);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java
index 40667f7..000f7e8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java
@@ -35,8 +35,7 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.wm.shell.pip.PipTestCase;
-import com.android.wm.shell.pip.phone.PipTouchState;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +46,7 @@
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
 @RunWithLooper
-public class PipTouchStateTest extends PipTestCase {
+public class PipTouchStateTest extends ShellTestCase {
 
     private PipTouchState mTouchState;
     private CountDownLatch mDoubleTapCallbackTriggeredLatch;
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 903ca2a..a3fcf90 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -160,10 +160,17 @@
                 "tests/ObbFile_test.cpp",
                 "tests/PosixUtils_test.cpp",
             ],
-            shared_libs: common_test_libs + ["libbinder", "liblog", "libui"],
+            shared_libs: common_test_libs + [
+                "libbinder",
+                "liblog",
+                "libui",
+            ],
         },
         host: {
-            static_libs: common_test_libs + ["liblog", "libz"],
+            static_libs: common_test_libs + [
+                "liblog",
+                "libz",
+            ],
         },
     },
     data: [
@@ -204,10 +211,20 @@
     export_include_dirs: ["include"],
     target: {
         android: {
-            shared_libs: common_test_libs + ["libbinder", "liblog"],
+            shared_libs: common_test_libs + [
+                "libbinder",
+                "liblog",
+            ],
         },
         host: {
-            static_libs: common_test_libs + ["libbinder", "liblog"],
+            static_libs: common_test_libs + [
+                "libbinder",
+                "liblog",
+            ],
+        },
+        darwin: {
+            // libbinder is not supported on mac
+            enabled: false,
         },
     },
 }
diff --git a/libs/androidfw/fuzz/cursorwindow_fuzzer/Android.bp b/libs/androidfw/fuzz/cursorwindow_fuzzer/Android.bp
index 2dac47b..b36ff09 100644
--- a/libs/androidfw/fuzz/cursorwindow_fuzzer/Android.bp
+++ b/libs/androidfw/fuzz/cursorwindow_fuzzer/Android.bp
@@ -27,5 +27,9 @@
                 "libutils",
             ],
         },
+        darwin: {
+            // libbinder is not supported on mac
+            enabled: false,
+        },
     },
 }
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 155bb6b..4ed5457 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -429,6 +429,8 @@
     whole_static_libs: ["libskia"],
 
     srcs: [
+        "canvas/CanvasOpBuffer.cpp",
+        "canvas/CanvasOpRasterizer.cpp",
         "pipeline/skia/SkiaDisplayList.cpp",
         "pipeline/skia/SkiaRecordingCanvas.cpp",
         "pipeline/skia/RenderNodeDrawable.cpp",
@@ -604,6 +606,7 @@
         "tests/unit/ABitmapTests.cpp",
         "tests/unit/CacheManagerTests.cpp",
         "tests/unit/CanvasContextTests.cpp",
+        "tests/unit/CanvasOpTests.cpp",
         "tests/unit/CommonPoolTests.cpp",
         "tests/unit/DamageAccumulatorTests.cpp",
         "tests/unit/DeferredLayerUpdaterTests.cpp",
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt b/libs/hwui/canvas/CanvasOpBuffer.cpp
similarity index 63%
copy from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
copy to libs/hwui/canvas/CanvasOpBuffer.cpp
index 24768cd..7054e47e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
+++ b/libs/hwui/canvas/CanvasOpBuffer.cpp
@@ -13,17 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
 
-import android.annotation.DimenRes
-import android.annotation.UserIdInt
+#include "CanvasOpBuffer.h"
 
-data class BubbleEntity(
-    @UserIdInt val userId: Int,
-    val packageName: String,
-    val shortcutId: String,
-    val key: String,
-    val desiredHeight: Int,
-    @DimenRes val desiredHeightResId: Int,
-    val title: String? = null
-)
+#include "CanvasOps.h"
+
+namespace android::uirenderer {
+
+template class OpBuffer<CanvasOpType, CanvasOpContainer>;
+
+}  // namespace android::uirenderer
diff --git a/libs/hwui/canvas/CanvasOpBuffer.h b/libs/hwui/canvas/CanvasOpBuffer.h
new file mode 100644
index 0000000..b80faeb
--- /dev/null
+++ b/libs/hwui/canvas/CanvasOpBuffer.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <SkMatrix.h>
+
+#include "CanvasOpTypes.h"
+#include "OpBuffer.h"
+
+namespace android::uirenderer {
+
+template <CanvasOpType T>
+struct CanvasOp;
+
+template <CanvasOpType T>
+class CanvasOpContainer {
+private:
+    BE_OPBUFFERS_FRIEND();
+
+    OpBufferItemHeader<CanvasOpType> header;
+    // TODO: Figure out some magic to make this not be here when it's identity (or not used)
+    SkMatrix mTransform;
+    CanvasOp<T> mImpl;
+
+public:
+    CanvasOpContainer(CanvasOp<T>&& impl, const SkMatrix& transform = SkMatrix::I())
+            : mTransform(transform), mImpl(std::move(impl)) {}
+
+    uint32_t size() const { return header.size; }
+    CanvasOpType type() const { return header.type; }
+
+    const SkMatrix& transform() const { return mTransform; }
+
+    CanvasOp<T>* operator->() noexcept { return &mImpl; }
+};
+
+extern template class OpBuffer<CanvasOpType, CanvasOpContainer>;
+class CanvasOpBuffer final : public OpBuffer<CanvasOpType, CanvasOpContainer> {
+public:
+    template <CanvasOpType T>
+    void push(CanvasOp<T>&& op) {
+        push_container(CanvasOpContainer<T>(std::move(op)));
+    }
+};
+
+}  // namespace android::uirenderer
diff --git a/libs/hwui/canvas/CanvasOpRasterizer.cpp b/libs/hwui/canvas/CanvasOpRasterizer.cpp
new file mode 100644
index 0000000..97c418a
--- /dev/null
+++ b/libs/hwui/canvas/CanvasOpRasterizer.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#include "CanvasOpRasterizer.h"
+
+#include <SkCanvas.h>
+#include <log/log.h>
+
+#include <vector>
+
+#include "CanvasOpBuffer.h"
+#include "CanvasOps.h"
+
+namespace android::uirenderer {
+
+void rasterizeCanvasBuffer(const CanvasOpBuffer& source, SkCanvas* destination) {
+    // Tracks the global transform from the current display list back toward the display space
+    // Push on beginning a RenderNode draw, pop on ending one
+    std::vector<SkMatrix> globalMatrixStack;
+    SkMatrix& currentGlobalTransform = globalMatrixStack.emplace_back(SkMatrix::I());
+
+    source.for_each([&]<CanvasOpType T>(CanvasOpContainer<T> * op) {
+        if constexpr (T == CanvasOpType::BeginZ || T == CanvasOpType::EndZ) {
+            // Do beginZ or endZ
+            LOG_ALWAYS_FATAL("TODO");
+            return;
+        } else {
+            // Generic OP
+            // First apply the current transformation
+            destination->setMatrix(SkMatrix::Concat(currentGlobalTransform, op->transform()));
+            // Now draw it
+            (*op)->draw(destination);
+        }
+    });
+}
+
+}  // namespace android::uirenderer
diff --git a/libs/hwui/canvas/CanvasOpRasterizer.h b/libs/hwui/canvas/CanvasOpRasterizer.h
new file mode 100644
index 0000000..c2235ab
--- /dev/null
+++ b/libs/hwui/canvas/CanvasOpRasterizer.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <hwui/Bitmap.h>
+
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+
+#include "CanvasOps.h"
+
+#include <experimental/type_traits>
+#include <variant>
+
+namespace android::uirenderer {
+
+class CanvasOpBuffer;
+
+void rasterizeCanvasBuffer(const CanvasOpBuffer& source, SkCanvas* destination);
+
+class ImmediateModeRasterizer {
+public:
+    explicit ImmediateModeRasterizer(std::unique_ptr<SkCanvas>&& canvas) {
+        mCanvas = canvas.get();
+        mOwnership = std::move(canvas);
+    }
+
+    explicit ImmediateModeRasterizer(std::shared_ptr<SkCanvas> canvas) {
+        mCanvas = canvas.get();
+        mOwnership = std::move(canvas);
+    }
+
+    explicit ImmediateModeRasterizer(Bitmap& bitmap) {
+        mCanvas = &(mOwnership.emplace<SkCanvas>(bitmap.getSkBitmap()));
+    }
+
+    template <CanvasOpType T>
+    void draw(const CanvasOp<T>& op) {
+        if constexpr (CanvasOpTraits::can_draw<CanvasOp<T>>) {
+            op.draw(mCanvas);
+        }
+    }
+
+private:
+    SkCanvas* mCanvas;
+    // Just here to keep mCanvas alive. Thankfully we never need to actually look inside this...
+    std::variant<SkCanvas, std::shared_ptr<SkCanvas>, std::unique_ptr<SkCanvas>> mOwnership;
+};
+
+}  // namespace android::uirenderer
diff --git a/libs/hwui/canvas/CanvasOpTypes.h b/libs/hwui/canvas/CanvasOpTypes.h
new file mode 100644
index 0000000..2d4f2f5
--- /dev/null
+++ b/libs/hwui/canvas/CanvasOpTypes.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <inttypes.h>
+
+namespace android::uirenderer {
+
+enum class CanvasOpType : int8_t {
+    // State ops
+    // TODO: Eliminate the end ops by having the start include the end-at position
+    Save,
+    SaveLayer,
+    SaveBehind,
+    Restore,
+    BeginZ,
+    EndZ,
+
+    // Clip ops
+    ClipRect,
+    ClipPath,
+
+    // Drawing ops
+    DrawColor,
+    DrawRect,
+
+    // TODO: Rest
+
+    COUNT  // must be last
+};
+
+}  // namespace android::uirenderer
\ No newline at end of file
diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h
new file mode 100644
index 0000000..a31a91c
--- /dev/null
+++ b/libs/hwui/canvas/CanvasOps.h
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <SkAndroidFrameworkUtils.h>
+#include <SkCanvas.h>
+#include <SkPath.h>
+#include <log/log.h>
+
+#include "CanvasOpTypes.h"
+
+#include <experimental/type_traits>
+
+namespace android::uirenderer {
+
+template <CanvasOpType T>
+struct CanvasOp;
+
+struct CanvasOpTraits {
+    CanvasOpTraits() = delete;
+
+    template<class T>
+    using draw_t = decltype(std::integral_constant<void (T::*)(SkCanvas*) const, &T::draw>{});
+
+    template <class T>
+    static constexpr bool can_draw = std::experimental::is_detected_v<draw_t, T>;
+};
+
+#define ASSERT_DRAWABLE() private: constexpr void _check_drawable() \
+    { static_assert(CanvasOpTraits::can_draw<std::decay_t<decltype(*this)>>); }
+
+// ----------------------------------------------
+//   State Ops
+//  ---------------------------------------------
+
+template <>
+struct CanvasOp<CanvasOpType::Save> {
+    void draw(SkCanvas* canvas) const { canvas->save(); }
+    ASSERT_DRAWABLE()
+};
+
+template <>
+struct CanvasOp<CanvasOpType::SaveLayer> {
+    SkCanvas::SaveLayerRec saveLayerRec;
+    void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
+    ASSERT_DRAWABLE()
+};
+
+template <>
+struct CanvasOp<CanvasOpType::SaveBehind> {
+    SkRect bounds;
+    void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
+    ASSERT_DRAWABLE()
+};
+
+template <>
+struct CanvasOp<CanvasOpType::Restore> {
+    void draw(SkCanvas* canvas) const { canvas->restore(); }
+    ASSERT_DRAWABLE()
+};
+
+template <>
+struct CanvasOp<CanvasOpType::BeginZ> {
+};
+template <>
+struct CanvasOp<CanvasOpType::EndZ> {};
+
+// ----------------------------------------------
+//   Clip Ops
+//  ---------------------------------------------
+
+template <>
+struct CanvasOp<CanvasOpType::ClipRect> {
+    SkRect rect;
+    SkClipOp clipOp;
+    void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
+    ASSERT_DRAWABLE()
+};
+
+template <>
+struct CanvasOp<CanvasOpType::ClipPath> {
+    SkPath path;
+    SkClipOp op;
+    void draw(SkCanvas* canvas) const { canvas->clipPath(path, op, true); }
+    ASSERT_DRAWABLE()
+};
+
+// ----------------------------------------------
+//   Drawing Ops
+//  ---------------------------------------------
+
+template <>
+struct CanvasOp<CanvasOpType::DrawColor> {
+    SkColor4f color;
+    SkBlendMode mode;
+    void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
+    ASSERT_DRAWABLE()
+};
+
+template <>
+struct CanvasOp<CanvasOpType::DrawRect> {
+    SkRect rect;
+    SkPaint paint;
+    void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
+    ASSERT_DRAWABLE()
+};
+
+
+// cleanup our macros
+#undef ASSERT_DRAWABLE
+
+}  // namespace android::uirenderer
\ No newline at end of file
diff --git a/libs/hwui/canvas/OpBuffer.h b/libs/hwui/canvas/OpBuffer.h
new file mode 100644
index 0000000..398e090
--- /dev/null
+++ b/libs/hwui/canvas/OpBuffer.h
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <array>
+#include <cinttypes>
+#include <cstddef>
+#include <cstdlib>
+#include <type_traits>
+#include <utility>
+
+namespace android::uirenderer {
+
+template <typename T>
+struct OpBufferItemHeader {
+    T type : 8;
+    uint32_t size : 24;
+};
+
+struct OpBufferAllocationHeader {
+    // Used size, including header size
+    size_t used = 0;
+    // Capacity, including header size
+    size_t capacity = 0;
+    // Offset relative to `this` at which the first item is
+    size_t startOffset = 0;
+    // Offset relative to `this` at which the last item is
+    size_t endOffset = 0;
+};
+
+#define BE_OPBUFFERS_FRIEND()                                      \
+    template <typename ItemTypes, template <ItemTypes> typename, typename, typename> \
+    friend class OpBuffer
+
+template <typename ItemTypes, template <ItemTypes> typename ItemContainer,
+          typename BufferHeader = OpBufferAllocationHeader,
+          typename ItemTypesSequence = std::make_index_sequence<static_cast<int>(ItemTypes::COUNT)>>
+class OpBuffer {
+    // Instead of re-aligning individual inserts, just pad the size of everything
+    // to a multiple of pointer alignment. This assumes we never work with doubles.
+    // Which we don't.
+    static constexpr size_t Alignment = alignof(void*);
+
+    static constexpr size_t PadAlign(size_t size) {
+        return (size + (Alignment - 1)) & -Alignment;
+    }
+
+    static constexpr auto STARTING_SIZE = PadAlign(sizeof(BufferHeader));
+
+public:
+    using ItemHeader = OpBufferItemHeader<ItemTypes>;
+
+    OpBuffer() = default;
+
+    // Prevent copying by default
+    OpBuffer(const OpBuffer&) = delete;
+    void operator=(const OpBuffer&) = delete;
+
+    OpBuffer(OpBuffer&& other) {
+        mBuffer = other.mBuffer;
+        other.mBuffer = nullptr;
+    }
+
+    void operator=(OpBuffer&& other) {
+        destroy();
+        mBuffer = other.mBuffer;
+        other.mBuffer = nullptr;
+    }
+
+    ~OpBuffer() {
+        destroy();
+    }
+
+    constexpr size_t capacity() const { return mBuffer ? mBuffer->capacity : 0; }
+
+    constexpr size_t size() const { return mBuffer ? mBuffer->used : 0; }
+
+    constexpr size_t remaining() const { return capacity() - size(); }
+
+    // TODO: Add less-copy'ing variants of this. emplace_back? deferred initialization?
+    template <ItemTypes T>
+    void push_container(ItemContainer<T>&& op) {
+        static_assert(alignof(ItemContainer<T>) <= Alignment);
+        static_assert(offsetof(ItemContainer<T>, header) == 0);
+
+        constexpr auto padded_size = PadAlign(sizeof(ItemContainer<T>));
+        if (remaining() < padded_size) {
+            resize(std::max(padded_size, capacity()) * 2);
+        }
+        mBuffer->endOffset = mBuffer->used;
+        mBuffer->used += padded_size;
+
+        void* allocateAt = reinterpret_cast<uint8_t*>(mBuffer) + mBuffer->endOffset;
+        auto temp = new (allocateAt) ItemContainer<T>{std::move(op)};
+        temp->header = {.type = T, .size = padded_size};
+    }
+
+    void resize(size_t newsize) {
+        // Add the header size to newsize
+        const size_t adjustedSize = newsize + STARTING_SIZE;
+
+        if (adjustedSize < size()) {
+            // todo: throw?
+            return;
+        }
+        if (newsize == 0) {
+            free(mBuffer);
+            mBuffer = nullptr;
+        } else {
+            if (mBuffer) {
+                mBuffer = reinterpret_cast<BufferHeader*>(realloc(mBuffer, adjustedSize));
+                mBuffer->capacity = adjustedSize;
+            } else {
+                mBuffer = new (malloc(adjustedSize)) BufferHeader();
+                mBuffer->capacity = adjustedSize;
+                mBuffer->used = STARTING_SIZE;
+                mBuffer->startOffset = STARTING_SIZE;
+            }
+        }
+    }
+
+    template <typename F>
+    void for_each(F&& f) const {
+        for_each(std::forward<F>(f), ItemTypesSequence{});
+    }
+
+    void clear();
+
+    ItemHeader* first() const { return isEmpty() ? nullptr : itemAt(mBuffer->startOffset); }
+
+    ItemHeader* last() const { return isEmpty() ? nullptr : itemAt(mBuffer->endOffset); }
+
+private:
+    template <typename F, std::size_t... I>
+    void for_each(F&& f, std::index_sequence<I...>) const {
+        // Validate we're not empty
+        if (isEmpty()) return;
+
+        // Setup the jump table, mapping from each type to a springboard that invokes the template
+        // function with the appropriate concrete type
+        using F_PTR = decltype(&f);
+        using THUNK = void (*)(F_PTR, void*);
+        static constexpr auto jump = std::array<THUNK, sizeof...(I)>{[](F_PTR fp, void* t) {
+            (*fp)(reinterpret_cast<ItemContainer<static_cast<ItemTypes>(I)>*>(t));
+        }...};
+
+        // Do the actual iteration of each item
+        uint8_t* current = reinterpret_cast<uint8_t*>(mBuffer) + mBuffer->startOffset;
+        uint8_t* end = reinterpret_cast<uint8_t*>(mBuffer) + mBuffer->used;
+        while (current != end) {
+            auto header = reinterpret_cast<ItemHeader*>(current);
+            // `f` could be a destructor, so ensure all accesses to the OP happen prior to invoking
+            // `f`
+            auto it = (void*)current;
+            current += header->size;
+            jump[static_cast<int>(header->type)](&f, it);
+        }
+    }
+
+    void destroy() {
+        clear();
+        resize(0);
+    }
+
+    bool offsetIsValid(size_t offset) const {
+        return offset >= mBuffer->startOffset && offset < mBuffer->used;
+    }
+
+    ItemHeader* itemAt(size_t offset) const {
+        if (!offsetIsValid(offset)) return nullptr;
+        return reinterpret_cast<ItemHeader*>(reinterpret_cast<uint8_t*>(mBuffer) + offset);
+    }
+
+    bool isEmpty() const { return mBuffer == nullptr || mBuffer->used == STARTING_SIZE; }
+
+    BufferHeader* mBuffer = nullptr;
+};
+
+template <typename ItemTypes, template <ItemTypes> typename ItemContainer, typename BufferHeader,
+        typename ItemTypeSequence>
+void OpBuffer<ItemTypes, ItemContainer, BufferHeader, ItemTypeSequence>::clear() {
+
+    // Don't need to do anything if we don't have a buffer
+    if (!mBuffer) return;
+
+    for_each([](auto op) {
+        using T = std::remove_reference_t<decltype(*op)>;
+        op->~T();
+    });
+    mBuffer->used = STARTING_SIZE;
+    mBuffer->startOffset = STARTING_SIZE;
+    mBuffer->endOffset = 0;
+}
+
+}  // namespace android::uirenderer
\ No newline at end of file
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 6ece7ef..94a047c 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -100,6 +100,12 @@
 
     void getSkBitmap(SkBitmap* outBitmap);
 
+    SkBitmap getSkBitmap() {
+        SkBitmap ret;
+        getSkBitmap(&ret);
+        return ret;
+    }
+
     int getAshmemFd() const;
     size_t getAllocationByteCount() const;
 
diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp
index 4aee6b9..21fcd2f 100644
--- a/libs/hwui/jni/fonts/Font.cpp
+++ b/libs/hwui/jni/fonts/Font.cpp
@@ -239,13 +239,10 @@
 }
 
 // Critical Native
-static jboolean Font_isSameBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong lFontHandle,
-                                         jlong rFontHandle) {
-    FontWrapper* lFont = reinterpret_cast<FontWrapper*>(lFontHandle);
-    FontWrapper* rFont = reinterpret_cast<FontWrapper*>(rFontHandle);
-    const void* lBufferPtr = lFont->font->typeface()->GetFontData();
-    const void* rBufferPtr = rFont->font->typeface()->GetFontData();
-    return lBufferPtr == rBufferPtr;
+static jlong Font_GetBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
+    FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
+    const void* bufferPtr = font->font->typeface()->GetFontData();
+    return reinterpret_cast<jlong>(bufferPtr);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -297,7 +294,7 @@
     { "nGetAxisInfo", "(JI)J", (void*) Font_getAxisInfo },
     { "nGetFontPath", "(J)Ljava/lang/String;", (void*) Font_getFontPath },
     { "nGetNativeFontPtr", "(J)J", (void*) Font_getNativeFontPtr },
-    { "nIsSameBufferAddress", "(JJ)Z", (void*) Font_isSameBufferAddress },
+    { "nGetFontBufferAddress", "(J)J", (void*) Font_GetBufferAddress },
 };
 
 static const JNINativeMethod gFontBufferHelperMethods[] = {
diff --git a/libs/hwui/tests/common/CallCountingCanvas.h b/libs/hwui/tests/common/CallCountingCanvas.h
new file mode 100644
index 0000000..a965571
--- /dev/null
+++ b/libs/hwui/tests/common/CallCountingCanvas.h
@@ -0,0 +1,168 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <SkCanvasVirtualEnforcer.h>
+#include <SkNoDrawCanvas.h>
+
+namespace android {
+namespace uirenderer {
+namespace test {
+
+class CallCountingCanvas final : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
+private:
+    int START_MARKER;
+public:
+    CallCountingCanvas() : SkCanvasVirtualEnforcer<SkNoDrawCanvas>(1, 1) {}
+
+    int sumTotalDrawCalls() {
+        // Dirty hack assumes we're nothing but ints between START_MARKET and END_MARKER
+        int* cur = &START_MARKER + 1;
+        int* end = &END_MARKER;
+        int sum = 0;
+        while (cur != end) {
+            sum += *cur;
+            cur++;
+        }
+        return sum;
+    }
+
+    int drawPaintCount = 0;
+    void onDrawPaint(const SkPaint& paint) override {
+        drawPaintCount++;
+    }
+
+    int drawBehindCount = 0;
+    void onDrawBehind(const SkPaint&) override {
+        drawBehindCount++;
+    }
+
+    int drawRectCount = 0;
+    void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
+        drawRectCount++;
+    }
+
+    int drawRRectCount = 0;
+    void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override {
+        drawRRectCount++;
+    }
+
+    int drawDRRectCount = 0;
+    void onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
+                      const SkPaint& paint) override {
+        drawDRRectCount++;
+    }
+
+    int drawOvalCount = 0;
+    void onDrawOval(const SkRect& rect, const SkPaint& paint) override {
+        drawOvalCount++;
+    }
+
+    int drawArcCount = 0;
+    void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
+                   const SkPaint& paint) override {
+        drawArcCount++;
+    }
+
+    int drawPathCount = 0;
+    void onDrawPath(const SkPath& path, const SkPaint& paint) override {
+        drawPaintCount++;
+    }
+
+    int drawRegionCount = 0;
+    void onDrawRegion(const SkRegion& region, const SkPaint& paint) override {
+        drawRegionCount++;
+    }
+
+    int drawTextBlobCount = 0;
+    void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                        const SkPaint& paint) override {
+        drawTextBlobCount++;
+    }
+
+    int drawPatchCount = 0;
+    void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+                     const SkPoint texCoords[4], SkBlendMode mode,
+                     const SkPaint& paint) override {
+        drawPatchCount++;
+    }
+
+    int drawPoints = 0;
+    void onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
+                      const SkPaint& paint) override {
+        drawPoints++;
+    }
+
+    int drawImageCount = 0;
+    void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy,
+                     const SkPaint* paint) override {
+        drawImageCount++;
+    }
+
+    int drawImageRectCount = 0;
+    void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
+                         const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) override {
+        drawImageRectCount++;
+    }
+
+    int drawImageNineCount = 0;
+    void onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
+                         const SkPaint* paint) override {
+        drawImageNineCount++;
+    }
+
+    int drawImageLatticeCount = 0;
+    void onDrawImageLattice(const SkImage* image, const SkCanvas::Lattice& lattice,
+                            const SkRect& dst, const SkPaint* paint) override {
+        drawImageLatticeCount++;
+    }
+
+    int drawAtlasCount = 0;
+    void onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect rect[],
+                     const SkColor colors[], int count, SkBlendMode mode, const SkRect* cull,
+                     const SkPaint* paint) override {
+        drawAtlasCount++;
+    }
+
+    int drawAnnotationCount = 0;
+    void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) override {
+        drawAnnotationCount++;
+    }
+
+    int drawShadowRecCount = 0;
+    void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override {
+        drawShadowRecCount++;
+    }
+
+    int drawDrawableCount = 0;
+    void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
+        drawDrawableCount++;
+    }
+
+    int drawPictureCount = 0;
+    void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+                       const SkPaint* paint) override {
+        drawPictureCount++;
+    }
+
+private:
+    int END_MARKER;
+};
+
+} /* namespace test */
+} /* namespace uirenderer */
+} /* namespace android */
\ No newline at end of file
diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp
new file mode 100644
index 0000000..0815d15
--- /dev/null
+++ b/libs/hwui/tests/unit/CanvasOpTests.cpp
@@ -0,0 +1,209 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <canvas/CanvasOpBuffer.h>
+#include <canvas/CanvasOps.h>
+#include <canvas/CanvasOpRasterizer.h>
+
+#include <tests/common/CallCountingCanvas.h>
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::test;
+
+// We lazy
+using Op = CanvasOpType;
+
+enum MockTypes {
+    Lifecycle,
+    COUNT
+};
+
+template<MockTypes T>
+struct MockOp;
+
+template<MockTypes T>
+struct MockOpContainer {
+    OpBufferItemHeader<MockTypes> header;
+    MockOp<T> impl;
+};
+
+struct LifecycleTracker {
+    int ctor_count = 0;
+    int dtor_count = 0;
+
+    int alive() { return ctor_count - dtor_count; }
+};
+
+template<>
+struct MockOp<MockTypes::Lifecycle> {
+    MockOp() = delete;
+    void operator=(const MockOp&) = delete;
+
+    MockOp(LifecycleTracker* tracker) : tracker(tracker) {
+        tracker->ctor_count += 1;
+    }
+
+    MockOp(const MockOp& other) {
+        tracker = other.tracker;
+        tracker->ctor_count += 1;
+    }
+
+    ~MockOp() {
+        tracker->dtor_count += 1;
+    }
+
+    LifecycleTracker* tracker = nullptr;
+};
+
+using MockBuffer = OpBuffer<MockTypes, MockOpContainer>;
+
+template<typename T>
+static int countItems(const T& t) {
+    int count = 0;
+    t.for_each([&](auto i) {
+        count++;
+    });
+    return count;
+}
+
+TEST(CanvasOp, lifecycleCheck) {
+    LifecycleTracker tracker;
+    {
+        MockBuffer buffer;
+        buffer.push_container(MockOpContainer<MockTypes::Lifecycle> {
+            .impl = MockOp<MockTypes::Lifecycle>{&tracker}
+        });
+        EXPECT_EQ(tracker.alive(), 1);
+        buffer.clear();
+        EXPECT_EQ(tracker.alive(), 0);
+    }
+    EXPECT_EQ(tracker.alive(), 0);
+}
+
+TEST(CanvasOp, lifecycleCheckMove) {
+    LifecycleTracker tracker;
+    {
+        MockBuffer buffer;
+        buffer.push_container(MockOpContainer<MockTypes::Lifecycle> {
+            .impl = MockOp<MockTypes::Lifecycle>{&tracker}
+        });
+        EXPECT_EQ(tracker.alive(), 1);
+        {
+            MockBuffer other(std::move(buffer));
+            EXPECT_EQ(tracker.alive(), 1);
+            EXPECT_EQ(buffer.size(), 0);
+            EXPECT_GT(other.size(), 0);
+            EXPECT_EQ(1, countItems(other));
+            EXPECT_EQ(0, countItems(buffer));
+
+            other.push_container(MockOpContainer<MockTypes::Lifecycle> {
+                .impl = MockOp<MockTypes::Lifecycle>{&tracker}
+            });
+
+            EXPECT_EQ(2, countItems(other));
+            EXPECT_EQ(2, tracker.alive());
+
+            buffer.push_container(MockOpContainer<MockTypes::Lifecycle> {
+                .impl = MockOp<MockTypes::Lifecycle>{&tracker}
+            });
+            EXPECT_EQ(1, countItems(buffer));
+            EXPECT_EQ(3, tracker.alive());
+
+            buffer = std::move(other);
+            EXPECT_EQ(2, countItems(buffer));
+            EXPECT_EQ(2, tracker.alive());
+        }
+        EXPECT_EQ(2, countItems(buffer));
+        EXPECT_EQ(2, tracker.alive());
+        buffer.clear();
+        EXPECT_EQ(0, countItems(buffer));
+        EXPECT_EQ(0, tracker.alive());
+    }
+    EXPECT_EQ(tracker.alive(), 0);
+}
+
+TEST(CanvasOp, simplePush) {
+    CanvasOpBuffer buffer;
+    EXPECT_EQ(buffer.size(), 0);
+    buffer.push<Op::Save>({});
+    buffer.push<Op::Save>({});
+    buffer.push<Op::Restore>({});
+    EXPECT_GT(buffer.size(), 0);
+
+    int saveCount = 0;
+    int restoreCount = 0;
+    int otherCount = 0;
+
+    buffer.for_each([&](auto op) {
+        switch (op->type()) {
+            case Op::Save:
+                saveCount++;
+                break;
+            case Op::Restore:
+                restoreCount++;
+                break;
+            default:
+                otherCount++;
+                break;
+        }
+    });
+
+    EXPECT_EQ(saveCount, 2);
+    EXPECT_EQ(restoreCount, 1);
+    EXPECT_EQ(otherCount, 0);
+
+    buffer.clear();
+    int itemCount = 0;
+    buffer.for_each([&](auto op) {
+        itemCount++;
+    });
+    EXPECT_EQ(itemCount, 0);
+    buffer.resize(0);
+    EXPECT_EQ(buffer.size(), 0);
+}
+
+TEST(CanvasOp, simpleDrawRect) {
+    CanvasOpBuffer buffer;
+    EXPECT_EQ(buffer.size(), 0);
+    buffer.push(CanvasOp<Op::DrawRect> {
+        .paint = SkPaint{},
+        .rect = SkRect::MakeEmpty()
+    });
+
+    CallCountingCanvas canvas;
+    EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+    rasterizeCanvasBuffer(buffer, &canvas);
+    EXPECT_EQ(1, canvas.drawRectCount);
+    EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
+TEST(CanvasOp, immediateRendering) {
+    auto canvas = std::make_shared<CallCountingCanvas>();
+
+    EXPECT_EQ(0, canvas->sumTotalDrawCalls());
+    ImmediateModeRasterizer rasterizer{canvas};
+    auto op = CanvasOp<Op::DrawRect> {
+        .paint = SkPaint{},
+        .rect = SkRect::MakeEmpty()
+    };
+    EXPECT_TRUE(CanvasOpTraits::can_draw<decltype(op)>);
+    rasterizer.draw(op);
+    EXPECT_EQ(1, canvas->drawRectCount);
+    EXPECT_EQ(1, canvas->sumTotalDrawCalls());
+}
\ No newline at end of file
diff --git a/location/java/android/location/Geocoder.java b/location/java/android/location/Geocoder.java
index 704cdbf..307fb87 100644
--- a/location/java/android/location/Geocoder.java
+++ b/location/java/android/location/Geocoder.java
@@ -21,6 +21,8 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
+import com.android.internal.util.Preconditions;
+
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
@@ -77,12 +79,9 @@
      * @throws NullPointerException if Locale is null
      */
     public Geocoder(Context context, Locale locale) {
-        if (locale == null) {
-            throw new NullPointerException("locale == null");
-        }
         mParams = new GeocoderParams(context, locale);
-        IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
-        mService = ILocationManager.Stub.asInterface(b);
+        mService = ILocationManager.Stub.asInterface(
+                ServiceManager.getService(Context.LOCATION_SERVICE));
     }
 
     /**
@@ -121,13 +120,10 @@
      * I/O problem occurs
      */
     public List<Address> getFromLocation(double latitude, double longitude, int maxResults)
-        throws IOException {
-        if (latitude < -90.0 || latitude > 90.0) {
-            throw new IllegalArgumentException("latitude == " + latitude);
-        }
-        if (longitude < -180.0 || longitude > 180.0) {
-            throw new IllegalArgumentException("longitude == " + longitude);
-        }
+            throws IOException {
+        Preconditions.checkArgumentInRange(latitude, -90.0, 90.0, "latitude");
+        Preconditions.checkArgumentInRange(longitude, -180.0, 180.0, "longitude");
+
         try {
             GeocodeListener listener = new GeocodeListener();
             mService.getFromLocation(latitude, longitude, maxResults, mParams, listener);
@@ -161,17 +157,7 @@
      * I/O problem occurs
      */
     public List<Address> getFromLocationName(String locationName, int maxResults) throws IOException {
-        if (locationName == null) {
-            throw new IllegalArgumentException("locationName == null");
-        }
-
-        try {
-            GeocodeListener listener = new GeocodeListener();
-            mService.getFromLocationName(locationName, 0, 0, 0, 0, maxResults, mParams, listener);
-            return listener.getResults();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        return getFromLocationName(locationName, maxResults, 0, 0, 0, 0);
     }
 
     /**
@@ -210,27 +196,14 @@
      * I/O problem occurs
      */
     public List<Address> getFromLocationName(String locationName, int maxResults,
-        double lowerLeftLatitude, double lowerLeftLongitude,
-        double upperRightLatitude, double upperRightLongitude) throws IOException {
-        if (locationName == null) {
-            throw new IllegalArgumentException("locationName == null");
-        }
-        if (lowerLeftLatitude < -90.0 || lowerLeftLatitude > 90.0) {
-            throw new IllegalArgumentException("lowerLeftLatitude == "
-                + lowerLeftLatitude);
-        }
-        if (lowerLeftLongitude < -180.0 || lowerLeftLongitude > 180.0) {
-            throw new IllegalArgumentException("lowerLeftLongitude == "
-                + lowerLeftLongitude);
-        }
-        if (upperRightLatitude < -90.0 || upperRightLatitude > 90.0) {
-            throw new IllegalArgumentException("upperRightLatitude == "
-                + upperRightLatitude);
-        }
-        if (upperRightLongitude < -180.0 || upperRightLongitude > 180.0) {
-            throw new IllegalArgumentException("upperRightLongitude == "
-                + upperRightLongitude);
-        }
+            double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude,
+            double upperRightLongitude) throws IOException {
+        Preconditions.checkArgument(locationName != null);
+        Preconditions.checkArgumentInRange(lowerLeftLatitude, -90.0, 90.0, "lowerLeftLatitude");
+        Preconditions.checkArgumentInRange(lowerLeftLongitude, -180.0, 180.0, "lowerLeftLongitude");
+        Preconditions.checkArgumentInRange(upperRightLatitude, -90.0, 90.0, "upperRightLatitude");
+        Preconditions.checkArgumentInRange(upperRightLongitude, -180.0, 180.0,
+                "upperRightLongitude");
 
         try {
             GeocodeListener listener = new GeocodeListener();
diff --git a/location/java/android/location/GeocoderParams.java b/location/java/android/location/GeocoderParams.java
index 1c6e9b6..b00a9a9 100644
--- a/location/java/android/location/GeocoderParams.java
+++ b/location/java/android/location/GeocoderParams.java
@@ -16,12 +16,16 @@
 
 package android.location;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
 
 import java.util.Locale;
+import java.util.Objects;
 
 /**
  * This class contains extra parameters to pass to an IGeocodeProvider
@@ -34,64 +38,88 @@
  * @hide
  */
 public class GeocoderParams implements Parcelable {
-    private Locale mLocale;
-    private String mPackageName;
 
-    // used only for parcelling
-    private GeocoderParams() {
+    private final int mUid;
+    private final String mPackageName;
+    private final @Nullable String mAttributionTag;
+    private final Locale mLocale;
+
+    public GeocoderParams(Context context) {
+        this(context, Locale.getDefault());
     }
 
-    /**
-     * This object is only constructed by the Geocoder class
-     *
-     * @hide
-     */
     public GeocoderParams(Context context, Locale locale) {
-        mLocale = locale;
-        mPackageName = context.getPackageName();
+        this(Process.myUid(), context.getPackageName(), context.getAttributionTag(), locale);
+    }
+
+    private GeocoderParams(int uid, String packageName, String attributionTag, Locale locale) {
+        mUid = uid;
+        mPackageName = Objects.requireNonNull(packageName);
+        mAttributionTag = attributionTag;
+        mLocale = Objects.requireNonNull(locale);
     }
 
     /**
-     * returns the Geocoder's locale
+     * Returns the client UID.
      */
     @UnsupportedAppUsage
-    public Locale getLocale() {
-        return mLocale;
+    public int getClientUid() {
+        return mUid;
     }
 
     /**
-     * returns the package name of the Geocoder's client
+     * Returns the client package name.
      */
     @UnsupportedAppUsage
-    public String getClientPackage() {
+    public @NonNull String getClientPackage() {
         return mPackageName;
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<GeocoderParams> CREATOR =
-        new Parcelable.Creator<GeocoderParams>() {
-        public GeocoderParams createFromParcel(Parcel in) {
-            GeocoderParams gp = new GeocoderParams();
-            String language = in.readString();
-            String country = in.readString();
-            String variant = in.readString();
-            gp.mLocale = new Locale(language, country, variant);
-            gp.mPackageName = in.readString();
-            return gp;
-        }
+    /**
+     * Returns the client attribution tag.
+     */
+    @UnsupportedAppUsage
+    public @Nullable String getClientAttributionTag() {
+        return mAttributionTag;
+    }
 
-        public GeocoderParams[] newArray(int size) {
-            return new GeocoderParams[size];
-        }
-    };
+    /**
+     * Returns the locale.
+     */
+    @UnsupportedAppUsage
+    public @NonNull Locale getLocale() {
+        return mLocale;
+    }
+
+    public static final @NonNull Parcelable.Creator<GeocoderParams> CREATOR =
+        new Parcelable.Creator<GeocoderParams>() {
+            public GeocoderParams createFromParcel(Parcel in) {
+                int uid = in.readInt();
+                String packageName = in.readString();
+                String attributionTag = in.readString();
+                String language = in.readString();
+                String country = in.readString();
+                String variant = in.readString();
+
+                return new GeocoderParams(uid, packageName, attributionTag,
+                        new Locale(language, country, variant));
+            }
+
+            public GeocoderParams[] newArray(int size) {
+                return new GeocoderParams[size];
+            }
+        };
 
     public int describeContents() {
         return 0;
     }
 
     public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mUid);
+        parcel.writeString(mPackageName);
+        parcel.writeString(mAttributionTag);
         parcel.writeString(mLocale.getLanguage());
         parcel.writeString(mLocale.getCountry());
         parcel.writeString(mLocale.getVariant());
-        parcel.writeString(mPackageName);
     }
 }
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 3493693..b61b79e 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -76,12 +76,11 @@
  * obtain periodic updates of the device's geographical location, or to be notified when the device
  * enters the proximity of a given geographical location.
  *
- * <p class="note">Unless noted, all Location API methods require the {@link
- * android.Manifest.permission#ACCESS_COARSE_LOCATION} or {@link
- * android.Manifest.permission#ACCESS_FINE_LOCATION} permissions. If your application only has the
- * coarse permission then it will not have access to fine location providers. Other providers will
- * still return location results, but the exact location will be obfuscated to a coarse level of
- * accuracy.
+ * <p class="note">Unless otherwise noted, all Location API methods require the
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permissions. If your application only
+ * has the coarse permission then providers will still return location results, but the exact
+ * location will be obfuscated to a coarse level of accuracy.
  */
 @SuppressWarnings({"deprecation"})
 @SystemService(Context.LOCATION_SERVICE)
@@ -89,6 +88,16 @@
 public class LocationManager {
 
     /**
+     * For apps targeting Android S and above, immutable PendingIntents passed into location APIs
+     * will generate an IllegalArgumentException.
+     *
+     * @hide
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
+    public static final long BLOCK_IMMUTABLE_PENDING_INTENTS = 171317480L;
+
+    /**
      * For apps targeting Android S and above, LocationRequest system APIs may not be used with
      * PendingIntent location requests.
      *
@@ -96,7 +105,7 @@
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
-    public static final long PREVENT_PENDING_INTENT_SYSTEM_API_USAGE = 169887240L;
+    public static final long BLOCK_PENDING_INTENT_SYSTEM_API_USAGE = 169887240L;
 
     /**
      * For apps targeting Android S and above, location clients may receive historical locations
@@ -116,7 +125,7 @@
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
-    private static final long GET_PROVIDER_SECURITY_EXCEPTIONS = 150935354L;
+    public static final long GET_PROVIDER_SECURITY_EXCEPTIONS = 150935354L;
 
     /**
      * For apps targeting Android K and above, supplied {@link PendingIntent}s must be targeted to a
@@ -126,7 +135,7 @@
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
-    private static final long TARGETED_PENDING_INTENT = 148963590L;
+    public static final long BLOCK_UNTARGETED_PENDING_INTENTS = 148963590L;
 
     /**
      * For apps targeting Android K and above, incomplete locations may not be passed to
@@ -136,7 +145,7 @@
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
-    private static final long INCOMPLETE_LOCATION = 148964793L;
+    public static final long BLOCK_INCOMPLETE_LOCATIONS = 148964793L;
 
     /**
      * For apps targeting Android S and above, all {@link GpsStatus} API usage must be replaced with
@@ -146,7 +155,7 @@
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
-    private static final long GPS_STATUS_USAGE = 144027538L;
+    public static final long BLOCK_GPS_STATUS_USAGE = 144027538L;
 
     /**
      * Name of the network location provider.
@@ -1372,11 +1381,16 @@
         Preconditions.checkArgument(locationRequest != null, "invalid null location request");
         Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent");
 
-        if (Compatibility.isChangeEnabled(TARGETED_PENDING_INTENT)) {
+        if (Compatibility.isChangeEnabled(BLOCK_UNTARGETED_PENDING_INTENTS)) {
             Preconditions.checkArgument(pendingIntent.isTargetedToPackage(),
                     "pending intent must be targeted to a package");
         }
 
+        if (Compatibility.isChangeEnabled(BLOCK_IMMUTABLE_PENDING_INTENTS)) {
+            Preconditions.checkArgument(!pendingIntent.isImmutable(),
+                    "pending intent must be mutable");
+        }
+
         try {
             mService.registerLocationPendingIntent(provider, locationRequest, pendingIntent,
                     mContext.getPackageName(), mContext.getAttributionTag());
@@ -1729,7 +1743,7 @@
         Preconditions.checkArgument(provider != null, "invalid null provider");
         Preconditions.checkArgument(location != null, "invalid null location");
 
-        if (Compatibility.isChangeEnabled(INCOMPLETE_LOCATION)) {
+        if (Compatibility.isChangeEnabled(BLOCK_INCOMPLETE_LOCATIONS)) {
             Preconditions.checkArgument(location.isComplete(),
                     "incomplete location object, missing timestamp or accuracy?");
         } else {
@@ -1821,29 +1835,38 @@
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. From API version 17 and onwards,
      * this method requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission.
      *
-     * @param latitude   the latitude of the central point of the alert region
-     * @param longitude  the longitude of the central point of the alert region
-     * @param radius     the radius of the central point of the alert region in meters
-     * @param expiration expiration realtime for this proximity alert in milliseconds, or -1 to
-     *                   indicate no expiration
-     * @param intent     a {@link PendingIntent} that will sent when entry to or exit from the alert
-     *                   region is detected
+     * @param latitude      the latitude of the central point of the alert region
+     * @param longitude     the longitude of the central point of the alert region
+     * @param radius        the radius of the central point of the alert region in meters
+     * @param expiration    expiration realtime for this proximity alert in milliseconds, or -1 to
+     *                      indicate no expiration
+     * @param pendingIntent a {@link PendingIntent} that will sent when entry to or exit from the
+     *                      alert region is detected
      * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
      *                           permission is not present
      */
     @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
     public void addProximityAlert(double latitude, double longitude, float radius, long expiration,
-            @NonNull PendingIntent intent) {
-        Preconditions.checkArgument(intent != null, "invalid null pending intent");
-        if (Compatibility.isChangeEnabled(TARGETED_PENDING_INTENT)) {
-            Preconditions.checkArgument(intent.isTargetedToPackage(),
+            @NonNull PendingIntent pendingIntent) {
+        Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent");
+
+        if (Compatibility.isChangeEnabled(BLOCK_UNTARGETED_PENDING_INTENTS)) {
+            Preconditions.checkArgument(pendingIntent.isTargetedToPackage(),
                     "pending intent must be targeted to a package");
         }
-        if (expiration < 0) expiration = Long.MAX_VALUE;
+
+        if (Compatibility.isChangeEnabled(BLOCK_IMMUTABLE_PENDING_INTENTS)) {
+            Preconditions.checkArgument(!pendingIntent.isImmutable(),
+                    "pending intent must be mutable");
+        }
+
+        if (expiration < 0) {
+            expiration = Long.MAX_VALUE;
+        }
 
         try {
             Geofence fence = Geofence.createCircle(latitude, longitude, radius, expiration);
-            mService.requestGeofence(fence, intent, mContext.getPackageName(),
+            mService.requestGeofence(fence, pendingIntent, mContext.getPackageName(),
                     mContext.getAttributionTag());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1941,7 +1964,7 @@
     @Deprecated
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public @Nullable GpsStatus getGpsStatus(@Nullable GpsStatus status) {
-        if (Compatibility.isChangeEnabled(GPS_STATUS_USAGE)) {
+        if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) {
             throw new UnsupportedOperationException(
                     "GpsStatus APIs not supported, please use GnssStatus APIs instead");
         }
@@ -1976,7 +1999,7 @@
     @Deprecated
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public boolean addGpsStatusListener(GpsStatus.Listener listener) {
-        if (Compatibility.isChangeEnabled(GPS_STATUS_USAGE)) {
+        if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) {
             throw new UnsupportedOperationException(
                     "GpsStatus APIs not supported, please use GnssStatus APIs instead");
         }
@@ -1996,7 +2019,7 @@
      */
     @Deprecated
     public void removeGpsStatusListener(GpsStatus.Listener listener) {
-        if (Compatibility.isChangeEnabled(GPS_STATUS_USAGE)) {
+        if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) {
             throw new UnsupportedOperationException(
                     "GpsStatus APIs not supported, please use GnssStatus APIs instead");
         }
diff --git a/location/java/android/location/timezone/LocationTimeZoneEvent.java b/location/java/android/location/timezone/LocationTimeZoneEvent.java
index d3fd5c3..922a389 100644
--- a/location/java/android/location/timezone/LocationTimeZoneEvent.java
+++ b/location/java/android/location/timezone/LocationTimeZoneEvent.java
@@ -21,7 +21,6 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.UserHandle;
 
 import com.android.internal.util.Preconditions;
 
@@ -65,9 +64,6 @@
 
     private static final int EVENT_TYPE_MAX = EVENT_TYPE_UNCERTAIN;
 
-    @NonNull
-    private final UserHandle mUserHandle;
-
     @EventType
     private final int mEventType;
 
@@ -76,9 +72,8 @@
 
     private final long mElapsedRealtimeNanos;
 
-    private LocationTimeZoneEvent(@NonNull UserHandle userHandle, @EventType int eventType,
-            @NonNull List<String> timeZoneIds, long elapsedRealtimeNanos) {
-        mUserHandle = Objects.requireNonNull(userHandle);
+    private LocationTimeZoneEvent(@EventType int eventType, @NonNull List<String> timeZoneIds,
+            long elapsedRealtimeNanos) {
         mEventType = checkValidEventType(eventType);
         mTimeZoneIds = immutableList(timeZoneIds);
 
@@ -89,14 +84,6 @@
     }
 
     /**
-     * Returns the current user when the event was generated.
-     */
-    @NonNull
-    public UserHandle getUserHandle() {
-        return mUserHandle;
-    }
-
-    /**
      * Returns the time of this fix, in elapsed real-time since system boot.
      *
      * <p>This value can be reliably compared to {@link
@@ -129,8 +116,7 @@
     @Override
     public String toString() {
         return "LocationTimeZoneEvent{"
-                + "mUserHandle=" + mUserHandle
-                + ", mEventType=" + mEventType
+                + "mEventType=" + mEventType
                 + ", mTimeZoneIds=" + mTimeZoneIds
                 + ", mElapsedRealtimeNanos=" + mElapsedRealtimeNanos
                 + '}';
@@ -140,14 +126,12 @@
             new Parcelable.Creator<LocationTimeZoneEvent>() {
                 @Override
                 public LocationTimeZoneEvent createFromParcel(Parcel in) {
-                    UserHandle userHandle = UserHandle.readFromParcel(in);
                     int eventType = in.readInt();
                     @SuppressWarnings("unchecked")
                     ArrayList<String> timeZoneIds =
                             (ArrayList<String>) in.readArrayList(null /* classLoader */);
                     long elapsedRealtimeNanos = in.readLong();
-                    return new LocationTimeZoneEvent(
-                            userHandle, eventType, timeZoneIds, elapsedRealtimeNanos);
+                    return new LocationTimeZoneEvent(eventType, timeZoneIds, elapsedRealtimeNanos);
                 }
 
                 @Override
@@ -163,7 +147,6 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        mUserHandle.writeToParcel(parcel, flags);
         parcel.writeInt(mEventType);
         parcel.writeList(mTimeZoneIds);
         parcel.writeLong(mElapsedRealtimeNanos);
@@ -178,21 +161,19 @@
             return false;
         }
         LocationTimeZoneEvent that = (LocationTimeZoneEvent) o;
-        return mUserHandle.equals(that.mUserHandle)
-                && mEventType == that.mEventType
+        return mEventType == that.mEventType
                 && mElapsedRealtimeNanos == that.mElapsedRealtimeNanos
                 && mTimeZoneIds.equals(that.mTimeZoneIds);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUserHandle, mEventType, mTimeZoneIds, mElapsedRealtimeNanos);
+        return Objects.hash(mEventType, mTimeZoneIds, mElapsedRealtimeNanos);
     }
 
     /** @hide */
     public static final class Builder {
 
-        private UserHandle mUserHandle;
         private @EventType int mEventType = EVENT_TYPE_UNKNOWN;
         private @NonNull List<String> mTimeZoneIds = Collections.emptyList();
         private long mElapsedRealtimeNanos;
@@ -204,21 +185,12 @@
          * Sets the contents of this from the supplied instance.
          */
         public Builder(@NonNull LocationTimeZoneEvent ltz) {
-            mUserHandle = ltz.mUserHandle;
             mEventType = ltz.mEventType;
             mTimeZoneIds = ltz.mTimeZoneIds;
             mElapsedRealtimeNanos = ltz.mElapsedRealtimeNanos;
         }
 
         /**
-         * Set the current user when this event was generated.
-         */
-        public Builder setUserHandle(@NonNull UserHandle userHandle) {
-            mUserHandle = Objects.requireNonNull(userHandle);
-            return this;
-        }
-
-        /**
          * Set the time zone ID of this event.
          */
         public Builder setEventType(@EventType int eventType) {
@@ -247,8 +219,7 @@
          * Builds a {@link LocationTimeZoneEvent} instance.
          */
         public LocationTimeZoneEvent build() {
-            return new LocationTimeZoneEvent(
-                    mUserHandle, mEventType, mTimeZoneIds, mElapsedRealtimeNanos);
+            return new LocationTimeZoneEvent(mEventType, mTimeZoneIds, mElapsedRealtimeNanos);
         }
     }
 
diff --git a/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java b/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java
index aa0e895..0739633 100644
--- a/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java
+++ b/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java
@@ -18,10 +18,8 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.app.ActivityManager;
 import android.location.timezone.LocationTimeZoneEvent;
 import android.os.SystemClock;
-import android.os.UserHandle;
 
 import java.util.Collections;
 import java.util.List;
@@ -146,7 +144,6 @@
         public LocationTimeZoneEventUnbundled build() {
             final int internalEventType = this.mEventType;
             LocationTimeZoneEvent event = new LocationTimeZoneEvent.Builder()
-                    .setUserHandle(UserHandle.of(ActivityManager.getCurrentUser()))
                     .setEventType(internalEventType)
                     .setTimeZoneIds(mTimeZoneIds)
                     .setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos())
diff --git a/media/java/android/media/IRemoteVolumeController.aidl b/media/java/android/media/IRemoteVolumeControllerCallback.aidl
similarity index 84%
rename from media/java/android/media/IRemoteVolumeController.aidl
rename to media/java/android/media/IRemoteVolumeControllerCallback.aidl
index 74c05c4..34c6361 100644
--- a/media/java/android/media/IRemoteVolumeController.aidl
+++ b/media/java/android/media/IRemoteVolumeControllerCallback.aidl
@@ -25,9 +25,9 @@
  * TODO add in better support for multiple remote sessions.
  * @hide
  */
-oneway interface IRemoteVolumeController {
-    void remoteVolumeChanged(in MediaSession.Token sessionToken, int flags);
+oneway interface IRemoteVolumeControllerCallback {
+    void onVolumeChanged(in MediaSession.Token sessionToken, int flags);
     // sets the default session to use with the slider, replaces remoteSliderVisibility
     // on IVolumeController
-    void updateRemoteController(in MediaSession.Token sessionToken);
+    void onSessionChanged(in MediaSession.Token sessionToken);
 }
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 4b208ce..5c1f893 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -676,17 +676,9 @@
         return null;
     }
 
-    /**
-     * Instantiate a CA system of the specified system id.
-     *
-     * @param CA_system_id The system id of the CA system.
-     *
-     * @throws UnsupportedCasException if the device does not support the
-     * specified CA system.
-     */
-    public MediaCas(int CA_system_id) throws UnsupportedCasException {
+    private void createPlugin(int casSystemId) throws UnsupportedCasException {
         try {
-            mCasSystemId = CA_system_id;
+            mCasSystemId = casSystemId;
             mUserId = ActivityManager.getCurrentUser();
             IMediaCasService service = getService();
             android.hardware.cas.V1_2.IMediaCasService serviceV12 =
@@ -696,16 +688,16 @@
                     android.hardware.cas.V1_1.IMediaCasService.castFrom(service);
                 if (serviceV11 == null) {
                     Log.d(TAG, "Used cas@1_0 interface to create plugin");
-                    mICas = service.createPlugin(CA_system_id, mBinder);
+                    mICas = service.createPlugin(casSystemId, mBinder);
                 } else {
                     Log.d(TAG, "Used cas@1.1 interface to create plugin");
-                    mICas = mICasV11 = serviceV11.createPluginExt(CA_system_id, mBinder);
+                    mICas = mICasV11 = serviceV11.createPluginExt(casSystemId, mBinder);
                 }
             } else {
                 Log.d(TAG, "Used cas@1.2 interface to create plugin");
                 mICas = mICasV11 = mICasV12 =
                     android.hardware.cas.V1_2.ICas
-                    .castFrom(serviceV12.createPluginExt(CA_system_id, mBinder));
+                        .castFrom(serviceV12.createPluginExt(casSystemId, mBinder));
             }
         } catch(Exception e) {
             Log.e(TAG, "Failed to create plugin: " + e);
@@ -713,11 +705,37 @@
         } finally {
             if (mICas == null) {
                 throw new UnsupportedCasException(
-                        "Unsupported CA_system_id " + CA_system_id);
+                    "Unsupported casSystemId " + casSystemId);
             }
         }
     }
 
+    private void registerClient(@NonNull Context context,
+            @Nullable String tvInputServiceSessionId,  @PriorityHintUseCaseType int priorityHint)  {
+
+        mTunerResourceManager = (TunerResourceManager)
+            context.getSystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE);
+        if (mTunerResourceManager != null) {
+            int[] clientId = new int[1];
+            ResourceClientProfile profile =
+                    new ResourceClientProfile(tvInputServiceSessionId, priorityHint);
+            mTunerResourceManager.registerClientProfile(
+                    profile, context.getMainExecutor(), mResourceListener, clientId);
+            mClientId = clientId[0];
+        }
+    }
+    /**
+     * Instantiate a CA system of the specified system id.
+     *
+     * @param casSystemId The system id of the CA system.
+     *
+     * @throws UnsupportedCasException if the device does not support the
+     * specified CA system.
+     */
+    public MediaCas(int casSystemId) throws UnsupportedCasException {
+        createPlugin(casSystemId);
+    }
+
     /**
      * Instantiate a CA system of the specified system id.
      *
@@ -733,19 +751,35 @@
     public MediaCas(@NonNull Context context, int casSystemId,
             @Nullable String tvInputServiceSessionId,
             @PriorityHintUseCaseType int priorityHint) throws UnsupportedCasException {
-        this(casSystemId);
-
         Objects.requireNonNull(context, "context must not be null");
-        mTunerResourceManager = (TunerResourceManager)
-                context.getSystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE);
-        if (mTunerResourceManager != null) {
-            int[] clientId = new int[1];
-            ResourceClientProfile profile =
-                    new ResourceClientProfile(tvInputServiceSessionId, priorityHint);
-            mTunerResourceManager.registerClientProfile(
-                    profile, context.getMainExecutor(), mResourceListener, clientId);
-            mClientId = clientId[0];
-        }
+        createPlugin(casSystemId);
+        registerClient(context, tvInputServiceSessionId, priorityHint);
+    }
+    /**
+     * Instantiate a CA system of the specified system id with EvenListener.
+     *
+     * @param context the context of the caller.
+     * @param casSystemId The system id of the CA system.
+     * @param tvInputServiceSessionId The Id of the session opened in TV Input Service (TIS)
+     *        {@link android.media.tv.TvInputService#onCreateSession(String, String)}
+     * @param priorityHint priority hint from the use case type for new created CAS system.
+     * @param listener the event listener to be set.
+     * @param handler the handler whose looper the event listener will be called on.
+     * If handler is null, we'll try to use current thread's looper, or the main
+     * looper. If neither are available, an internal thread will be created instead.
+     *
+     * @throws UnsupportedCasException if the device does not support the
+     * specified CA system.
+     */
+    public MediaCas(@NonNull Context context, int casSystemId,
+            @Nullable String tvInputServiceSessionId,
+            @PriorityHintUseCaseType int priorityHint,
+            @Nullable Handler handler, @Nullable EventListener listener)
+            throws UnsupportedCasException {
+        Objects.requireNonNull(context, "context must not be null");
+        setEventListener(listener, handler);
+        createPlugin(casSystemId);
+        registerClient(context, tvInputServiceSessionId, priorityHint);
     }
 
     IHwBinder getBinder() {
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 42e39101..6554544 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -16,6 +16,9 @@
 
 package android.media;
 
+import static android.Manifest.permission.BIND_IMS_SERVICE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -83,6 +86,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Scanner;
 import java.util.Set;
 import java.util.UUID;
@@ -2109,8 +2113,8 @@
         mOnInfoListener = null;
         mOnVideoSizeChangedListener = null;
         mOnTimedTextListener = null;
-        mOnImsRxNoticeListener = null;
-        mOnImsRxNoticeHandler = null;
+        mOnRtpRxNoticeListener = null;
+        mOnRtpRxNoticeHandler = null;
         synchronized (mTimeProviderLock) {
             if (mTimeProvider != null) {
                 mTimeProvider.close();
@@ -3323,7 +3327,7 @@
     private static final int MEDIA_META_DATA = 202;
     private static final int MEDIA_DRM_INFO = 210;
     private static final int MEDIA_TIME_DISCONTINUITY = 211;
-    private static final int MEDIA_IMS_RX_NOTICE = 300;
+    private static final int MEDIA_RTP_RX_NOTICE = 300;
     private static final int MEDIA_AUDIO_ROUTING_CHANGED = 10000;
 
     private TimeProvider mTimeProvider;
@@ -3633,31 +3637,34 @@
                 }
                 return;
 
-            case MEDIA_IMS_RX_NOTICE:
-                final OnImsRxNoticeListener imsRxNoticeListener;
-                final Handler imsRxNoticeHandler;
-                imsRxNoticeListener = mOnImsRxNoticeListener;
-                imsRxNoticeHandler = mOnImsRxNoticeHandler;
-                if (imsRxNoticeListener == null) {
+            case MEDIA_RTP_RX_NOTICE:
+                final OnRtpRxNoticeListener rtpRxNoticeListener = mOnRtpRxNoticeListener;
+                final Handler rtpRxNoticeHandler = mOnRtpRxNoticeHandler;
+                if (rtpRxNoticeListener == null) {
                     return;
                 }
                 if (msg.obj instanceof Parcel) {
                     Parcel parcel = (Parcel) msg.obj;
-                    byte[] event;
+                    parcel.setDataPosition(0);
+                    int noticeType;
+                    int[] data;
                     try {
-                        event = parcel.marshall();
+                        noticeType = parcel.readInt();
+                        int numOfArgs = parcel.dataAvail() / 4;
+                        data = new int[numOfArgs];
+                        for (int i = 0; i < numOfArgs; i++) {
+                            data[i] = parcel.readInt();
+                        }
                     } finally {
                         parcel.recycle();
                     }
-                    if (imsRxNoticeHandler == null) {
-                        imsRxNoticeListener.onImsRxNotice(mMediaPlayer, event);
+                    if (rtpRxNoticeHandler == null) {
+                        rtpRxNoticeListener.onRtpRxNotice(mMediaPlayer, noticeType, data);
                     } else {
-                        imsRxNoticeHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                imsRxNoticeListener.onImsRxNotice(mMediaPlayer, event);
-                            }
-                        });
+                        rtpRxNoticeHandler.post(
+                                () ->
+                                        rtpRxNoticeListener
+                                                .onRtpRxNotice(mMediaPlayer, noticeType, data));
                     }
                 }
                 return;
@@ -4103,18 +4110,18 @@
 
     /**
      * Interface definition of a callback to be invoked when
-     * IMS Rx connection has a notice.
+     * RTP Rx connection has a notice.
      *
-     * @see MediaPlayer.setOnImsRxNoticeListener
+     * @see #setOnRtpRxNoticeListener
      *
      * @hide
      */
     @SystemApi
-    public interface OnImsRxNoticeListener
+    public interface OnRtpRxNoticeListener
     {
         /**
-         * Called to indicate an IMS event noticed from native media frameworks.
-         * <p></p>
+         * Called when an RTP Rx connection has a notice.
+         * <p>
          * Basic format. All TYPE and ARG are 4 bytes unsigned integer in native byte order.
          * <pre>{@code
          * 0                4               8                12
@@ -4169,14 +4176,14 @@
          * TYPE 205 - Transport layer Feedback message. (RFC-5104 Sec.4.2)
          * 0                4               8                12
          * +----------------+---------------+----------------+----------------+
-         * |      205       |      SSRC     | FB type(1 or 3)|     value      |
+         * |      205       |FB type(1 or 3)|      SSRC      |      Value     |
          * +----------------+---------------+----------------+----------------+
-         * SSRC
-         *      - Remote side's SSRC value of the media sender (RFC-3550 Sec.5.1)
          * Feedback (FB) type: determines the type of the event.
          *      - if 1, we received a NACK request from the remote side.
          *      - if 3, we received a TMMBR (Temporary Maximum Media Stream Bit Rate Request) from
          *        the remote side.
+         * SSRC
+         *      - Remote side's SSRC value of the media sender (RFC-3550 Sec.5.1)
          * Value: the FCI (Feedback Control Information) depending on the value of FB type
          *      - if FB type is 1, the Generic NACK as specified in RFC-4585 Sec.6.2.1
          *      - if FB type is 3, the TMMBR as specified in RFC-5104 Sec.4.2.1.1
@@ -4185,13 +4192,13 @@
          * TYPE 206 - Payload-specific Feedback message. (RFC-5104 Sec.4.3)
          * 0                4               8
          * +----------------+---------------+----------------+
-         * |      206       |      SSRC     | FB type(1 or 4)|
+         * |      206       |FB type(1 or 4)|      SSRC      |
          * +----------------+---------------+----------------+
-         * SSRC
-         *      - Remote side's SSRC value of the media sender (RFC-3550 Sec.5.1)
          * Feedback (FB) type: determines the type of the event.
          *      - if 1, we received a PLI request from the remote side.
          *      - if 4, we received a FIR request from the remote side.
+         * SSRC
+         *      - Remote side's SSRC value of the media sender (RFC-3550 Sec.5.1)
          *
          *
          * TYPE 300 - CVO (RTP Extension) message.
@@ -4212,34 +4219,39 @@
          * }</pre>
          *
          * @param mp the {@code MediaPlayer} associated with this callback.
-         * @param event an IMS media event serialized as byte[] array.
+         * @param noticeType TYPE of the event.
+         * @param params RTP Rx media data serialized as int[] array.
          */
-        void onImsRxNotice(@NonNull MediaPlayer mp, @NonNull byte[] event);
+        void onRtpRxNotice(@NonNull MediaPlayer mp, int noticeType, @NonNull int[] params);
     }
 
     /**
-     * Register a callback to be invoked when IMS Rx connection has a notice.
-     * The callback required if mediaplayer configured for RTPSource by
-     * MediaPlayer.setDataSource(String8 rtpParams) of mediaplayer.h
+     * Sets the listener to be invoked when an RTP Rx connection has a notice.
+     * The listener is required if MediaPlayer is configured for RTPSource by
+     * MediaPlayer.setDataSource(String8 rtpParams) of mediaplayer.h.
      *
-     * @see MediaPlayer.OnImsRxNoticeListener
+     * @see OnRtpRxNoticeListener
      *
-     * @param listener the callback that will be run
-     * @param handler Specifies Handler object for the thread on which to execute
-     * the callback. If null, the handler on the main looper will be used.
+     * @param listener the listener called after a notice from RTP Rx
+     * @param handler the {@link Handler} that receives RTP Tx events
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission("android.permission.BIND_IMS_SERVICE")
-    public void setOnImsRxNoticeListener(
-        @Nullable OnImsRxNoticeListener listener, @Nullable Handler handler) {
-        mOnImsRxNoticeListener = listener;
-        mOnImsRxNoticeHandler = handler;
+    public void setOnRtpRxNoticeListener(
+            @NonNull Context context,
+            @NonNull OnRtpRxNoticeListener listener, @Nullable Handler handler) {
+        Objects.requireNonNull(context);
+        Preconditions.checkArgument(
+                context.checkSelfPermission(BIND_IMS_SERVICE) == PERMISSION_GRANTED,
+                "android.permission.BIND_IMS_SERVICE permission not granted.");
+        mOnRtpRxNoticeListener = Objects.requireNonNull(listener);
+        mOnRtpRxNoticeHandler = handler;
     }
 
-    private OnImsRxNoticeListener mOnImsRxNoticeListener;
-    private Handler mOnImsRxNoticeHandler;
+    private OnRtpRxNoticeListener mOnRtpRxNoticeListener;
+    private Handler mOnRtpRxNoticeHandler;
 
     /**
      * Register a callback to be invoked when a selected track has timed metadata available.
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index df5e85e..da69c6c 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -520,11 +520,12 @@
 
         @Override
         public void applyVolumeShaper(
-                @NonNull VolumeShaper.Configuration configuration,
-                @NonNull VolumeShaper.Operation operation) {
+                @NonNull VolumeShaperConfiguration configuration,
+                @NonNull VolumeShaperOperation operation) {
             final PlayerBase pb = mWeakPB.get();
             if (pb != null) {
-                pb.playerApplyVolumeShaper(configuration, operation);
+                pb.playerApplyVolumeShaper(VolumeShaper.Configuration.fromParcelable(configuration),
+                        VolumeShaper.Operation.fromParcelable(operation));
             }
         }
     }
diff --git a/media/java/android/media/PlayerProxy.java b/media/java/android/media/PlayerProxy.java
index 5f3997a..ec39128 100644
--- a/media/java/android/media/PlayerProxy.java
+++ b/media/java/android/media/PlayerProxy.java
@@ -143,7 +143,8 @@
             @NonNull VolumeShaper.Configuration configuration,
             @NonNull VolumeShaper.Operation operation) {
         try {
-            mConf.getIPlayer().applyVolumeShaper(configuration, operation);
+            mConf.getIPlayer().applyVolumeShaper(configuration.toParcelable(),
+                    operation.toParcelable());
         } catch (NullPointerException|RemoteException e) {
             throw new IllegalStateException(
                     "No player to proxy for applyVolumeShaper operation,"
diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java
index df8d08e..5bad693 100644
--- a/media/java/android/media/VolumeShaper.java
+++ b/media/java/android/media/VolumeShaper.java
@@ -21,6 +21,7 @@
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
+import android.os.BadParcelableException;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -482,50 +483,62 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            // this needs to match the native VolumeShaper.Configuration parceling
-            dest.writeInt(mType);
-            dest.writeInt(mId);
-            if (mType != TYPE_ID) {
-                dest.writeInt(mOptionFlags);
-                dest.writeDouble(mDurationMs);
-                // this needs to match the native Interpolator parceling
-                dest.writeInt(mInterpolatorType);
-                dest.writeFloat(0.f); // first slope (specifying for native side)
-                dest.writeFloat(0.f); // last slope (specifying for native side)
-                // mTimes and mVolumes should have the same length.
-                dest.writeInt(mTimes.length);
-                for (int i = 0; i < mTimes.length; ++i) {
-                    dest.writeFloat(mTimes[i]);
-                    dest.writeFloat(mVolumes[i]);
-                }
-            }
+            VolumeShaperConfiguration parcelable = toParcelable();
+            parcelable.writeToParcel(dest, flags);
         }
 
-        public static final @android.annotation.NonNull Parcelable.Creator<VolumeShaper.Configuration> CREATOR
-                = new Parcelable.Creator<VolumeShaper.Configuration>() {
-            @Override
-            public VolumeShaper.Configuration createFromParcel(Parcel p) {
-                // this needs to match the native VolumeShaper.Configuration parceling
-                final int type = p.readInt();
-                final int id = p.readInt();
-                if (type == TYPE_ID) {
-                    return new VolumeShaper.Configuration(id);
-                } else {
-                    final int optionFlags = p.readInt();
-                    final double durationMs = p.readDouble();
-                    // this needs to match the native Interpolator parceling
-                    final int interpolatorType = p.readInt();
-                    final float firstSlope = p.readFloat(); // ignored on the Java side
-                    final float lastSlope = p.readFloat();  // ignored on the Java side
-                    final int length = p.readInt();
-                    final float[] times = new float[length];
-                    final float[] volumes = new float[length];
-                    for (int i = 0; i < length; ++i) {
-                        times[i] = p.readFloat();
-                        volumes[i] = p.readFloat();
-                    }
+        /** @hide */
+        public VolumeShaperConfiguration toParcelable() {
+            VolumeShaperConfiguration parcelable = new VolumeShaperConfiguration();
+            parcelable.type = typeToAidl(mType);
+            parcelable.id = mId;
+            if (mType != TYPE_ID) {
+                parcelable.optionFlags = optionFlagsToAidl(mOptionFlags);
+                parcelable.durationMs = mDurationMs;
+                parcelable.interpolatorConfig = toInterpolatorParcelable();
+            }
+            return parcelable;
+        }
 
-                    return new VolumeShaper.Configuration(
+        private InterpolatorConfig toInterpolatorParcelable() {
+            InterpolatorConfig parcelable = new InterpolatorConfig();
+            parcelable.type = interpolatorTypeToAidl(mInterpolatorType);
+            parcelable.firstSlope = 0.f; // first slope (specifying for native side)
+            parcelable.lastSlope = 0.f; // last slope (specifying for native side)
+            parcelable.xy = new float[mTimes.length * 2];
+            for (int i = 0; i < mTimes.length; ++i) {
+                parcelable.xy[i * 2] = mTimes[i];
+                parcelable.xy[i * 2 + 1] = mVolumes[i];
+            }
+            return parcelable;
+        }
+
+        /** @hide */
+        public static Configuration fromParcelable(VolumeShaperConfiguration parcelable) {
+            // this needs to match the native VolumeShaper.Configuration parceling
+            final int type = typeFromAidl(parcelable.type);
+            final int id = parcelable.id;
+            if (type == TYPE_ID) {
+                return new VolumeShaper.Configuration(id);
+            } else {
+                final int optionFlags = optionFlagsFromAidl(parcelable.optionFlags);
+                final double durationMs = parcelable.durationMs;
+                final int interpolatorType = interpolatorTypeFromAidl(
+                        parcelable.interpolatorConfig.type);
+                // parcelable.interpolatorConfig.firstSlope is ignored on the Java side
+                // parcelable.interpolatorConfig.lastSlope is ignored on the Java side
+                final int length = parcelable.interpolatorConfig.xy.length;
+                if (length % 2 != 0) {
+                    throw new android.os.BadParcelableException("xy length must be even");
+                }
+                final float[] times = new float[length / 2];
+                final float[] volumes = new float[length / 2];
+                for (int i = 0; i < length / 2; ++i) {
+                    times[i] = parcelable.interpolatorConfig.xy[i * 2];
+                    volumes[i] = parcelable.interpolatorConfig.xy[i * 2 + 1];
+                }
+
+                return new VolumeShaper.Configuration(
                         type,
                         id,
                         optionFlags,
@@ -533,7 +546,14 @@
                         interpolatorType,
                         times,
                         volumes);
-                }
+            }
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<VolumeShaper.Configuration> CREATOR
+                = new Parcelable.Creator<VolumeShaper.Configuration>() {
+            @Override
+            public VolumeShaper.Configuration createFromParcel(Parcel p) {
+                return fromParcelable(VolumeShaperConfiguration.CREATOR.createFromParcel(p));
             }
 
             @Override
@@ -542,6 +562,84 @@
             }
         };
 
+        private static @InterpolatorType
+        int interpolatorTypeFromAidl(@android.media.InterpolatorType int aidl) {
+            switch (aidl) {
+                case android.media.InterpolatorType.STEP:
+                    return INTERPOLATOR_TYPE_STEP;
+                case android.media.InterpolatorType.LINEAR:
+                    return INTERPOLATOR_TYPE_LINEAR;
+                case android.media.InterpolatorType.CUBIC:
+                    return INTERPOLATOR_TYPE_CUBIC;
+                case android.media.InterpolatorType.CUBIC_MONOTONIC:
+                    return INTERPOLATOR_TYPE_CUBIC_MONOTONIC;
+                default:
+                    throw new BadParcelableException("Unknown interpolator type");
+            }
+        }
+
+        private static @android.media.InterpolatorType
+        int interpolatorTypeToAidl(@InterpolatorType int type) {
+            switch (type) {
+                case INTERPOLATOR_TYPE_STEP:
+                    return android.media.InterpolatorType.STEP;
+                case INTERPOLATOR_TYPE_LINEAR:
+                    return android.media.InterpolatorType.LINEAR;
+                case INTERPOLATOR_TYPE_CUBIC:
+                    return android.media.InterpolatorType.CUBIC;
+                case INTERPOLATOR_TYPE_CUBIC_MONOTONIC:
+                    return android.media.InterpolatorType.CUBIC_MONOTONIC;
+                default:
+                    throw new RuntimeException("Unknown interpolator type");
+            }
+        }
+
+        private static @Type
+        int typeFromAidl(@android.media.VolumeShaperConfigurationType int aidl) {
+            switch (aidl) {
+                case VolumeShaperConfigurationType.ID:
+                    return TYPE_ID;
+                case VolumeShaperConfigurationType.SCALE:
+                    return TYPE_SCALE;
+                default:
+                    throw new BadParcelableException("Unknown type");
+            }
+        }
+
+        private static @android.media.VolumeShaperConfigurationType
+        int typeToAidl(@Type int type) {
+            switch (type) {
+                case TYPE_ID:
+                    return VolumeShaperConfigurationType.ID;
+                case TYPE_SCALE:
+                    return VolumeShaperConfigurationType.SCALE;
+                default:
+                    throw new RuntimeException("Unknown type");
+            }
+        }
+
+        private static int optionFlagsFromAidl(int aidl) {
+            int result = 0;
+            if ((aidl & (1 << VolumeShaperConfigurationOptionFlag.VOLUME_IN_DBFS)) != 0) {
+                result |= OPTION_FLAG_VOLUME_IN_DBFS;
+            }
+            if ((aidl & (1 << VolumeShaperConfigurationOptionFlag.CLOCK_TIME)) != 0) {
+                result |= OPTION_FLAG_CLOCK_TIME;
+            }
+            return result;
+        }
+
+        private static int optionFlagsToAidl(int flags) {
+            int result = 0;
+            if ((flags & OPTION_FLAG_VOLUME_IN_DBFS) != 0) {
+                result |= (1 << VolumeShaperConfigurationOptionFlag.VOLUME_IN_DBFS);
+            }
+            if ((flags & OPTION_FLAG_CLOCK_TIME) != 0) {
+                result |= (1 << VolumeShaperConfigurationOptionFlag.CLOCK_TIME);
+            }
+            return result;
+        }
+
         /**
          * @hide
          * Constructs a {@code VolumeShaper} from an id.
@@ -1172,25 +1270,31 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            // this needs to match the native VolumeShaper.Operation parceling
-            dest.writeInt(mFlags);
-            dest.writeInt(mReplaceId);
-            dest.writeFloat(mXOffset);
+            toParcelable().writeToParcel(dest, flags);
+        }
+
+        /** @hide */
+        public VolumeShaperOperation toParcelable() {
+            VolumeShaperOperation result = new VolumeShaperOperation();
+            result.flags = flagsToAidl(mFlags);
+            result.replaceId = mReplaceId;
+            result.xOffset = mXOffset;
+            return result;
+        }
+
+        /** @hide */
+        public static Operation fromParcelable(VolumeShaperOperation parcelable) {
+            return new VolumeShaper.Operation(
+                    flagsFromAidl(parcelable.flags),
+                    parcelable.replaceId,
+                    parcelable.xOffset);
         }
 
         public static final @android.annotation.NonNull Parcelable.Creator<VolumeShaper.Operation> CREATOR
                 = new Parcelable.Creator<VolumeShaper.Operation>() {
             @Override
             public VolumeShaper.Operation createFromParcel(Parcel p) {
-                // this needs to match the native VolumeShaper.Operation parceling
-                final int flags = p.readInt();
-                final int replaceId = p.readInt();
-                final float xOffset = p.readFloat();
-
-                return new VolumeShaper.Operation(
-                        flags
-                        , replaceId
-                        , xOffset);
+                return fromParcelable(VolumeShaperOperation.CREATOR.createFromParcel(p));
             }
 
             @Override
@@ -1199,6 +1303,46 @@
             }
         };
 
+        private static int flagsFromAidl(int aidl) {
+            int result = 0;
+            if ((aidl & (1 << VolumeShaperOperationFlag.REVERSE)) != 0) {
+                result |= FLAG_REVERSE;
+            }
+            if ((aidl & (1 << VolumeShaperOperationFlag.TERMINATE)) != 0) {
+                result |= FLAG_TERMINATE;
+            }
+            if ((aidl & (1 << VolumeShaperOperationFlag.JOIN)) != 0) {
+                result |= FLAG_JOIN;
+            }
+            if ((aidl & (1 << VolumeShaperOperationFlag.DELAY)) != 0) {
+                result |= FLAG_DEFER;
+            }
+            if ((aidl & (1 << VolumeShaperOperationFlag.CREATE_IF_NECESSARY)) != 0) {
+                result |= FLAG_CREATE_IF_NEEDED;
+            }
+            return result;
+        }
+
+        private static int flagsToAidl(int flags) {
+            int result = 0;
+            if ((flags & FLAG_REVERSE) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.REVERSE);
+            }
+            if ((flags & FLAG_TERMINATE) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.TERMINATE);
+            }
+            if ((flags & FLAG_JOIN) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.JOIN);
+            }
+            if ((flags & FLAG_DEFER) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.DELAY);
+            }
+            if ((flags & FLAG_CREATE_IF_NEEDED) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.CREATE_IF_NECESSARY);
+            }
+            return result;
+        }
+
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         private Operation(@Flag int flags, int replaceId, float xOffset) {
             mFlags = flags;
@@ -1393,17 +1537,27 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeFloat(mVolume);
-            dest.writeFloat(mXOffset);
+            toParcelable().writeToParcel(dest, flags);
+        }
+
+        /** @hide */
+        public VolumeShaperState toParcelable() {
+            VolumeShaperState result = new VolumeShaperState();
+            result.volume = mVolume;
+            result.xOffset = mXOffset;
+            return result;
+        }
+
+        /** @hide */
+        public static State fromParcelable(VolumeShaperState p) {
+            return new VolumeShaper.State(p.volume, p.xOffset);
         }
 
         public static final @android.annotation.NonNull Parcelable.Creator<VolumeShaper.State> CREATOR
                 = new Parcelable.Creator<VolumeShaper.State>() {
             @Override
             public VolumeShaper.State createFromParcel(Parcel p) {
-                return new VolumeShaper.State(
-                        p.readFloat()     // volume
-                        , p.readFloat()); // xOffset
+                return fromParcelable(VolumeShaperState.CREATOR.createFromParcel(p));
             }
 
             @Override
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index 1557ea6..f157d7f 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -17,7 +17,7 @@
 
 import android.content.ComponentName;
 import android.content.pm.ParceledListSlice;
-import android.media.IRemoteVolumeController;
+import android.media.IRemoteVolumeControllerCallback;
 import android.media.Session2Token;
 import android.media.session.IActiveSessionsListener;
 import android.media.session.IOnMediaKeyEventDispatchedListener;
@@ -57,8 +57,8 @@
     void addSession2TokensListener(in ISession2TokensListener listener, int userId);
     void removeSession2TokensListener(in ISession2TokensListener listener);
 
-    void registerRemoteVolumeController(in IRemoteVolumeController rvc);
-    void unregisterRemoteVolumeController(in IRemoteVolumeController rvc);
+    void registerRemoteVolumeControllerCallback(in IRemoteVolumeControllerCallback rvc);
+    void unregisterRemoteVolumeControllerCallback(in IRemoteVolumeControllerCallback rvc);
 
     // For PhoneWindowManager to precheck media keys
     boolean isGlobalPriorityActive();
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index b7b9e4b..b596555 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -28,7 +28,7 @@
 import android.content.Context;
 import android.content.pm.ParceledListSlice;
 import android.media.AudioManager;
-import android.media.IRemoteVolumeController;
+import android.media.IRemoteVolumeControllerCallback;
 import android.media.MediaFrameworkInitializer;
 import android.media.MediaSession2;
 import android.media.Session2Token;
@@ -88,6 +88,8 @@
     private final OnMediaKeyEventSessionChangedListenerStub
             mOnMediaKeyEventSessionChangedListenerStub =
             new OnMediaKeyEventSessionChangedListenerStub();
+    private final RemoteVolumeControllerCallbackStub mRemoteVolumeControllerCallbackStub =
+            new RemoteVolumeControllerCallbackStub();
 
     private final Object mLock = new Object();
     @GuardedBy("mLock")
@@ -106,6 +108,9 @@
     private String mCurMediaKeyEventSessionPackage;
     @GuardedBy("mLock")
     private MediaSession.Token mCurMediaKeyEventSession;
+    @GuardedBy("mLock")
+    private final Map<RemoteVolumeControllerCallback, Executor>
+            mRemoteVolumeControllerCallbacks = new ArrayMap<>();
 
     private Context mContext;
     private OnVolumeKeyLongPressListenerImpl mOnVolumeKeyLongPressListener;
@@ -462,33 +467,62 @@
     }
 
     /**
-     * Set the remote volume controller to receive volume updates on.
+     * Set the remote volume controller callback to receive volume updates on.
      * Only for use by System UI and Settings application.
      *
-     * @param rvc The volume controller to receive updates on.
+     * @param callback The volume controller callback to receive updates on.
      * @hide
      */
-    public void registerRemoteVolumeController(IRemoteVolumeController rvc) {
-        try {
-            mService.registerRemoteVolumeController(rvc);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error in registerRemoteVolumeController.", e);
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void registerRemoteVolumeControllerCallback(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull RemoteVolumeControllerCallback callback) {
+        Objects.requireNonNull(executor, "executor shouldn't be null");
+        Objects.requireNonNull(callback, "callback shouldn't be null");
+        boolean shouldRegisterCallback = false;
+        synchronized (mLock) {
+            int prevCallbackCount = mRemoteVolumeControllerCallbacks.size();
+            mRemoteVolumeControllerCallbacks.put(callback, executor);
+            if (prevCallbackCount == 0 && mRemoteVolumeControllerCallbacks.size() == 1) {
+                shouldRegisterCallback = true;
+            }
+        }
+        if (shouldRegisterCallback) {
+            try {
+                mService.registerRemoteVolumeControllerCallback(
+                        mRemoteVolumeControllerCallbackStub);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to register remote volume controller callback", e);
+            }
         }
     }
 
     /**
-     * Unregisters the remote volume controller which was previously registered with
-     * {@link #registerRemoteVolumeController(IRemoteVolumeController)}.
+     * Unregisters the remote volume controller callback which was previously registered with
+     * {@link #registerRemoteVolumeControllerCallback(Executor, RemoteVolumeControllerCallback)}.
      * Only for use by System UI and Settings application.
      *
-     * @param rvc The volume controller which was registered.
+     * @param callback The volume controller callback to receive updates on.
      * @hide
      */
-    public void unregisterRemoteVolumeController(IRemoteVolumeController rvc) {
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void unregisterRemoteVolumeControllerCallback(
+            @NonNull RemoteVolumeControllerCallback callback) {
+        Objects.requireNonNull(callback, "callback shouldn't be null");
+        boolean shouldUnregisterCallback = false;
+        synchronized (mLock) {
+            if (mRemoteVolumeControllerCallbacks.remove(callback) != null
+                    && mRemoteVolumeControllerCallbacks.size() == 0) {
+                shouldUnregisterCallback = true;
+            }
+        }
         try {
-            mService.unregisterRemoteVolumeController(rvc);
+            if (shouldUnregisterCallback) {
+                mService.unregisterRemoteVolumeControllerCallback(
+                        mRemoteVolumeControllerCallbackStub);
+            }
         } catch (RemoteException e) {
-            Log.e(TAG, "Error in unregisterRemoteVolumeController.", e);
+            Log.e(TAG, "Failed to unregister remote volume controller callback", e);
         }
     }
 
@@ -1048,10 +1082,11 @@
          * has specified the target.
          * <p>
          * The session token can be {@link null} if the media button session is unset. In that case,
-         * framework would dispatch to the last sessions's media button receiver. If the media
-         * button receive isn't set as well, then it
+         * packageName will return the package name of the last session's media button receiver, or
+         * an empty string if the last session didn't set a media button receiver.
          *
-         * @param packageName The package name who would receive the media key event. Can be empty.
+         * @param packageName The package name of the component that will receive the media key
+         *                    event. Can be empty.
          * @param sessionToken The media session's token. Can be {@code null}.
          */
         void onMediaKeyEventSessionChanged(@NonNull String packageName,
@@ -1059,6 +1094,29 @@
     }
 
     /**
+     * Callback to receive changes in the remote volume controller.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public interface RemoteVolumeControllerCallback {
+        /**
+         * Called when the volume is changed.
+         *
+         * @param sessionToken the remote media session token
+         * @param flags any of the flags from {@link AudioManager}
+         */
+        void onVolumeChanged(@NonNull MediaSession.Token sessionToken, int flags);
+
+        /**
+         * Called when the session for the default remote controller is changed.
+         *
+         * @param sessionToken the remote media session token
+         */
+        void onSessionChanged(@Nullable MediaSession.Token sessionToken);
+    }
+
+    /**
      * Information of a remote user of {@link MediaSession} or {@link MediaBrowserService}.
      * This can be used to decide whether the remote user is trusted app, and also differentiate
      * caller of {@link MediaSession} and {@link MediaBrowserService} callbacks.
@@ -1290,4 +1348,29 @@
             }
         }
     }
+
+    private final class RemoteVolumeControllerCallbackStub
+            extends IRemoteVolumeControllerCallback.Stub {
+        @Override
+        public void onVolumeChanged(MediaSession.Token sessionToken, int flags) {
+            Map<RemoteVolumeControllerCallback, Executor> callbacks = new ArrayMap<>();
+            synchronized (mLock) {
+                callbacks.putAll(mRemoteVolumeControllerCallbacks);
+            }
+            for (Map.Entry<RemoteVolumeControllerCallback, Executor> e : callbacks.entrySet()) {
+                e.getValue().execute(() -> e.getKey().onVolumeChanged(sessionToken, flags));
+            }
+        }
+
+        @Override
+        public void onSessionChanged(MediaSession.Token sessionToken) {
+            Map<RemoteVolumeControllerCallback, Executor> callbacks = new ArrayMap<>();
+            synchronized (mLock) {
+                callbacks.putAll(mRemoteVolumeControllerCallbacks);
+            }
+            for (Map.Entry<RemoteVolumeControllerCallback, Executor> e : callbacks.entrySet()) {
+                e.getValue().execute(() -> e.getKey().onSessionChanged(sessionToken));
+            }
+        }
+    }
 }
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 1881e38..5a578dd 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -122,6 +122,17 @@
             android.hardware.tv.tuner.V1_1.Constants.Constant
                     .INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM;
     /**
+     * Invalid first macroblock address in MmtpRecordEvent and TsRecordEvent.
+     *
+     * <p>Returned by {@link MmtpRecordEvent#getMbInSlice()} and
+     * {@link TsRecordEvent#getMbInSlice()} when the requested sequence number is not available.
+     *
+     * @see android.media.tv.tuner.filter.MmtpRecordEvent#getMbInSlice()
+     * @see android.media.tv.tuner.filter.TsRecordEvent#getMbInSlice()
+     */
+    public static final int INVALID_FIRST_MACROBLOCK_IN_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_FIRST_MACROBLOCK_IN_SLICE;
+    /**
      * Invalid local transport stream id.
      *
      * <p>Returned by {@link #linkFrontendToCiCam(int)} when the requested failed
@@ -1062,6 +1073,13 @@
         }
     }
 
+    private void onDvbcAnnexReported(int dvbcAnnex) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(
+                    () -> mScanCallback.onDvbcAnnexReported(dvbcAnnex));
+        }
+    }
+
     /**
      * Opens a filter object based on the given types and buffer size.
      *
diff --git a/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java b/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
index 7060bd72..f0abce9 100644
--- a/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
+++ b/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
@@ -31,13 +31,16 @@
     private final long mDataLength;
     private final int mMpuSequenceNumber;
     private final long mPts;
+    private final int mFirstMbInSlice;
 
     // This constructor is used by JNI code only
-    private MmtpRecordEvent(int scHevcIndexMask, long dataLength, int mpuSequenceNumber, long pts) {
+    private MmtpRecordEvent(int scHevcIndexMask, long dataLength, int mpuSequenceNumber, long pts,
+            int firstMbInSlice) {
         mScHevcIndexMask = scHevcIndexMask;
         mDataLength = dataLength;
         mMpuSequenceNumber = mpuSequenceNumber;
         mPts = pts;
+        mFirstMbInSlice = firstMbInSlice;
     }
 
     /**
@@ -58,6 +61,11 @@
 
     /**
      * Get the MPU sequence number of the filtered data.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner.INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker.getTunerVersion()} to get the version
+     * information.
      */
     public int getMpuSequenceNumber() {
         return mMpuSequenceNumber;
@@ -65,10 +73,26 @@
 
     /**
      * Get the Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
-     * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and
-     * the SC_HEVC.
+     * and has the same format as the PTS in ISO/IEC 13818-1.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner.INVALID_TIMESTAMP}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker.getTunerVersion()} to get the version
+     * information.
      */
     public long getPts() {
         return mPts;
     }
+
+    /**
+     * Get the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner.INVALID_FIRST_MACROBLOCK_IN_SLICE}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker.getTunerVersion()} to get the version
+     * information.
+     */
+    public int getFirstMbInSlice() {
+        return mFirstMbInSlice;
+    }
 }
diff --git a/media/java/android/media/tv/tuner/filter/RecordSettings.java b/media/java/android/media/tv/tuner/filter/RecordSettings.java
index ec01e44..a6fd20e 100644
--- a/media/java/android/media/tv/tuner/filter/RecordSettings.java
+++ b/media/java/android/media/tv/tuner/filter/RecordSettings.java
@@ -133,8 +133,11 @@
      * according to ISO/IEC 13818-1.
      * @hide
      */
-    @IntDef(flag = true, value = {SC_INDEX_I_FRAME, SC_INDEX_P_FRAME, SC_INDEX_B_FRAME,
-            SC_INDEX_SEQUENCE})
+    @IntDef(prefix = "SC_INDEX_",
+            flag = true,
+            value = {SC_INDEX_I_FRAME, SC_INDEX_P_FRAME, SC_INDEX_B_FRAME,
+                    SC_INDEX_SEQUENCE, SC_INDEX_I_SLICE, SC_INDEX_P_SLICE,
+                    SC_INDEX_B_SLICE, SC_INDEX_SI_SLICE, SC_INDEX_SP_SLICE})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ScIndex {}
 
@@ -154,7 +157,31 @@
      * SC index for a new sequence.
      */
     public static final int SC_INDEX_SEQUENCE = Constants.DemuxScIndex.SEQUENCE;
-
+    /**
+     * All blocks are coded as I blocks.
+     */
+    public static final int SC_INDEX_I_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.I_SLICE;
+    /**
+     * Blocks are coded as I or P blocks.
+     */
+    public static final int SC_INDEX_P_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.P_SLICE;
+    /**
+     * Blocks are coded as I, P or B blocks.
+     */
+    public static final int SC_INDEX_B_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.B_SLICE;
+    /**
+     * A so-called switching I slice that is coded.
+     */
+    public static final int SC_INDEX_SI_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.SI_SLICE;
+    /**
+     * A so-called switching P slice that is coded.
+     */
+    public static final int SC_INDEX_SP_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.SP_SLICE;
 
     /**
      * Indexes can be tagged by NAL unit group in HEVC according to ISO/IEC 23008-2.
diff --git a/media/java/android/media/tv/tuner/filter/TsRecordEvent.java b/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
index 258e2f2..6ea3bf8 100644
--- a/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
+++ b/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
@@ -33,14 +33,17 @@
     private final int mScIndexMask;
     private final long mDataLength;
     private final long mPts;
+    private final int mFirstMbInSlice;
 
     // This constructor is used by JNI code only
-    private TsRecordEvent(int pid, int tsIndexMask, int scIndexMask, long dataLength, long pts) {
+    private TsRecordEvent(int pid, int tsIndexMask, int scIndexMask, long dataLength, long pts,
+            int firstMbInSlice) {
         mPid = pid;
         mTsIndexMask = tsIndexMask;
         mScIndexMask = scIndexMask;
         mDataLength = dataLength;
         mPts = pts;
+        mFirstMbInSlice = firstMbInSlice;
     }
 
     /**
@@ -77,10 +80,26 @@
 
     /**
      * Gets the Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
-     * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and
-     * the SC_HEVC.
+     * and has the same format as the PTS in ISO/IEC 13818-1.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner.INVALID_TIMESTAMP}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker.getTunerVersion()} to get the version
+     * information.
      */
     public long getPts() {
         return mPts;
     }
+
+    /**
+     * Get the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner.INVALID_FIRST_MACROBLOCK_IN_SLICE}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker.getTunerVersion()} to get the version
+     * information.
+     */
+    public int getFirstMbInSlice() {
+        return mFirstMbInSlice;
+    }
 }
diff --git a/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
index fadc004..98f8096 100644
--- a/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
@@ -341,12 +341,13 @@
         return mScanType;
     }
     /**
-     * To receive Diseqc Message or not. Default value is false.
+     * Get if the client could handle the Diseqc Rx Message or not. Default value is false.
      *
-     * The setter {@link Builder#setDiseqcRxMessage(boolean)} is only supported with Tuner HAL 1.1
-     * or higher.
+     * The setter {@link Builder#setCouldHandleDiseqcRxMessage(boolean)} is only supported with
+     * Tuner HAL 1.1 or higher. Use {@link TunerVersionChecker.getTunerVersion()} to check the
+     * version.
      */
-    public boolean isDiseqcRxMessage() {
+    public boolean getCouldHandleDiseqcRxMessage() {
         return mIsDiseqcRxMessage;
     }
 
@@ -408,16 +409,18 @@
         }
 
         /**
-         * Set true to receive Diseqc Message.
+         * Set true to indicate the client could handle the Diseqc Messages. Note that it's still
+         * possible that the client won't receive the messages when HAL is not able to setup Rx
+         * channel in the hardware layer.
          *
          * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
          * no-op. Use {@link TunerVersionChecker.getTunerVersion()} to check the version.
          */
         @NonNull
-        public Builder setDiseqcRxMessage(boolean isDiseqcRxMessage) {
+        public Builder setCouldHandleDiseqcRxMessage(boolean couldReceiveDiseqcMessage) {
             if (TunerVersionChecker.checkHigherOrEqualVersionTo(
-                        TunerVersionChecker.TUNER_VERSION_1_1, "setDiseqcRxMessage")) {
-                mIsDiseqcRxMessage = isDiseqcRxMessage;
+                        TunerVersionChecker.TUNER_VERSION_1_1, "setCouldHandleDiseqcRxMessage")) {
+                mIsDiseqcRxMessage = couldReceiveDiseqcMessage;
             }
             return this;
         }
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendSettings.java b/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
index 2147622..f8470b11 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
@@ -302,6 +302,7 @@
      *
      * @return the end frequency in Hz.
      */
+    @IntRange(from = 1)
     public int getEndFrequency() {
         return mEndFrequency;
     }
@@ -341,11 +342,15 @@
      *
      * @param endFrequency the end frequency used during blind scan. The default value is
      * {@link android.media.tv.tuner.Tuner#INVALID_FRONTEND_SETTING_FREQUENCY}.
+     * @throws IllegalArgumentException if the {@code endFrequency} is not greater than 0.
      */
     @IntRange(from = 1)
     public void setEndFrequency(int endFrequency) {
         if (TunerVersionChecker.checkHigherOrEqualVersionTo(
                 TunerVersionChecker.TUNER_VERSION_1_1, "setEndFrequency")) {
+            if (endFrequency < 1) {
+                throw new IllegalArgumentException("endFrequency must be greater than 0");
+            }
             mEndFrequency = endFrequency;
         }
     }
diff --git a/media/java/android/media/tv/tuner/frontend/ScanCallback.java b/media/java/android/media/tv/tuner/frontend/ScanCallback.java
index 9bf7a5d..27627d7 100644
--- a/media/java/android/media/tv/tuner/frontend/ScanCallback.java
+++ b/media/java/android/media/tv/tuner/frontend/ScanCallback.java
@@ -75,4 +75,7 @@
 
     /** Frontend scan message priority reported. */
     default void onPriorityReported(boolean isHighPriority) {}
+
+    /** DVBC Frontend Annex reported. */
+    default void onDvbcAnnexReported(@DvbcFrontendSettings.Annex int dvbcAnnex) {}
 }
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 724965d..c7fb50f 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -31,6 +31,8 @@
     ],
 
     shared_libs: [
+        "audioclient-types-aidl-unstable-cpp",
+        "av-types-aidl-unstable-cpp",
         "libandroid_runtime",
         "libaudioclient",
         "libnativehelper",
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 27e1992..758f015 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -605,9 +605,13 @@
 
         jlong pts = (eventsExt.size() > i) ? static_cast<jlong>(eventsExt[i].tsRecord().pts)
                 : static_cast<jlong>(Constant64Bit::INVALID_PRESENTATION_TIME_STAMP);
+        jlong firstMbInSlice = (eventsExt.size() > i)
+                ? static_cast<jint>(eventsExt[i].tsRecord().firstMbInSlice)
+                : static_cast<jint>(Constant::INVALID_FIRST_MACROBLOCK_IN_SLICE);
 
         jobject obj =
-                env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber, pts);
+                env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber,
+                        pts, firstMbInSlice);
         env->SetObjectArrayElement(arr, i, obj);
     }
     return arr;
@@ -632,10 +636,13 @@
                 : static_cast<jint>(Constant::INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM);
         jlong pts = (eventsExt.size() > i) ? static_cast<jlong>(eventsExt[i].mmtpRecord().pts)
                 : static_cast<jlong>(Constant64Bit::INVALID_PRESENTATION_TIME_STAMP);
+        jlong firstMbInSlice = (eventsExt.size() > i)
+                ? static_cast<jint>(eventsExt[i].mmtpRecord().firstMbInSlice)
+                : static_cast<jint>(Constant::INVALID_FIRST_MACROBLOCK_IN_SLICE);
 
         jobject obj =
                 env->NewObject(eventClazz, eventInit, scHevcIndexMask, byteNumber,
-                        mpuSequenceNumber, pts);
+                        mpuSequenceNumber, pts, firstMbInSlice);
         env->SetObjectArrayElement(arr, i, obj);
     }
     return arr;
@@ -1058,10 +1065,18 @@
             bool isHighPriority = message.isHighPriority();
             env->CallVoidMethod(
                     mObject,
-                    env->GetMethodID(clazz, "onPriorityReported", "([B)V"),
+                    env->GetMethodID(clazz, "onPriorityReported", "(B)V"),
                     isHighPriority);
             break;
         }
+        case FrontendScanMessageTypeExt1_1::DVBC_ANNEX: {
+            jint dvbcAnnex = (jint) message.annex();
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onDvbcAnnexReported", "(I)V"),
+                    dvbcAnnex);
+            break;
+        }
         default:
             break;
     }
diff --git a/media/packages/BluetoothMidiService/tests/unit/Android.bp b/media/packages/BluetoothMidiService/tests/unit/Android.bp
index 4d4ae9e..fa4612b 100644
--- a/media/packages/BluetoothMidiService/tests/unit/Android.bp
+++ b/media/packages/BluetoothMidiService/tests/unit/Android.bp
@@ -20,7 +20,6 @@
     certificate: "platform",
     static_libs: [
         //"frameworks-base-testutils",
-        "android-support-test",
         "androidx.test.core",
         "androidx.test.ext.truth",
         "androidx.test.runner",
diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp
index 234462f..3f1954a 100644
--- a/media/tests/MediaFrameworkTest/Android.bp
+++ b/media/tests/MediaFrameworkTest/Android.bp
@@ -10,7 +10,6 @@
         "androidx.test.ext.junit",
         "androidx.test.rules",
         "android-ex-camera2",
-        "android-support-test",
         "testng"
     ],
     platform_apis: true,
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
index 4d0c258..a439b79 100644
--- a/media/tests/MediaRouter/Android.bp
+++ b/media/tests/MediaRouter/Android.bp
@@ -9,7 +9,7 @@
     ],
 
     static_libs: [
-        "android-support-test",
+        "androidx.test.rules",
         "mockito-target-minus-junit4",
         "testng",
         "truth-prebuilt",
diff --git a/media/tests/MediaRouter/AndroidManifest.xml b/media/tests/MediaRouter/AndroidManifest.xml
index d9806f3..02688d5 100644
--- a/media/tests/MediaRouter/AndroidManifest.xml
+++ b/media/tests/MediaRouter/AndroidManifest.xml
@@ -27,7 +27,7 @@
         </service>
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                      android:targetPackage="com.android.mediaroutertest"
                      android:label="MediaRouter Tests"/>
 </manifest>
diff --git a/media/tests/MediaRouter/AndroidTest.xml b/media/tests/MediaRouter/AndroidTest.xml
index 1301062..d350e05 100644
--- a/media/tests/MediaRouter/AndroidTest.xml
+++ b/media/tests/MediaRouter/AndroidTest.xml
@@ -10,7 +10,7 @@
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="com.android.mediaroutertest"/>
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouteInfoTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouteInfoTest.java
index 92e4c95..255b95f 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouteInfoTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouteInfoTest.java
@@ -20,13 +20,14 @@
 
 import android.hardware.display.DisplayManagerGlobal;
 import android.media.MediaRouter;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.Display;
 import android.view.DisplayAddress;
 import android.view.DisplayAdjustments;
 import android.view.DisplayInfo;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
index ddefe26..1286fc1 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
@@ -52,12 +52,13 @@
 import android.media.RouteDiscoveryPreference;
 import android.media.RoutingSessionInfo;
 import android.os.Bundle;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.text.TextUtils;
 
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/RoutingSessionInfoTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/RoutingSessionInfoTest.java
index 31f240d..77b3160 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/RoutingSessionInfoTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/RoutingSessionInfoTest.java
@@ -20,8 +20,9 @@
 import static org.junit.Assert.assertNotEquals;
 
 import android.media.RoutingSessionInfo;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/media/tests/MediaTranscodingTest/Android.bp b/media/tests/MediaTranscodingTest/Android.bp
index 907c3c8..bd687a1 100644
--- a/media/tests/MediaTranscodingTest/Android.bp
+++ b/media/tests/MediaTranscodingTest/Android.bp
@@ -9,7 +9,7 @@
         "androidx.test.ext.junit",
         "androidx.test.rules",
         "androidx.test.uiautomator_uiautomator",
-        "android-support-test",
+        "androidx.test.rules",
         "testng"
     ],
     platform_apis: true,
diff --git a/media/tests/TunerTest/Android.bp b/media/tests/TunerTest/Android.bp
index cef8791..e865604 100644
--- a/media/tests/TunerTest/Android.bp
+++ b/media/tests/TunerTest/Android.bp
@@ -9,7 +9,7 @@
     ],
 
     static_libs: [
-        "android-support-test",
+        "androidx.test.rules",
         "testng"
     ],
 
diff --git a/media/tests/TunerTest/AndroidManifest.xml b/media/tests/TunerTest/AndroidManifest.xml
index 17e9f19..ec155ca 100644
--- a/media/tests/TunerTest/AndroidManifest.xml
+++ b/media/tests/TunerTest/AndroidManifest.xml
@@ -23,7 +23,7 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                      android:targetPackage="com.android.mediatunertest"
                      android:label="Media Tuner Tests"/>
 </manifest>
diff --git a/media/tests/TunerTest/AndroidTest.xml b/media/tests/TunerTest/AndroidTest.xml
index d9c31f45..c718b15 100644
--- a/media/tests/TunerTest/AndroidTest.xml
+++ b/media/tests/TunerTest/AndroidTest.xml
@@ -12,6 +12,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="com.android.mediatunertest"/>
         <option name="hidden-api-checks" value="false"/>
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
     </test>
 </configuration>
diff --git a/media/tests/TunerTest/src/com/android/mediatunertest/TunerTest.java b/media/tests/TunerTest/src/com/android/mediatunertest/TunerTest.java
index afdbce0..de7f7eb 100644
--- a/media/tests/TunerTest/src/com/android/mediatunertest/TunerTest.java
+++ b/media/tests/TunerTest/src/com/android/mediatunertest/TunerTest.java
@@ -21,9 +21,10 @@
 import android.content.Context;
 import android.media.tv.tuner.Descrambler;
 import android.media.tv.tuner.Tuner;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/packages/CarSystemUI/res/values-ca/strings.xml b/packages/CarSystemUI/res/values-ca/strings.xml
index cbd469b..c151d48 100644
--- a/packages/CarSystemUI/res/values-ca/strings.xml
+++ b/packages/CarSystemUI/res/values-ca/strings.xml
@@ -24,7 +24,7 @@
     <string name="start_guest_session" msgid="497784785761754874">"Convidat"</string>
     <string name="car_add_user" msgid="4067337059622483269">"Afegeix un usuari"</string>
     <string name="car_new_user" msgid="6637442369728092473">"Usuari nou"</string>
-    <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai."</string>
+    <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquesta persona ha de configurar el seu espai."</string>
     <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
     <string name="car_loading_profile" msgid="4507385037552574474">"S\'està carregant"</string>
     <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"S\'està carregant l\'usuari (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-es-rUS/strings.xml b/packages/CarSystemUI/res/values-es-rUS/strings.xml
index 16aba86..e067594 100644
--- a/packages/CarSystemUI/res/values-es-rUS/strings.xml
+++ b/packages/CarSystemUI/res/values-es-rUS/strings.xml
@@ -25,7 +25,7 @@
     <string name="car_add_user" msgid="4067337059622483269">"Agregar usuario"</string>
     <string name="car_new_user" msgid="6637442369728092473">"Usuario nuevo"</string>
     <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando agregues un usuario nuevo, esa persona deberá configurar su espacio."</string>
-    <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario podrá actualizar las apps de otras personas."</string>
+    <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
     <string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string>
     <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
     <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Cerrar"</string>
diff --git a/packages/CarSystemUI/res/values-fi/strings.xml b/packages/CarSystemUI/res/values-fi/strings.xml
index 79b53f6..4c20f85 100644
--- a/packages/CarSystemUI/res/values-fi/strings.xml
+++ b/packages/CarSystemUI/res/values-fi/strings.xml
@@ -25,7 +25,7 @@
     <string name="car_add_user" msgid="4067337059622483269">"Lisää käyttäjä"</string>
     <string name="car_new_user" msgid="6637442369728092473">"Uusi käyttäjä"</string>
     <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kun lisäät uuden käyttäjän, hänen on valittava oman tilansa asetukset."</string>
-    <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia."</string>
+    <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
     <string name="car_loading_profile" msgid="4507385037552574474">"Ladataan"</string>
     <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ladataan käyttäjäprofiilia (<xliff:g id="FROM_USER">%1$d</xliff:g>–<xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
     <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Sulje"</string>
diff --git a/packages/CarSystemUI/res/values-in/strings.xml b/packages/CarSystemUI/res/values-in/strings.xml
index 386d79e..60525ad 100644
--- a/packages/CarSystemUI/res/values-in/strings.xml
+++ b/packages/CarSystemUI/res/values-in/strings.xml
@@ -24,7 +24,7 @@
     <string name="start_guest_session" msgid="497784785761754874">"Tamu"</string>
     <string name="car_add_user" msgid="4067337059622483269">"Tambahkan Pengguna"</string>
     <string name="car_new_user" msgid="6637442369728092473">"Pengguna Baru"</string>
-    <string name="user_add_user_message_setup" msgid="1035578846007352323">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri."</string>
+    <string name="user_add_user_message_setup" msgid="1035578846007352323">"Jika ditambahkan, pengguna baru harus menyiapkan ruangnya sendiri."</string>
     <string name="user_add_user_message_update" msgid="7061671307004867811">"Setiap pengguna dapat mengupdate aplikasi untuk semua pengguna lain."</string>
     <string name="car_loading_profile" msgid="4507385037552574474">"Memuat"</string>
     <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuat pengguna (dari <xliff:g id="FROM_USER">%1$d</xliff:g> menjadi <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-kk/strings.xml b/packages/CarSystemUI/res/values-kk/strings.xml
index 2dd1b66..313fe81 100644
--- a/packages/CarSystemUI/res/values-kk/strings.xml
+++ b/packages/CarSystemUI/res/values-kk/strings.xml
@@ -24,7 +24,7 @@
     <string name="start_guest_session" msgid="497784785761754874">"Қонақ"</string>
     <string name="car_add_user" msgid="4067337059622483269">"Пайдаланушыны енгізу"</string>
     <string name="car_new_user" msgid="6637442369728092473">"Жаңа пайдаланушы"</string>
-    <string name="user_add_user_message_setup" msgid="1035578846007352323">"Енгізілген жаңа пайдаланушы өз профилін реттеуі керек."</string>
+    <string name="user_add_user_message_setup" msgid="1035578846007352323">"Қосылған жаңа пайдаланушы өз профилін реттеуі керек."</string>
     <string name="user_add_user_message_update" msgid="7061671307004867811">"Кез келген пайдаланушы қолданбаларды басқа пайдаланушылар үшін жаңарта алады."</string>
     <string name="car_loading_profile" msgid="4507385037552574474">"Жүктелуде"</string>
     <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Пайдаланушы профилі жүктелуде (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
diff --git a/packages/CarSystemUI/res/values-ky/strings.xml b/packages/CarSystemUI/res/values-ky/strings.xml
index dd9225a..74150d0 100644
--- a/packages/CarSystemUI/res/values-ky/strings.xml
+++ b/packages/CarSystemUI/res/values-ky/strings.xml
@@ -25,7 +25,7 @@
     <string name="car_add_user" msgid="4067337059622483269">"Колдонуучу кошуу"</string>
     <string name="car_new_user" msgid="6637442369728092473">"Жаңы колдонуучу"</string>
     <string name="user_add_user_message_setup" msgid="1035578846007352323">"Жаңы колдонуучу кошулганда, ал өзүнүн профилин жөндөп алышы керек."</string>
-    <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу калган бардык колдонуучулар үчүн да жаңырта алат."</string>
+    <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
     <string name="car_loading_profile" msgid="4507385037552574474">"Жүктөлүүдө"</string>
     <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Колдонуучу тууралуу маалымат жүктөлүүдө (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
     <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Жабуу"</string>
diff --git a/packages/CarSystemUI/res/values-sk/strings.xml b/packages/CarSystemUI/res/values-sk/strings.xml
index b100a5d4..80b9b5e 100644
--- a/packages/CarSystemUI/res/values-sk/strings.xml
+++ b/packages/CarSystemUI/res/values-sk/strings.xml
@@ -25,7 +25,7 @@
     <string name="car_add_user" msgid="4067337059622483269">"Pridať používateľa"</string>
     <string name="car_new_user" msgid="6637442369728092473">"Nový používateľ"</string>
     <string name="user_add_user_message_setup" msgid="1035578846007352323">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor."</string>
-    <string name="user_add_user_message_update" msgid="7061671307004867811">"Ktorýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
+    <string name="user_add_user_message_update" msgid="7061671307004867811">"Každý používateľ môže aktualizovať aplikácie pre všetkých ostatných používateľov."</string>
     <string name="car_loading_profile" msgid="4507385037552574474">"Načítava sa"</string>
     <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Načítava sa používateľ (predchádzajúci: <xliff:g id="FROM_USER">%1$d</xliff:g>, nasledujúci: <xliff:g id="TO_USER">%2$d</xliff:g>)"</string>
     <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zavrieť"</string>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index 3def945..ec1240f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -17,7 +17,6 @@
 package com.android.systemui;
 
 import com.android.systemui.biometrics.AuthController;
-import com.android.systemui.bubbles.dagger.BubbleModule;
 import com.android.systemui.car.navigationbar.CarNavigationBar;
 import com.android.systemui.car.notification.CarNotificationModule;
 import com.android.systemui.car.sideloaded.SideLoadedAppController;
@@ -48,8 +47,7 @@
 
 /** Binder for car specific {@link SystemUI} modules. */
 @Module(includes = {RecentsModule.class, StatusBarModule.class, NotificationsModule.class,
-        BubbleModule.class, KeyguardModule.class, OverlayWindowModule.class,
-        CarNotificationModule.class})
+        KeyguardModule.class, OverlayWindowModule.class, CarNotificationModule.class})
 public abstract class CarSystemUIBinder {
     /** Inject into AuthController. */
     @Binds
diff --git a/packages/DynamicSystemInstallationService/res/values-af/strings.xml b/packages/DynamicSystemInstallationService/res/values-af/strings.xml
index 1b300358..c5f21cb 100644
--- a/packages/DynamicSystemInstallationService/res/values-af/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-af/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Herbegin"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Het dinamiese stelsel weggegooi"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Kan nie dinamiese stelsel herbegin of laai nie"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Kon nie dinamiese stelsel deaktiveer nie"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-am/strings.xml b/packages/DynamicSystemInstallationService/res/values-am/strings.xml
index a8a7b00..d0fc3cc 100644
--- a/packages/DynamicSystemInstallationService/res/values-am/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-am/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ዳግም ጀምር"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"የተጣለ ተለዋዋጭ ሥርዓት"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ዳግም ማስጀመር አይቻልም ወይም ተለዋዋጭ ሥርዓትን ይስቀሉ"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ተለዋዋጭ ስርዓትን ማሰናከል አልተሳካም"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ar/strings.xml b/packages/DynamicSystemInstallationService/res/values-ar/strings.xml
index 44a6503..279cba1 100644
--- a/packages/DynamicSystemInstallationService/res/values-ar/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ar/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"النظام الديناميكي جاهز. لبدء استخدامه، يجب إعادة تشغيل الجهاز."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"التثبيت قيد التقدّم."</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"تعذّر التثبيت."</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"تعذّر التحقّق من الصورة. يجب إلغاء التثبيت."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"تعذّر التحقّق من النسخة. يجب إلغاء التثبيت."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"‏يتم الآن تشغيل نظام ديناميكي. يجب إعادة التشغيل لاستخدام الإصدار الأصلي لنظام Android."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"إلغاء"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"تجاهل"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"إعادة التشغيل"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"تم تجاهل النظام الديناميكي."</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"لا يمكن إعادة التشغيل أو تحميل النظام الديناميكي."</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"تعذّر إيقاف النظام الديناميكي."</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-as/strings.xml b/packages/DynamicSystemInstallationService/res/values-as/strings.xml
index e93ad9b..13c8abc 100644
--- a/packages/DynamicSystemInstallationService/res/values-as/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-as/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ৰিষ্টাৰ্ট কৰক"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"বাতিল কৰা ডায়নামিক ছিষ্টেম"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ডায়নামিক ছিষ্টেম ৰিষ্টার্ট অথবা ল\'ড কৰিব নোৱাৰি"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ডায়নামিক ছিষ্টেম অক্ষম কৰিব পৰা নগ’ল"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-az/strings.xml b/packages/DynamicSystemInstallationService/res/values-az/strings.xml
index ad3d3e7..159794e 100644
--- a/packages/DynamicSystemInstallationService/res/values-az/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-az/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Yenidən başladın"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamik sistemdən imtina edildi"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dinamik sistemi yenidən başlatmaq və ya yükləmək mümkün deyil"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dinamik sistemi deaktiv etmək alınmadı"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
index 0107047..0e770da 100644
--- a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"Dinamični sistem je spreman. Da biste počeli da ga koristite, restartujte uređaj."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalira se"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Instaliranje nije uspelo"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Validacija slike nije uspela. Otkažite instalaciju."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Validacija slike diska nije uspela. Otkažite instalaciju."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Trenutno je pokrenut dinamični sistem. Restartujte da biste koristili originalnu verziju Android-a."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Otkaži"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Odbaci"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restartuj"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamični sistem je odbačen"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Restartovanje ili učitavanje dinamičnog sistema nije uspelo"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Onemogućavanje dinamičnog sistema nije uspelo"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-be/strings.xml b/packages/DynamicSystemInstallationService/res/values-be/strings.xml
index 5a52f73..2044655a 100644
--- a/packages/DynamicSystemInstallationService/res/values-be/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-be/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Перазапусціць"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Дынамічная сістэма адхілена"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Не ўдалося перазапусціць або загрузіць дынамічную сістэму"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Не ўдалося адключыць дынамічную сістэму"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-bg/strings.xml b/packages/DynamicSystemInstallationService/res/values-bg/strings.xml
index 194bf2d..f8c4fd9 100644
--- a/packages/DynamicSystemInstallationService/res/values-bg/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-bg/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Рестартиране"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамичната система е отхвърлена"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Динамичната система не може да се рестартира или зареди"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Деактивирането на динамичната система не бе успешно"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-bn/strings.xml b/packages/DynamicSystemInstallationService/res/values-bn/strings.xml
index 43886b3..f44dd74 100644
--- a/packages/DynamicSystemInstallationService/res/values-bn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-bn/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"রিস্টার্ট করুন"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ডায়নামিক সিস্টেম বাতিল করা হয়েছে"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ডায়নামিক সিস্টেম রিস্টার্ট বা লোড করা যাচ্ছে না"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ডায়নামিক সিস্টেম বন্ধ করা যায়নি"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-bs/strings.xml b/packages/DynamicSystemInstallationService/res/values-bs/strings.xml
index 342230b2..9eb2ec7 100644
--- a/packages/DynamicSystemInstallationService/res/values-bs/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-bs/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Ponovo pokreni"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamični sistem je odbačen"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nije moguće ponovo pokrenuti ili učitati dinamični sistem"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Onemogućavanje dinamičnog sistema nije uspjelo"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ca/strings.xml b/packages/DynamicSystemInstallationService/res/values-ca/strings.xml
index e9e4d35..da6bd8a 100644
--- a/packages/DynamicSystemInstallationService/res/values-ca/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ca/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reinicia"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"S\'ha descartat el sistema dinàmic"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"No es pot reiniciar ni carregar el sistema dinàmic"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"No s\'ha pogut desactivar el sistema dinàmic"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-cs/strings.xml b/packages/DynamicSystemInstallationService/res/values-cs/strings.xml
index 6ae71c6..b8a7f37 100644
--- a/packages/DynamicSystemInstallationService/res/values-cs/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-cs/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restartovat"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Zahodit dynamický systém"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dynamický systém nelze znovu spustit nebo načíst"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dynamický systém se nepodařilo deaktivovat"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-da/strings.xml b/packages/DynamicSystemInstallationService/res/values-da/strings.xml
index 10b798c..252ae5a 100644
--- a/packages/DynamicSystemInstallationService/res/values-da/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-da/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"Det dynamiske system er klar. Hvis du vil begynde at bruge det, skal du genstarte din enhed."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation i gang"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Installationen mislykkedes"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Billedet kunne ikke valideres. Afbryd installationen."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Systembilledet kunne ikke valideres. Afbryd installationen."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Der køres i øjeblikket et dynamisk system. Genstart for at bruge den oprindelige Android-version."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Annuller"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Afbryd"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Genstart"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Det dynamiske system blev slettet"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Det dynamiske system kan ikke genstartes eller indlæses"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Det dynamiske system kunne ikke deaktiveres"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-de/strings.xml b/packages/DynamicSystemInstallationService/res/values-de/strings.xml
index 82459b2..382fc01 100644
--- a/packages/DynamicSystemInstallationService/res/values-de/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-de/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Neu starten"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamisches System verworfen"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Neustart und Laden des dynamischen Systems nicht möglich"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Fehler beim Deaktivieren des dynamischen Systems"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-el/strings.xml b/packages/DynamicSystemInstallationService/res/values-el/strings.xml
index ef02906..61dfd34 100644
--- a/packages/DynamicSystemInstallationService/res/values-el/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-el/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Επανεκκίνηση"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Οι δυναμικές συστήματος απορρίφθηκαν."</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Δεν είναι δυνατή η επανεκκίνηση ή η φόρτωση δυναμικών συστήματος"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Απέτυχε η απενεργοποίηση των δυναμικών συστήματος"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml
index 6f3f887..62dba98 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Failed to disable dynamic system"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml
index 6f3f887..62dba98 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Failed to disable dynamic system"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml
index 6f3f887..62dba98 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Failed to disable dynamic system"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml
index 6f3f887..62dba98 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restart"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Discarded dynamic system"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Can’t restart or load dynamic system"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Failed to disable dynamic system"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml b/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml
index aeb65be..1d8a48b 100644
--- a/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Se descartó el sistema dinámico"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"No se puede reiniciar o cargar el sistema dinámico"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"No se pudo inhabilitar el sistema dinámico"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-es/strings.xml b/packages/DynamicSystemInstallationService/res/values-es/strings.xml
index 0c3ae53..fe47884 100644
--- a/packages/DynamicSystemInstallationService/res/values-es/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-es/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Se ha descartado el sistema dinámico"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"No se ha podido reiniciar o cargar el sistema dinámico"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"No se ha podido inhabilitar el sistema dinámico"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-et/strings.xml b/packages/DynamicSystemInstallationService/res/values-et/strings.xml
index ab20a04..058d6b9 100644
--- a/packages/DynamicSystemInstallationService/res/values-et/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-et/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Taaskäivita"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dünaamilisest süsteemist loobuti"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dünaamilist süsteemi ei saa taaskäivitada ega laadida"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dünaamilise süsteemi keelamine ebaõnnestus"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-eu/strings.xml b/packages/DynamicSystemInstallationService/res/values-eu/strings.xml
index 1863778..6576edd 100644
--- a/packages/DynamicSystemInstallationService/res/values-eu/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-eu/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Berrabiarazi"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Baztertu da sistema dinamikoa"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Ezin da berrabiarazi edo kargatu sistema dinamikoa"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Ezin izan da desgaitu sistema dinamikoa"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-fa/strings.xml b/packages/DynamicSystemInstallationService/res/values-fa/strings.xml
index 5b0b218..9c97687 100644
--- a/packages/DynamicSystemInstallationService/res/values-fa/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fa/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"بازراه‌اندازی"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"از سیستم پویا صرف‌نظر شد"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"نمی‌توان سیستم پویا را بازراه‌اندازی یا بار کرد"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"سیستم پویا غیرفعال نشد"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-fi/strings.xml b/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
index b4315e7..4cfac02 100644
--- a/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Käynn. uudelleen"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynaaminen järjestelmä hylätty"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dynaamista järjestelmää ei voi käynnistää uudelleen tai ladata"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dynaamisen järjestelmän käytöstäpoisto epäonnistui"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml b/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml
index 973efef..f5e394a 100644
--- a/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"Le système dynamique est prêt. Pour commencer à l\'utiliser, redémarrez votre appareil."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation en cours…"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Échec de l\'installation"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Impossible de valider l\'image. Annulation de l\'installation."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Impossible de valider l\'image. Annulez l\'installation."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Un système dynamique est en cours d\'exécution. Pour utiliser la version originale d\'Android, redémarrez l\'appareil."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Annuler"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Annuler"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Redémarrer"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Système dynamique supprimé"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Impossible de redémarrer ou de charger le système dynamique"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Échec de la désactivation du système dynamique"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-fr/strings.xml b/packages/DynamicSystemInstallationService/res/values-fr/strings.xml
index 5422e8e..c4cd92d 100644
--- a/packages/DynamicSystemInstallationService/res/values-fr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fr/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Redémarrer"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Système dynamique supprimé"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Impossible de redémarrer ou de charger le système dynamique"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Échec de la désactivation du système dynamique"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-gl/strings.xml b/packages/DynamicSystemInstallationService/res/values-gl/strings.xml
index e24f495a..58a80a7 100644
--- a/packages/DynamicSystemInstallationService/res/values-gl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-gl/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Descartouse o sistema dinámico"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Non se puido reiniciar nin cargar o sistema dinámico"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Produciuse un erro ao desactivar o sistema dinámico"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-gu/strings.xml b/packages/DynamicSystemInstallationService/res/values-gu/strings.xml
index 6c2e673..aa1c3c5 100644
--- a/packages/DynamicSystemInstallationService/res/values-gu/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-gu/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ફરી શરૂ કરો"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ડાઇનૅમિક સિસ્ટમ કાઢી નાખવામાં આવી"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ડાઇનૅમિક સિસ્ટમને ફરી શરૂ અથવા લોડ કરી શકાતી નથી"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ડાઇનૅમિક સિસ્ટમ બંધ કરવામાં નિષ્ફળ રહ્યાં"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-hi/strings.xml b/packages/DynamicSystemInstallationService/res/values-hi/strings.xml
index 13dc9e8..e2d535f 100644
--- a/packages/DynamicSystemInstallationService/res/values-hi/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-hi/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"रीस्टार्ट करें"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"डाइनैमिक सिस्टम खारिज किया गया"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"डाइनैमिक सिस्टम रीस्टार्ट या लोड नहीं हो सका"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"डाइनैमिक सिस्टम को बंद नहीं किया जा सका"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-hr/strings.xml b/packages/DynamicSystemInstallationService/res/values-hr/strings.xml
index 3318d20..f4b7f73 100644
--- a/packages/DynamicSystemInstallationService/res/values-hr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-hr/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Pokreni"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Odbačeni dinamični sustav"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nije moguće ponovno pokretanje ili učitavanje dinamičnog sustava"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Onemogućivanje dinamičnog sustava nije uspjelo"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-hu/strings.xml b/packages/DynamicSystemInstallationService/res/values-hu/strings.xml
index 208ab3b..b155fe2 100644
--- a/packages/DynamicSystemInstallationService/res/values-hu/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-hu/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Újraindítás"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Elvetett dinamikus rendszer"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nem lehet újraindítani vagy betölteni a dinamikus rendszert"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Nem sikerült kikapcsolni a dinamikus rendszert"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-hy/strings.xml b/packages/DynamicSystemInstallationService/res/values-hy/strings.xml
index 4dcc72e..287ea91 100644
--- a/packages/DynamicSystemInstallationService/res/values-hy/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-hy/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Վերագործարկել"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Դինամիկ համակարգի գործարկումը չեղարկվեց"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Չհաջողվեց վերագործարկել կամ բեռնել դինամիկ համակարգը"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Չհաջողվեց անջատել դինամիկ համակարգը"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-in/strings.xml b/packages/DynamicSystemInstallationService/res/values-in/strings.xml
index 2fa4f11..6986005 100644
--- a/packages/DynamicSystemInstallationService/res/values-in/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-in/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Mulai ulang"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamic System dihapus"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Tidak dapat memulai ulang atau memuat Dynamic System"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Gagal menonaktifkan sistem dinamis"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-is/strings.xml b/packages/DynamicSystemInstallationService/res/values-is/strings.xml
index ef7484c..e0a415b 100644
--- a/packages/DynamicSystemInstallationService/res/values-is/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-is/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Endurræsa"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Breytilegu kerfi fleygt"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Ekki tókst að endurræsa eða hlaða breytilegu kerfi"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Ekki tókst að slökkva á breytilegu kerfi"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-it/strings.xml b/packages/DynamicSystemInstallationService/res/values-it/strings.xml
index c8fa41b..2c91aeb 100644
--- a/packages/DynamicSystemInstallationService/res/values-it/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-it/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Riavvia"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistema dinamico annullato"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Impossibile riavviare o caricare il sistema dinamico"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Impossibile disattivare il sistema dinamico"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-iw/strings.xml b/packages/DynamicSystemInstallationService/res/values-iw/strings.xml
index d9bf983..2f539e3 100644
--- a/packages/DynamicSystemInstallationService/res/values-iw/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-iw/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"המערכת הדינמית מוכנה. כדי להתחיל להשתמש בה, יש להפעיל מחדש את המכשיר."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"ההתקנה מתבצעת"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"ההתקנה נכשלה"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"אימות התמונה נכשל. יש לבטל את ההתקנה."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"האימות של קובץ האימג\' נכשל. ההתקנה תבוטל."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"‏בשלב זה פועלת מערכת דינמית. כדי להשתמש בגרסת Android המקורית, יש לבצע הפעלה מחדש."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"ביטול"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"סגירה"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"הפעלה מחדש"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"המערכת הדינמית נסגרה"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"לא ניתן להפעיל מחדש או לטעון את המערכת הדינמית"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"השבתת המערכת הדינמית נכשלה"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ja/strings.xml b/packages/DynamicSystemInstallationService/res/values-ja/strings.xml
index 2082d91..2d5fc4f 100644
--- a/packages/DynamicSystemInstallationService/res/values-ja/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ja/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"再起動"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"動的システムを破棄しました"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"動的システムの再起動や読み込みを行えません"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"動的システムを無効にできませんでした"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ka/strings.xml b/packages/DynamicSystemInstallationService/res/values-ka/strings.xml
index e57de2c..6aea2f9 100644
--- a/packages/DynamicSystemInstallationService/res/values-ka/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ka/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"გადატვირთვა"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"გაუქმებული დინამიური სისტემა"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"დინამიური სისტემის გადატვირთვა ან ჩატვირთვა ვერ ხერხდება"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"დინამიკური სისტემის გათიშვა ვარ მოხერხდა"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-kk/strings.xml b/packages/DynamicSystemInstallationService/res/values-kk/strings.xml
index da10e9c..9aafc2f 100644
--- a/packages/DynamicSystemInstallationService/res/values-kk/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-kk/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Қайта қосу"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамикалық жүйе өшірілді."</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Динамикалық жүйені қайта қосу не жүктеу мүмкін емес."</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Динамикалық жүйе өшірілмеді."</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-km/strings.xml b/packages/DynamicSystemInstallationService/res/values-km/strings.xml
index 7bb5980..510d526 100644
--- a/packages/DynamicSystemInstallationService/res/values-km/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-km/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ចាប់ផ្ដើមឡើងវិញ"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"បានលុបចោល​ប្រព័ន្ធឌីណាមិច"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"មិនអាច​ចាប់ផ្ដើមឡើងវិញ ឬផ្ទុក​ប្រព័ន្ធឌីណាមិច​បានទេ"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"មិនអាចបិទ​ប្រព័ន្ធឌីណាមិច​បានទេ"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-kn/strings.xml b/packages/DynamicSystemInstallationService/res/values-kn/strings.xml
index f41f2ef..dffe22d 100644
--- a/packages/DynamicSystemInstallationService/res/values-kn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-kn/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ಮರುಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ಡೈನಮಿಕ್ ಸಿಸ್ಟಂ ಅನ್ನು ತ್ಯಜಿಸಲಾಗಿದೆ"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ಡೈನಾಮಿಕ್ ಸಿಸ್ಟಂ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಅಥವಾ ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ಡೈನಾಮಿಕ್ ಸಿಸ್ಟಂ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ko/strings.xml b/packages/DynamicSystemInstallationService/res/values-ko/strings.xml
index bca9e07..0db6d06 100644
--- a/packages/DynamicSystemInstallationService/res/values-ko/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ko/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"다시 시작"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"동적 시스템 삭제됨"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"동적 시스템을 다시 시작하거나 로드할 수 없음"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"동적 시스템을 사용 중지하는 데 실패함"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ky/strings.xml b/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
index d2ad56a..79734b7 100644
--- a/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Өчүрүп күйгүзүү"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамикалык система жоюлду"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Динамикалык система өчүрүлүп күйгүзүлбөй же жүктөлбөй жатат"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Динамикалык система өчпөй койду"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-lo/strings.xml b/packages/DynamicSystemInstallationService/res/values-lo/strings.xml
index a732aa4..0ee3990 100644
--- a/packages/DynamicSystemInstallationService/res/values-lo/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-lo/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"ລະບົບໄດນາມິກພ້ອມແລ້ວ. ກະລຸນາຣີສະຕາດອຸປະກອນຂອງທ່ານເພື່ອເລີ່ມນຳໃຊ້ມັນ."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"ກຳລັງຕິດຕັ້ງຢູ່"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"ຕິດຕັ້ງບໍ່ສຳເລັດ"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ການກວດສອບໄຟລ໌ຮູບບໍ່ສຳເລັດ. ຍົກເລີກການຕິດຕັ້ງ."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ກວດສອບໄຟລ໌ອິມເມກບໍ່ສຳເລັດ. ຍົກເລີກການຕິດຕັ້ງ."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ຕອນນີ້ກຳລັງໃຊ້ລະບົບໄດນາມິກ. ກະລຸນາຣີສະຕາດເພື່ອໃຊ້ເວີຊັນ Android ຕົ້ນສະບັບ."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"ຍົກເລີກ"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"ປິດໄວ້"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ຣີສະຕາດ"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ລະບົບໄດນາມິກທີ່ຍົກເລີກແລ້ວ"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ບໍ່ສາມາດຣີສະຕາດ ຫຼື ໂຫຼດລະບົບໄດນາມິກໄດ້"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ປິດການນຳໃຊ້ລະບົບໄດນາມິກບໍ່ສຳເລັດ"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-lt/strings.xml b/packages/DynamicSystemInstallationService/res/values-lt/strings.xml
index b25c62a..5673e8f 100644
--- a/packages/DynamicSystemInstallationService/res/values-lt/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-lt/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Pal. iš naujo"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinaminė sistema atmesta"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nepavyko paleisti iš naujo ar įkelti dinaminės sistemos"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Nepavyko išjungti dinaminės sistemos"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-lv/strings.xml b/packages/DynamicSystemInstallationService/res/values-lv/strings.xml
index 4ca6ace..4f83563 100644
--- a/packages/DynamicSystemInstallationService/res/values-lv/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-lv/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Restartēt"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamiskā sistēma tika atmesta"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nevar restartēt vai ielādēt dinamisko sistēmu"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Neizdevās atspējot dinamisko sistēmu."</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-mk/strings.xml b/packages/DynamicSystemInstallationService/res/values-mk/strings.xml
index 52a52a5..8742d2d 100644
--- a/packages/DynamicSystemInstallationService/res/values-mk/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-mk/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Рестартирај"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Отфрлен динамичен систем"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Не може да го рестартира или вчита динамичниот систем"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Не успеа да се оневозможи динамичниот систем"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ml/strings.xml b/packages/DynamicSystemInstallationService/res/values-ml/strings.xml
index 2504069..2d4824a 100644
--- a/packages/DynamicSystemInstallationService/res/values-ml/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ml/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"ഡെെനാമിക് സിസ്റ്റം തയ്യാറാണ്. അത് ഉപയോഗിച്ച് തുടങ്ങാൻ നിങ്ങളുടെ ഉപകരണം റീസ്റ്റാർട്ട് ചെയ്യുക."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"ഇൻസ്‌റ്റാൾ ചെയ്യൽ പുരോഗതിയിലാണ്"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"ഇൻസ്‌റ്റാൾ ചെയ്യാനായില്ല"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ചിത്രത്തിന്റെ മൂല്യനിർണ്ണയം നടത്താനായില്ല. ഇൻസ്‌റ്റലേഷൻ റദ്ദാക്കുക."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ഇമേജ് മൂല്യനിർണ്ണയം നടത്താനായില്ല. ഇൻസ്‌റ്റലേഷൻ റദ്ദാക്കുക."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"നിലവിൽ ഒരു ഡെെനാമിക് സിസ്റ്റം റൺ ചെയ്യുന്നുണ്ട്. ഒറിജിനൽ Android പതിപ്പ് ഉപയോഗിക്കാൻ റീസ്റ്റാർട്ട് ചെയ്യുക."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"റദ്ദാക്കുക"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"നിരസിക്കുക"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"റീസ്റ്റാർട്ട് ചെയ്യൂ"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ഡെെനാമിക് സിസ്റ്റം നിരസിച്ചു"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"റീസ്റ്റാർട്ട് ചെയ്യാനോ ഡെെനാമിക് സിസ്റ്റം ലോഡ് ചെയ്യാനോ ആവില്ല"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ഡൈനാമിക് സിസ്‌റ്റം പ്രവർത്തനരഹിതമാക്കാനായില്ല"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-mn/strings.xml b/packages/DynamicSystemInstallationService/res/values-mn/strings.xml
index fe93f65..367cc62 100644
--- a/packages/DynamicSystemInstallationService/res/values-mn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-mn/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Дахин эхлүүлэх"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамик системийг устгасан"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Динамик системийг дахин эхлүүлэх эсвэл ачаалах боломжгүй байна"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Динамик системийг идэвхгүй болгож чадсангүй"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-mr/strings.xml b/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
index 5f27af0..3b6741d 100644
--- a/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"डायनॅमिक सिस्टम तयार आहे. ती वापरणे सुरू करण्यासाठी, तुमचे डिव्हाइस रीस्टार्ट करा."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"इंस्टॉल प्रगतीपथावर आहे"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"इंस्टॉल करता आली नाही"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"इमेज प्रमाणीकरण करता आले नाही. इंस्टॉलेशन रद्द करा."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"इमेज प्रमाणित करता आली नाही. इंस्टॉलेशन रद्द करा."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"सध्या डायनॅमिक सिस्टम रन करत आहे. मूळ Android आवृत्ती वापरण्यासाठी रीस्टार्ट करा."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"रद्द करा"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"काढून टाका"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"रीस्टार्ट करा"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"डायनॅमिक सिस्टम काढून टाकली"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"डायनॅमिक सिस्टम रीस्टार्ट किंवा लोड करू शकत नाही"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"डायनॅमिक सिस्टम बंद करता आली नाही"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ms/strings.xml b/packages/DynamicSystemInstallationService/res/values-ms/strings.xml
index 797152c..17b2c70 100644
--- a/packages/DynamicSystemInstallationService/res/values-ms/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ms/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Mulakan semula"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistem dinamik dibuang"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Tidak dapat memulakan semula atau memuatkan sistem dinamik"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Gagal melumpuhkan sistem dinamik"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-my/strings.xml b/packages/DynamicSystemInstallationService/res/values-my/strings.xml
index 3ee85b2..809f4dc 100644
--- a/packages/DynamicSystemInstallationService/res/values-my/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-my/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"ပြောင်းလဲနိုင်သောစနစ် အသင့်ဖြစ်ပါပြီ။ ၎င်းကို စတင်အသုံးပြုရန် သင့်စက်ကို ပြန်စပါ။"</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"ထည့်သွင်းနေဆဲဖြစ်သည်"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"ထည့်သွင်း၍မရပါ"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ပုံအတည်ပြု၍ မရပါ။ ထည့်သွင်းမှုကို ရပ်ပါ။"</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ဒစ်ခ် မိတ္တူကို အတည်ပြု၍ မရပါ။ ထည့်သွင်းမှုကို ရပ်ပါ။"</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"လက်ရှိတွင် ပြောင်းလဲနိုင်သောစနစ်ကို အသုံးပြုနေသည်။ မူလ Android ဗားရှင်း အသုံးပြုရန် ပြန်စတင်ပါ။"</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"မလုပ်တော့"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"ဖယ်ပစ်ရန်"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ပြန်စရန်"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ပြောင်းလဲနိုင်သောစနစ်ကို ဖယ်လိုက်သည်"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ပြန်စ၍ မရပါ (သို့) ပြောင်းလဲနိုင်သောစနစ် ဖွင့်၍မရပါ"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ပြောင်းလဲနိုင်သောစနစ်ကို ပိတ်၍မရပါ"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-nb/strings.xml b/packages/DynamicSystemInstallationService/res/values-nb/strings.xml
index 88087e5..2f8fce8 100644
--- a/packages/DynamicSystemInstallationService/res/values-nb/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-nb/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"Det dynamiske systemet er klart. Start enheten din på nytt for å begynne å bruke det."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Installeringen pågår"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Installeringen mislyktes"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Bildebekreftelsen mislyktes. Avbryt installeringen."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Kunne ikke validere diskbildet. Avbryt installeringen."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Kjører et dynamisk system nå. Start på nytt for å bruke den opprinnelige Android-versjonen."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Avbryt"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Forkast"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Start på nytt"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Det dynamiske systemet er forkastet"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Det dynamiske systemet kan ikke startes på nytt eller lastes inn"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Kunne ikke slå av det dynamiske systemet"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ne/strings.xml b/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
index da98fee..e84329b 100644
--- a/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"रिस्टार्ट गर्नु…"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamic System खारेज गरियो"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"रिस्टार्ट गर्न वा Dynamic System लोड गर्न सकिएन"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"गतिशील प्रणाली अफ गर्न सकिएन"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
index 5120c90..3bf7247 100644
--- a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"Dynamisch systeem is klaar. Start je apparaat opnieuw op om het te gebruiken."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Installatie wordt uitgevoerd"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Installatie mislukt"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Valideren van afbeelding mislukt. Installatie afbreken."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Valideren van image mislukt. Installatie afbreken."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Er is momenteel een dynamisch systeem actief. Start je apparaat opnieuw op om de oorspronkelijke Android-versie te gebruiken."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Annuleren"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Niet opslaan"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Herstarten"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamisch systeem niet opgeslagen"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Kan dynamisch systeem niet opnieuw opstarten of laden"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Kan dynamisch systeem niet uitschakelen"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-or/strings.xml b/packages/DynamicSystemInstallationService/res/values-or/strings.xml
index 878947e..05b9016 100644
--- a/packages/DynamicSystemInstallationService/res/values-or/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-or/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ପ୍ରସ୍ତୁତ ଅଛି। ଏହାକୁ ବ୍ୟବହାର କରିବା ଆରମ୍ଭ କରିବାକୁ, ଆପଣଙ୍କ ଡିଭାଇସକୁ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ।"</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"ଇନଷ୍ଟଲ୍ ହେଉଛି"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"ଇନଷ୍ଟଲ୍ କରିବା ବିଫଳ ହୋଇଛି"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ଛବି ବୈଧକରଣ ବିଫଳ ହୋଇଛି। ଇନଷ୍ଟଲେସନ୍ ରଦ୍ଦ କରନ୍ତୁ।"</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ଇମେଜ୍ ବୈଧକରଣ ବିଫଳ ହୋଇଛି। ଇନଷ୍ଟଲେସନ୍ ରଦ୍ଦ କରନ୍ତୁ।"</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ବର୍ତ୍ତମାନ ଏକ ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଚାଲୁଛି। ମୂଳ Android ସଂସ୍କରଣ ବ୍ୟବହାର କରିବାକୁ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ।"</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"ବାତିଲ୍ କରନ୍ତୁ"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"ଖାରଜ କରନ୍ତୁ"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଖାରଜ କରାଯାଇଛି"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ରିଷ୍ଟାର୍ଟ କିମ୍ବା ଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଅକ୍ଷମ କରିବାରେ ବିଫଳ ହୋଇଛି"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pa/strings.xml b/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
index 2695aaf..8f2fd18 100644
--- a/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਤਿਆਰ ਹੈ। ਇਸ ਦੀ ਵਰਤੋਂ ਸ਼ੁਰੂ ਕਰਨ ਲਈ, ਆਪਣਾ ਡੀਵਾਈਸ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ।"</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"ਸਥਾਪਨਾ ਜਾਰੀ ਹੈ"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"ਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ਚਿੱਤਰ ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ ਰਹੀ। ਸਥਾਪਨਾ ਨੂੰ ਰੱਦ ਕਰੋ।"</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ਇਮੇਜ ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ ਰਹੀ। ਸਥਾਪਨਾ ਨੂੰ ਰੱਦ ਕਰੋ।"</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ਫ਼ਿਲਹਾਲ ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਚੱਲ ਰਿਹਾ ਹੈ। ਮੂਲ Android ਵਰਜਨ ਵਰਤਣ ਲਈ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ।"</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"ਰੱਦ ਕਰੋ"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"ਖਾਰਜ ਕਰੋ"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਰੱਦ ਕੀਤਾ ਗਿਆ"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਮੁੜ-ਸ਼ੁਰੂ ਜਾਂ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਨੂੰ ਬੰਦ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pl/strings.xml b/packages/DynamicSystemInstallationService/res/values-pl/strings.xml
index 33592c8..9aa4558 100644
--- a/packages/DynamicSystemInstallationService/res/values-pl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pl/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Uruchom ponownie"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Usunięto system dynamiczny"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nie można ponownie uruchomić lub wczytać systemu dynamicznego"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Nie udało się wyłączyć systemu dynamicznego"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml
index 43bd021..09ae30d 100644
--- a/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistema dinâmico descartado"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Não é possível reiniciar ou carregar o sistema dinâmico"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Falha ao desativar o sistema dinâmico"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml
index dc29a65..4b1a92c 100644
--- a/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"O sistema dinâmico está pronto. Para o começar a utilizar, reinicie o dispositivo."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Instalação em curso"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Falha na instalação"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Falha ao validar a imagem. A instalação foi interrompida."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Falha ao validar a imagem. Interrompa a instalação."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Está atualmente em execução um sistema dinâmico. Reinicie para utilizar a versão original do Android."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Cancelar"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Rejeitar"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistema dinâmico rejeitado"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Não é possível reiniciar ou carregar o sistema dinâmico."</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Falha ao desativar o sistema dinâmico"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pt/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt/strings.xml
index 43bd021..09ae30d 100644
--- a/packages/DynamicSystemInstallationService/res/values-pt/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pt/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reiniciar"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistema dinâmico descartado"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Não é possível reiniciar ou carregar o sistema dinâmico"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Falha ao desativar o sistema dinâmico"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ro/strings.xml b/packages/DynamicSystemInstallationService/res/values-ro/strings.xml
index c9d391a..27b88db 100644
--- a/packages/DynamicSystemInstallationService/res/values-ro/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ro/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reporniți"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"S-a renunțat la sistemul dinamic"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nu se poate reporni sau încărca sistemul dinamic"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Sistemul dinamic nu a fost dezactivat"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ru/strings.xml b/packages/DynamicSystemInstallationService/res/values-ru/strings.xml
index cba9a71..b36b4f9 100644
--- a/packages/DynamicSystemInstallationService/res/values-ru/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ru/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Перезапустить"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамическая система удалена."</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Не удается запустить или загрузить динамическую систему."</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Не удалось отключить динамическую систему."</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-si/strings.xml b/packages/DynamicSystemInstallationService/res/values-si/strings.xml
index 7aab6e9..e842d80 100644
--- a/packages/DynamicSystemInstallationService/res/values-si/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-si/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"යළි අරඹන්න"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ගතික පද්ධතිය ඉවත දමන ලදි"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ගතික පද්ධතිය නැවත ආරම්භ කිරීමට හෝ පූරණය කිරීමට නොහැක"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ගතික පද්ධතිය අබල කිරීමට අසමත් විය"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sk/strings.xml b/packages/DynamicSystemInstallationService/res/values-sk/strings.xml
index 61c176f..f2025fc 100644
--- a/packages/DynamicSystemInstallationService/res/values-sk/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sk/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Reštartovať"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Zahodený dynamický systém"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Nie je možné reštartovať alebo načítať dynamický systém"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dynamický systém sa nepodarilo deaktivovať"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sl/strings.xml b/packages/DynamicSystemInstallationService/res/values-sl/strings.xml
index 0be1248..1827a9d 100644
--- a/packages/DynamicSystemInstallationService/res/values-sl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sl/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Znova zaženi"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamični sistem je bil zavržen"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dinamičnega sistema ni mogoče znova zagnati ali naložiti"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dinamičnega sistema ni bilo mogoče onemogočiti"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sq/strings.xml b/packages/DynamicSystemInstallationService/res/values-sq/strings.xml
index 43a5f7b..581a9e1 100644
--- a/packages/DynamicSystemInstallationService/res/values-sq/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sq/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Rinis"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Sistemi dinamik u hoq"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Sistemi dinamik nuk mund të rinisej ose të ngarkohej"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Çaktivizimi i sistemit dinamik dështoi"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sr/strings.xml b/packages/DynamicSystemInstallationService/res/values-sr/strings.xml
index a5ba656..e0c6b2f 100644
--- a/packages/DynamicSystemInstallationService/res/values-sr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sr/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"Динамични систем је спреман. Да бисте почели да га користите, рестартујте уређај."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Инсталира се"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Инсталирање није успело"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Валидација слике није успела. Откажите инсталацију."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Валидација слике диска није успела. Откажите инсталацију."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Тренутно је покренут динамични систем. Рестартујте да бисте користили оригиналну верзију Android-а."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Откажи"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Одбаци"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Рестартуј"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамични систем је одбачен"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Рестартовање или учитавање динамичног система није успело"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Онемогућавање динамичног система није успело"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sv/strings.xml b/packages/DynamicSystemInstallationService/res/values-sv/strings.xml
index 99e6752..3da2b18 100644
--- a/packages/DynamicSystemInstallationService/res/values-sv/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sv/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"Det dynamiska systemet är klart. Om du vill använda det startar du om enheten."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Installation pågår"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Installationen misslyckades"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Bildvalideringen misslyckades. Avbryt installationen."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Valideringen av diskavbildningen misslyckades. Avbryt installationen."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Ett dynamiskt system körs. Om du vill använda den ursprungliga Android-versionen startar du om."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Avbryt"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Ignorera"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Starta om"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Det dynamiska systemet ignorerades"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Det gick inte att starta om eller läsa in det dynamiska systemet"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Det gick inte att inaktivera det dynamiska systemet"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sw/strings.xml b/packages/DynamicSystemInstallationService/res/values-sw/strings.xml
index 8af9ad3..8a92bd3 100644
--- a/packages/DynamicSystemInstallationService/res/values-sw/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sw/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Zima kisha uwashe"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Umeondoa Dynamic System"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Imeshindwa kuzima na kuwasha au kupakia Dynamic System"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Imeshindwa kuzima Dynamic System"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ta/strings.xml b/packages/DynamicSystemInstallationService/res/values-ta/strings.xml
index bbe8c4e..1a1f0a0 100644
--- a/packages/DynamicSystemInstallationService/res/values-ta/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ta/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"மீண்டும் தொடங்கு"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dynamic system நிராகரிக்கப்பட்டது"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dynamic systemமை மீண்டும் தொடங்கவோ ஏற்றவோ முடியவில்லை"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dynamic systemமை முடக்க இயலவில்லை"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-te/strings.xml b/packages/DynamicSystemInstallationService/res/values-te/strings.xml
index 4a9433e7..f014467 100644
--- a/packages/DynamicSystemInstallationService/res/values-te/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-te/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"రీస్టార్ట్ చేయి"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"డైనమిక్ సిస్టమ్ విస్మరించబడింది"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"డైనమిక్ సిస్టమ్‌ను రీస్టార్ట్ చేయడం లేదా లోడ్ చేయడం సాధ్యపడలేదు"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"డైనమిక్ సిస్టమ్‌ను డిజేబుల్ చేయడంలో విఫలమైంది"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-th/strings.xml b/packages/DynamicSystemInstallationService/res/values-th/strings.xml
index 5b81a03..24a55a9 100644
--- a/packages/DynamicSystemInstallationService/res/values-th/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-th/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"ระบบแบบไดนามิกพร้อมแล้ว โปรดรีสตาร์ทอุปกรณ์เพื่อเริ่มใช้"</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"กำลังติดตั้ง"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"ติดตั้งไม่สำเร็จ"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ตรวจสอบรูปภาพไม่สำเร็จ ล้มเลิกการติดตั้ง"</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"ตรวจสอบอิมเมจดิสก์ไม่สำเร็จ ล้มเลิกการติดตั้ง"</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ปัจจุบันใช้ระบบแบบไดนามิกอยู่ รีสตาร์ทเพื่อใช้ Android เวอร์ชันดั้งเดิม"</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"ยกเลิก"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"ยกเลิก"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"รีสตาร์ท"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ยกเลิกระบบแบบไดนามิกแล้ว"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"รีสตาร์ทหรือโหลดระบบแบบไดนามิกไม่ได้"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ปิดใช้ระบบไดนามิกไม่สำเร็จ"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-tl/strings.xml b/packages/DynamicSystemInstallationService/res/values-tl/strings.xml
index d6c2f15..0ec7434 100644
--- a/packages/DynamicSystemInstallationService/res/values-tl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-tl/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"I-restart"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Na-discard ang dynamic system"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Hindi ma-restart o ma-load ang dynamic system"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Hindi na-disable ang dynamic na system"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-tr/strings.xml b/packages/DynamicSystemInstallationService/res/values-tr/strings.xml
index a98526e..6d33979 100644
--- a/packages/DynamicSystemInstallationService/res/values-tr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-tr/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Yeniden başlat"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamik sistem silindi"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dinamik sistem yeniden başlatılamıyor veya yüklenemiyor"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dinamik sistem devre dışı bırakılamadı"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-uk/strings.xml b/packages/DynamicSystemInstallationService/res/values-uk/strings.xml
index 6526787..2712fb2 100644
--- a/packages/DynamicSystemInstallationService/res/values-uk/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-uk/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Перезапустити"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Динамічну систему видалено"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Не вдається перезапустити пристрій або завантажити динамічну систему"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Не вдалося вимкнути динамічну систему"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ur/strings.xml b/packages/DynamicSystemInstallationService/res/values-ur/strings.xml
index f5e2b74..2f96e81 100644
--- a/packages/DynamicSystemInstallationService/res/values-ur/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ur/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ری سٹارٹ کریں"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"مسترد کردہ ڈائنیمک سسٹم"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"ڈائنیمک سسٹم کو ری سٹارٹ یا لوڈ نہیں کر سکتے"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"ڈائنیمک سسٹم کو غیر فعال کرنے میں ناکام"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-uz/strings.xml b/packages/DynamicSystemInstallationService/res/values-uz/strings.xml
index 3c347e2..df21144 100644
--- a/packages/DynamicSystemInstallationService/res/values-uz/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-uz/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Boshidan"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Dinamik tizim bekor qilindi"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Dinamik tizim qayta ishga tushmadi yoki yuklanmadi"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Dinamik tizim faolsizlantirilmadi"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-vi/strings.xml b/packages/DynamicSystemInstallationService/res/values-vi/strings.xml
index a93d29e..83881aa 100644
--- a/packages/DynamicSystemInstallationService/res/values-vi/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-vi/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"Hệ thống động đã sẵn sàng. Để bắt đầu sử dụng hệ thống này, hãy khởi động lại thiết bị của bạn."</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"Đang cài đặt"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"Không cài đặt được"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Không xác thực được hình ảnh. Hủy cài đặt."</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"Không xác thực được ảnh ổ đĩa. Hủy cài đặt."</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Thiết bị đang chạy một hệ thống động. Hãy khởi động lại để sử dụng Android phiên bản gốc."</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"Hủy"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"Hủy"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Khởi động lại"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Đã hủy hệ thống động"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Không thể khởi động lại hoặc tải hệ thống động"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Không vô hiệu hóa được hệ thống động"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml
index c27718e..9a64aa1 100644
--- a/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml
@@ -5,7 +5,7 @@
     <string name="notification_install_completed" msgid="6252047868415172643">"动态系统已准备就绪。重启您的设备即可开始使用动态系统。"</string>
     <string name="notification_install_inprogress" msgid="7383334330065065017">"正在安装"</string>
     <string name="notification_install_failed" msgid="4066039210317521404">"安装失败"</string>
-    <string name="notification_image_validation_failed" msgid="2720357826403917016">"图片验证失败。安装将中止。"</string>
+    <string name="notification_image_validation_failed" msgid="2720357826403917016">"映像验证失败。安装将中止。"</string>
     <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"目前正在运行动态系统。需重启才能使用原 Android 版本。"</string>
     <string name="notification_action_cancel" msgid="5929299408545961077">"取消"</string>
     <string name="notification_action_discard" msgid="1817481003134947493">"舍弃"</string>
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"重启"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"已舍弃动态系统"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"无法重启或加载动态系统"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"无法停用动态系统"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml
index 656c2af..f477c23 100644
--- a/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"重新啟動"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"已捨棄動態系統"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"無法重新啟動或載入動態系統"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"無法停用動態系統"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml
index a6f9b56..96fb5e7 100644
--- a/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"重新啟動"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"已捨棄動態系統"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"無法重新啟動或載入動態系統"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"無法停用動態系統"</string>
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-zu/strings.xml b/packages/DynamicSystemInstallationService/res/values-zu/strings.xml
index 0cf79ba..617e9ed 100644
--- a/packages/DynamicSystemInstallationService/res/values-zu/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-zu/strings.xml
@@ -13,6 +13,5 @@
     <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Qala kabusha"</string>
     <string name="toast_dynsystem_discarded" msgid="1733249860276017050">"Kulahlwe uhlole olunhlobonhlobo"</string>
     <string name="toast_failed_to_reboot_to_dynsystem" msgid="6336737274625452067">"Ayikwazi ukuqalisa kabusha noma ukulayisha uhlole olunhlobonhlobo"</string>
-    <!-- no translation found for toast_failed_to_disable_dynsystem (3285742944977744413) -->
-    <skip />
+    <string name="toast_failed_to_disable_dynsystem" msgid="3285742944977744413">"Yehlulekile ukukhubaza isistimu eguqukayo"</string>
 </resources>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index dd991e0..a9c754d 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -344,6 +344,10 @@
             try {
                 session = getPackageManager().getPackageInstaller().openSession(mSessionId);
             } catch (IOException e) {
+                synchronized (this) {
+                    isDone = true;
+                    notifyAll();
+                }
                 return null;
             }
 
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index 271b70d..bbcc6a2 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -108,7 +108,8 @@
         }
 
         Intent nextActivity = new Intent(intent);
-        nextActivity.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+        nextActivity.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
+                | Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
         // The the installation source as the nextActivity thinks this activity is the source, hence
         // set the originating UID and sourceInfo explicitly
diff --git a/packages/PrintSpooler/res/values-uz/strings.xml b/packages/PrintSpooler/res/values-uz/strings.xml
index ea0a6ea..dbab903 100644
--- a/packages/PrintSpooler/res/values-uz/strings.xml
+++ b/packages/PrintSpooler/res/values-uz/strings.xml
@@ -94,7 +94,7 @@
     <item msgid="2762241247228983754">"Rang"</item>
   </string-array>
   <string-array name="duplex_mode_labels">
-    <item msgid="3882302912790928315">"Yo‘q"</item>
+    <item msgid="3882302912790928315">"Hech qanday"</item>
     <item msgid="7296563835355641719">"Uzun tomoni"</item>
     <item msgid="79513688117503758">"Qisqa tomoni"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index e2b04d4..5dddf2d 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Geaktiveer"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Jou toestel moet herselflaai om hierdie verandering toe te pas. Herselflaai nou of kanselleer."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Bedraade oorfoon"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 0e3684e..27c8319 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ነቅቷል"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"የእርስዎን መሣሪያ ይህ ለው ለማመልከት እንደገና መነሣት አለበት። አሁን እንደገና ያስነሡ ወይም ይተዉት።"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ባለገመድ ጆሮ ማዳመጫ"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 7ec46d2..9a984e2 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -562,4 +562,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"مفعّل"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"يجب إعادة تشغيل جهازك ليتم تطبيق هذا التغيير. يمكنك إعادة التشغيل الآن أو إلغاء التغيير."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"سمّاعة سلكية"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index fe04094..4592d0b 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"সক্ষম কৰা আছে"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"এই সলনিটো কার্যকৰী হ’বলৈ আপোনাৰ ডিভাইচটো ৰিবুট কৰিবই লাগিব। এতিয়াই ৰিবুট কৰক অথবা বাতিল কৰক।"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"তাঁৰযুক্ত হেডফ\'ন"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index bd10cfb..5984d75 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu dəyişikliyin tətbiq edilməsi üçün cihaz yenidən başladılmalıdır. İndi yenidən başladın və ya ləğv edin."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Simli qulaqlıq"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index ebbe996..c2b1487 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -559,4 +559,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate da restartujete uređaj da bi se ova promena primenila. Restartujte ga odmah ili otkažite."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Žičane slušalice"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 9aad825..61e2a75 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -560,4 +560,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Уключана"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Перазагрузіце прыладу, каб прымяніць гэта змяненне. Перазагрузіце ці скасуйце."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Правадныя навушнікі"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 8bf13fe..973873f 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Активирано"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"За да бъде приложена тази промяна, устройството ви трябва да бъде рестартирано. Рестартирайте сега или анулирайте."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Слушалки с кабел"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 8bcf9a6..a86e93c 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"চালু করা আছে"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"এই পরিবর্তনটি প্রয়োগ করার জন্য আপনার ডিভাইসটি অবশ্যই রিবুট করতে হবে। এখনই রিবুট করুন বা বাতিল করুন।"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"তার যুক্ত হেডফোন"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 6e4ce03..ad174e7 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -559,4 +559,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate ponovo pokrenuti uređaj da se ova promjena primijeni. Ponovo pokrenite odmah ili otkažite."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Žičane slušalice"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 525a187..f1c980f 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -531,7 +531,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restringit"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"Vols afegir un usuari nou?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Pots compartir aquest dispositiu amb altres persones creant usuaris addicionals. Cada usuari té el seu propi espai, que pot personalitzar amb aplicacions i fons de pantalla, entre d\'altres. Els usuaris també poden ajustar opcions de configuració del dispositiu, com ara la Wi-Fi, que afecten els altres usuaris.\n\nQuan afegeixis un usuari nou, haurà de configurar el seu espai.\n\nTots els usuaris poden actualitzar les aplicacions de la resta. És possible que la configuració i els serveis d\'accessibilitat no es transfereixin a l\'usuari nou."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai.\n\nQualsevol usuari pot actualitzar les aplicacions dels altres usuaris."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"Quan s\'afegeix un usuari nou, aquesta persona ha de configurar el seu espai.\n\nQualsevol usuari pot actualitzar les aplicacions dels altres usuaris."</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Vols configurar l\'usuari ara?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Assegura\'t que la persona estigui disponible per accedir al dispositiu i configurar el seu espai."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vols configurar el perfil ara?"</string>
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Has de reiniciar el teu dispositiu perquè s\'apliquin els canvis. Reinicia\'l ara o cancel·la."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Auriculars amb cable"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 64ad700..c1ef0b3 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -560,4 +560,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuto"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Aby se tato změna projevila, je třeba zařízení restartovat. Restartujte zařízení nebo zrušte akci."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Kabelová sluchátka"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 433368b..c101e99 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiveret"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Din enhed skal genstartes for at anvende denne ændring. Genstart nu, eller annuller."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Høretelefoner med ledning"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 9946eed..ab25178 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiviert"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Damit diese Änderung übernommen wird, musst du dein Gerät neu starten. Du kannst es jetzt neu starten oder den Vorgang abbrechen."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Kabelgebundene Kopfhörer"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index c265dbc..fb0b1ba 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ενεργή"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Για να εφαρμοστεί αυτή η αλλαγή, θα πρέπει να επανεκκινήσετε τη συσκευή σας. Επανεκκίνηση τώρα ή ακύρωση."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Ενσύρματα ακουστικά"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 285c615..faa5df3 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Wired headphones"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index bbd5c76..2589421 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -558,4 +558,6 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Wired headphones"</string>
+    <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"On"</string>
+    <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Off"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 285c615..faa5df3 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Wired headphones"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 285c615..faa5df3 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Wired headphones"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 699ad42..94049a7 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -558,4 +558,6 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‎Enabled‎‏‎‎‏‎"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‎‎‎Your device must be rebooted for this change to apply. Reboot now or cancel.‎‏‎‎‏‎"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‎Wired headphone‎‏‎‎‏‎"</string>
+    <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎On‎‏‎‎‏‎"</string>
+    <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎Off‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index ab421f6..eeb56c5 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Debes reiniciar el dispositivo para que se aplique el cambio. Reinícialo ahora o cancela la acción."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Auriculares con cable"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 1d9994d..4656049 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Es necesario reiniciar tu dispositivo para que se apliquen los cambios. Reinicia ahora o cancela la acción."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Auriculares con cable"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 72766c0..abc639b 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Lubatud"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Selle muudatuse rakendamiseks tuleb seade taaskäivitada. Taaskäivitage kohe või tühistage."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Juhtmega kõrvaklapid"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index c7462ce..d64d721 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Gaituta"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Aldaketa aplikatzeko, berrabiarazi egin behar da gailua. Berrabiaraz ezazu orain, edo utzi bertan behera."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Entzungailu kableduna"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 0b21a2d..d73f61d 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"برای اعمال این تغییر، دستگاهتان باید راه‌اندازی مجدد شود. اکنون راه‌اندازی مجدد کنید یا لغو کنید."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"هدفون سیمی"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index dd1c12a..b4451eb 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -550,12 +550,16 @@
     <string name="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string>
     <string name="guest_nickname" msgid="6332276931583337261">"Vieras"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Ota valokuva"</string>
+    <string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string>
-    <string name="user_image_photo_selector" msgid="433658323306627093">"Valitse valokuva"</string>
+    <string name="user_image_photo_selector" msgid="433658323306627093">"Valitse kuva"</string>
     <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Laitteen oletusasetus"</string>
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Ei käytössä"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Käytössä"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Laitteesi on käynnistettävä uudelleen, jotta muutos tulee voimaan. Käynnistä uudelleen nyt tai peruuta."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Langalliset kuulokkeet"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index f0364c6..3eff351 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Votre appareil doit être redémarré pour que ce changement prenne effet. Redémarrez-le maintenant ou annulez la modification."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Écouteurs filaires"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 17d13c1..2efa736 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Vous devez redémarrer l\'appareil pour que cette modification soit appliquée. Redémarrez maintenant ou annulez l\'opération."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Casque filaire"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index e0b21c3..ee5d899 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necesario reiniciar o teu dispositivo para aplicar este cambio. Reiníciao agora ou cancela o cambio."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Auriculares con cable"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 08a2b99..5bb783d 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -33,11 +33,11 @@
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' સાથે કનેક્ટ કરી શકાતું નથી"</string>
     <string name="wifi_check_password_try_again" msgid="8817789642851605628">"પાસવર્ડ તપાસો અને ફરી પ્રયાસ કરો"</string>
     <string name="wifi_not_in_range" msgid="1541760821805777772">"રેન્જમાં નથી"</string>
-    <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"આપમેળે કનેક્ટ કરશે નહીં"</string>
+    <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_via_network_scorer" msgid="7665725527352893558">"%1$s દ્વારા સ્વત: કનેક્ટ થયેલ"</string>
-    <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"નેટવર્ક રેટિંગ પ્રદાતા દ્વારા આપમેળે કનેક્ટ થયું"</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>
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ચાલુ છે"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"આ ફેરફારને લાગુ કરવા માટે તમારા ડિવાઇસને રીબૂટ કરવાની જરૂર છે. હમણાં જ રીબૂટ કરો કે રદ કરો."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"વાયરવાળો હૅડફોન"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 8486e34..4cf90fc 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"चालू है"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"बदली गई सेटिंग को लागू करने के लिए, डिवाइस को रीस्टार्ट करना होगा. अपने डिवाइस को रीस्टार्ट करें या रद्द करें."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"वायर वाला हेडफ़ोन"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index a4ef323..5384473 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -559,4 +559,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Uređaj se mora ponovno pokrenuti da bi se ta promjena primijenila. Ponovo pokrenite uređaj odmah ili odustanite."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Žičane slušalice"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 480552b..223f783 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Engedélyezve"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Az eszközt újra kell indítani, hogy a módosítás megtörténjen. Indítsa újra most, vagy vesse el a módosítást."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Vezetékes fejhallgató"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 9fbf998..14c4f61 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Միացված է"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Սարքն անհրաժեշտ է վերագործարկել, որպեսզի փոփոխությունը կիրառվի։ Վերագործարկեք հիմա կամ չեղարկեք փոփոխությունը։"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Լարով ականջակալ"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index b1391ec..3792a30 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktif"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Perangkat Anda harus di-reboot agar perubahan ini diterapkan. Reboot sekarang atau batalkan."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Headphone berkabel"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 1636c55..dbd12cc 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Virkt"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Endurræsa þarf tækið til að þessi breyting taki gildi. Endurræstu núna eða hættu við."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Heyrnartól með snúru"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index b358d65..0949fd6 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Attivo"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Per applicare questa modifica, devi riavviare il dispositivo. Riavvia ora o annulla."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Cuffie con cavo"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 0f2eb4b..8380110 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -560,4 +560,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"מופעל"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"צריך להפעיל מחדש את המכשיר כדי להחיל את השינוי. יש להפעיל מחדש עכשיו או לבטל."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"אוזניות חוטיות"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index dba1c95..a63cfe4 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"有効"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"この変更を適用するには、デバイスの再起動が必要です。今すぐ再起動するか、キャンセルしてください。"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"有線ヘッドフォン"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 8302b8d..d8dd26f 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ჩართული"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ამ ცვლილების ასამოქმედებლად თქვენი მოწყობილობა უნდა გადაიტვირთოს. გადატვირთეთ ახლავე ან გააუქმეთ."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"სადენიანი ყურსასმენი"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index ffb5c9a..262afde 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Қосулы"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бұл өзгеріс күшіне енуі үшін, құрылғыны қайта жүктеу керек. Қазір қайта жүктеңіз не бас тартыңыз."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Сымды құлақаспап"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 6fbd2d1..2161b21 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"បានបើក"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ត្រូវតែ​ចាប់ផ្ដើម​ឧបករណ៍​របស់អ្នក​ឡើងវិញ ដើម្បីឱ្យ​ការផ្លាស់ប្ដូរ​នេះ​មានប្រសិទ្ធភាព។ ចាប់ផ្ដើមឡើងវិញ​ឥឡូវនេះ ឬ​បោះបង់​។"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"កាស​មានខ្សែ"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 653d8ba..4c539cc 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ಈ ಬದಲಾವಣೆ ಅನ್ವಯವಾಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ರೀಬೂಟ್ ಮಾಡಬೇಕು. ಇದೀಗ ರೀಬೂಟ್ ಮಾಡಿ ಅಥವಾ ರದ್ದುಗೊಳಿಸಿ."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ವೈಯರ್ ಹೊಂದಿರುವ ಹೆಡ್‌ಫೋನ್"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 761f813..fa2eec4 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"사용 설정됨"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"변경사항을 적용하려면 기기를 재부팅해야 합니다. 지금 재부팅하거나 취소하세요."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"유선 헤드폰"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index c72b93f..6e737cc 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Күйүк"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бул өзгөрүү күчүнө кириши үчүн, түзмөктү өчүрүп күйгүзүңүз. Азыр же кийинчерээк өчүрүп күйгүзсөңүз болот."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Зымдуу гарнитура"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 7883308..3968766 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ເປີດການນຳໃຊ້ແລ້ວ"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ທ່ານຕ້ອງປິດເປີດອຸປະກອນຄືນໃໝ່ເພື່ອນຳໃຊ້ການປ່ຽນແປງນີ້. ປິດເປີດໃໝ່ດຽວນີ້ ຫຼື ຍົກເລີກ."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ຫູຟັງແບບມີສາຍ"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index e3aa368..eee053b 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -560,4 +560,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Įgalinta"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Kad pakeitimas būtų pritaikytas, įrenginį reikia paleisti iš naujo. Dabar paleiskite iš naujo arba atšaukite."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Laidinės ausinės"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index e994974..161ea77 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -559,4 +559,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Iespējots"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Lai šīs izmaiņas tiktu piemērotas, nepieciešama ierīces atkārtota palaišana. Atkārtoti palaidiet to tūlīt vai atceliet izmaiņas."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Vadu austiņas"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index e711747..0715360 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Овозможено"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"За да се примени променава, уредот мора да се рестартира. Рестартирајте сега или откажете."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Жичени слушалки"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index cebd552..a7a5c22 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"പ്രവർത്തനക്ഷമമാക്കി"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ഈ മാറ്റം ബാധകമാകുന്നതിന് നിങ്ങളുടെ ഉപകരണം റീബൂട്ട് ചെയ്യേണ്ടതുണ്ട്. ഇപ്പോൾ റീബൂട്ട് ചെയ്യുകയോ റദ്ദാക്കുകയോ ചെയ്യുക."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"വയേർഡ് ഹെഡ്ഫോൺ"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 8074366..c397cb5 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -70,7 +70,7 @@
     <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_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>
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Идэвхжүүлсэн"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Энэ өөрчлөлтийг хэрэгжүүлэхийн тулд таны төхөөрөмжийг дахин асаах ёстой. Одоо дахин асаах эсвэл цуцлана уу."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Утастай чихэвч"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 8c55328..5ea183e 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सुरू केले आहे"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"हा बदल लागू करण्यासाठी तुमचे डिव्हाइस रीबूट करणे आवश्यक आहे. आता रीबूट करा किंवा रद्द करा."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"वायर असलेला हेडफोन"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index d988dd0..abc841d 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Didayakan"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Peranti anda mesti dibut semula supaya perubahan ini berlaku. But semula sekarang atau batalkan."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Fon kepala berwayar"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 5a16743..a0e3714 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ဖွင့်ထားသည်"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ဤအပြောင်းအလဲ ထည့်သွင်းရန် သင့်စက်ကို ပြန်လည်စတင်ရမည်။ ယခု ပြန်လည်စတင်ပါ သို့မဟုတ် ပယ်ဖျက်ပါ။"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ကြိုးတပ်နားကြပ်"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index df96ea6..19aa7f1 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Slått på"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten din må startes på nytt for at denne endringen skal tre i kraft. Start på nytt nå eller avbryt."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Hodetelefoner med kabel"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index e34732f..8a86692 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सक्षम पारिएको छ"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"यो परिवर्तन लागू गर्न तपाईंको यन्त्र अनिवार्य रूपमा रिबुट गर्नु पर्छ। अहिले रिबुट गर्नुहोस् वा रद्द गर्नुहोस्।"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"तारसहितको हेडफोन"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 729d57b..440808d 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ingeschakeld"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Je apparaat moet opnieuw worden opgestart om deze wijziging toe te passen. Start nu opnieuw op of annuleer de wijziging."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Bedrade hoofdtelefoon"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 1ce7d56e..c67fd47 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ସକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ୍ କରନ୍ତୁ।"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ତାରଯୁକ୍ତ ହେଡଫୋନ୍"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index c122a28..e52f740 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ਇਸ ਤਬਦੀਲੀ ਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਰੀਬੂਟ ਕਰਨਾ ਲਾਜ਼ਮੀ ਹੈ। ਹੁਣੇ ਰੀਬੂਟ ਕਰੋ ਜਾਂ ਰੱਦ ਕਰੋ।"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ਤਾਰ ਵਾਲੇ ਹੈੱਡਫ਼ੋਨ"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 112ae47..8629b05 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -560,4 +560,6 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Włączono"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Wprowadzenie zmiany wymaga ponownego uruchomienia urządzenia. Uruchom ponownie teraz lub anuluj."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Słuchawki przewodowe"</string>
+    <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Włączono"</string>
+    <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Wyłączono"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 102961a..bac1ae4 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -147,7 +147,7 @@
     <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Ponto de acesso portátil"</string>
     <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
-    <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e acesso portátil"</string>
+    <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e ponto de acesso"</string>
     <string name="managed_user_title" msgid="449081789742645723">"Todos os apps de trabalho"</string>
     <string name="user_guest" msgid="6939192779649870792">"Convidado"</string>
     <string name="unknown" msgid="3544487229740637809">"Desconhecido"</string>
@@ -558,4 +558,6 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Fones de ouvido com fio"</string>
+    <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Ativado"</string>
+    <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Desativado"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 7354835..9a803d6 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativada"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reiniciar o dispositivo para aplicar esta alteração. Reinicie agora ou cancele."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Auscultadores com fios"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 102961a..bac1ae4 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -147,7 +147,7 @@
     <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Ponto de acesso portátil"</string>
     <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Tethering"</string>
-    <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e acesso portátil"</string>
+    <string name="tether_settings_title_all" msgid="8910259483383010470">"Tethering e ponto de acesso"</string>
     <string name="managed_user_title" msgid="449081789742645723">"Todos os apps de trabalho"</string>
     <string name="user_guest" msgid="6939192779649870792">"Convidado"</string>
     <string name="unknown" msgid="3544487229740637809">"Desconhecido"</string>
@@ -558,4 +558,6 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Fones de ouvido com fio"</string>
+    <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Ativado"</string>
+    <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Desativado"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 32e70da..b288a62 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -559,4 +559,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Pentru ca modificarea să se aplice, trebuie să reporniți dispozitivul. Reporniți-l acum sau anulați."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Căști cu fir"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index b04d93b..f87d5aa 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -560,4 +560,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Включено"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Чтобы изменение вступило в силу, необходимо перезапустить устройство. Вы можете сделать это сейчас или позже."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Проводные наушники"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 86725c2..3115067 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"සබලයි"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"මෙම වෙනස යෙදීමට ඔබේ උපාංගය නැවත පණ ගැන්විය යුතුය. දැන් නැවත පණ ගන්වන්න හෝ අවලංගු කරන්න."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"රැහැන්ගත කළ හෙඩ්ෆෝන්"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 91e9564..178408d 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -560,4 +560,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuté"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Zmena sa prejaví až po reštarte zariadenia. Môžete ho teraz reštartovať alebo akciu zrušiť."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Slúchadlá s káblom"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 45ffcde..517d5c9 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -560,4 +560,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogočeno"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Napravo je treba znova zagnati, da bo ta sprememba uveljavljena. Znova zaženite zdaj ali prekličite."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Žične slušalke"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index c398363..5d31885 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Pajisja jote duhet të riniset që ky ndryshim të zbatohet. Rinise tani ose anuloje."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Kufje me tela"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 18cf808..8cf7603 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -559,4 +559,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Омогућено"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Морате да рестартујете уређај да би се ова промена применила. Рестартујте га одмах или откажите."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Жичане слушалице"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 197655e..d3afb22 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiverat"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten måste startas om för att ändringen ska börja gälla. Starta om nu eller avbryt."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Hörlurar med sladd"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 1f0d167..a8cf7fb47 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Imewashwa"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Ni lazima uwashe tena kifaa chako ili mabadiliko haya yatekelezwe. Washa tena sasa au ughairi."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Vipokea sauti vya waya"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index b6d8be8..41ebe05 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"இயக்கப்பட்டது"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"இந்த மாற்றங்கள் செயல்படுத்தப்பட உங்கள் சாதனத்தை மறுபடி தொடங்க வேண்டும். இப்போதே மறுபடி தொடங்கவும் அல்லது ரத்துசெய்யவும்."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"வயருள்ள ஹெட்ஃபோன்"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index 1d7e88c..e1c0406 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -86,7 +86,7 @@
     <item msgid="8147982633566548515">"map14"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="2494959071796102843">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+    <item msgid="2494959071796102843">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
     <item msgid="4055460186095649420">"SBC"</item>
     <item msgid="720249083677397051">"AAC"</item>
     <item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ఆడియో"</item>
@@ -94,7 +94,7 @@
     <item msgid="3825367753087348007">"LDAC"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="8868109554557331312">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+    <item msgid="8868109554557331312">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
     <item msgid="9024885861221697796">"SBC"</item>
     <item msgid="4688890470703790013">"AAC"</item>
     <item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ఆడియో"</item>
@@ -102,38 +102,38 @@
     <item msgid="2553206901068987657">"LDAC"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
-    <item msgid="926809261293414607">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+    <item msgid="926809261293414607">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
     <item msgid="8003118270854840095">"44.1 kHz"</item>
     <item msgid="3208896645474529394">"48.0 kHz"</item>
     <item msgid="8420261949134022577">"88.2 kHz"</item>
     <item msgid="8887519571067543785">"96.0 kHz"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
-    <item msgid="2284090879080331090">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+    <item msgid="2284090879080331090">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
     <item msgid="1872276250541651186">"44.1 kHz"</item>
     <item msgid="8736780630001704004">"48.0 kHz"</item>
     <item msgid="7698585706868856888">"88.2 kHz"</item>
     <item msgid="8946330945963372966">"96.0 kHz"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
-    <item msgid="2574107108483219051">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+    <item msgid="2574107108483219051">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
     <item msgid="4671992321419011165">"16 బిట్‌లు/నమూనా"</item>
     <item msgid="1933898806184763940">"24 బిట్‌లు/నమూనా"</item>
     <item msgid="1212577207279552119">"32 బిట్‌లు/నమూనా"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
-    <item msgid="9196208128729063711">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+    <item msgid="9196208128729063711">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
     <item msgid="1084497364516370912">"16 బిట్‌లు/నమూనా"</item>
     <item msgid="2077889391457961734">"24 బిట్‌లు/నమూనా"</item>
     <item msgid="3836844909491316925">"32 బిట్‌లు/నమూనా"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
-    <item msgid="3014194562841654656">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+    <item msgid="3014194562841654656">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
     <item msgid="5982952342181788248">"మోనో"</item>
     <item msgid="927546067692441494">"స్టీరియో"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
-    <item msgid="1997302811102880485">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
+    <item msgid="1997302811102880485">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
     <item msgid="8005696114958453588">"మోనో"</item>
     <item msgid="1333279807604675720">"స్టీరియో"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 5a8e734..a4d7d83 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -156,14 +156,14 @@
     <string name="launch_defaults_none" msgid="8049374306261262709">"ఆటోమేటిక్ ఆప్ష‌న్‌లు ఏవీ సెట్ చేయ‌‌లేదు"</string>
     <string name="tts_settings" msgid="8130616705989351312">"వచనం నుండి ప్రసంగం సెట్టింగ్‌లు"</string>
     <string name="tts_settings_title" msgid="7602210956640483039">"టెక్స్ట్-టు-స్పీచ్ అవుట్‌పుట్"</string>
-    <string name="tts_default_rate_title" msgid="3964187817364304022">"ప్రసంగం రేట్"</string>
+    <string name="tts_default_rate_title" msgid="3964187817364304022">"స్పీచ్ రేట్"</string>
     <string name="tts_default_rate_summary" msgid="3781937042151716987">"వచనాన్ని చదివి వినిపించాల్సిన వేగం"</string>
     <string name="tts_default_pitch_title" msgid="6988592215554485479">"పిచ్"</string>
     <string name="tts_default_pitch_summary" msgid="9132719475281551884">"సమన్వయం చేసిన ప్రసంగం యొక్క టోన్‌ను ప్రభావితం చేస్తుంది"</string>
     <string name="tts_default_lang_title" msgid="4698933575028098940">"భాష"</string>
     <string name="tts_lang_use_system" msgid="6312945299804012406">"సిస్టమ్ భాషను ఉపయోగించు"</string>
     <string name="tts_lang_not_selected" msgid="7927823081096056147">"భాష ఎంచుకోబడలేదు"</string>
-    <string name="tts_default_lang_summary" msgid="9042620014800063470">"చదవి వినిపించబడే వచనం కోసం భాష-నిర్దిష్ట వాయిస్‌ను సెట్ చేస్తుంది"</string>
+    <string name="tts_default_lang_summary" msgid="9042620014800063470">"టెక్స్ట్‌ను చదివి వినిపించేటప్పుడు, ఒక్కో భాషకు వాడాల్సిన నిర్దిష్ట వాయిస్‌ను సెట్ చేస్తుంది"</string>
     <string name="tts_play_example_title" msgid="1599468547216481684">"ఒక ఉదాహరణ వినండి"</string>
     <string name="tts_play_example_summary" msgid="634044730710636383">"ప్రసంగ సమన్వయం గురించి సంక్షిప్త ప్రదర్శనను ప్లే చేయి"</string>
     <string name="tts_install_data_title" msgid="1829942496472751703">"వాయిస్ డేటాను ఇన్‌స్టాల్ చేయి"</string>
@@ -196,7 +196,7 @@
     <string name="choose_profile" msgid="343803890897657450">"ప్రొఫైల్‌ను ఎంచుకోండి"</string>
     <string name="category_personal" msgid="6236798763159385225">"వ్యక్తిగతం"</string>
     <string name="category_work" msgid="4014193632325996115">"ఆఫీస్"</string>
-    <string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఎంపికలు"</string>
+    <string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఆప్షన్‌లు"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"డెవలపర్ ఎంపికలను ప్రారంభించండి"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"అనువర్తన అభివృద్ధి కోసం ఎంపికలను సెట్ చేయండి"</string>
     <string name="development_settings_not_available" msgid="355070198089140951">"ఈ వినియోగదారు కోసం డెవలపర్ ఎంపికలు అందుబాటులో లేవు"</string>
@@ -280,7 +280,7 @@
     <string name="private_dns_mode_provider" msgid="3619040641762557028">"ప్రైవేట్ DNS ప్రదాత హోస్ట్‌పేరు"</string>
     <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ప్రదాత యొక్క హోస్ట్‌పేరును నమోదు చేయండి"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
-    <string name="wifi_display_certification_summary" msgid="8111151348106907513">"వైర్‌లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string>
+    <string name="wifi_display_certification_summary" msgid="8111151348106907513">"వైర్‌లెస్ డిస్‌ప్లే సర్టిఫికేషన్ ఆప్షన్‌లను చూపు"</string>
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
     <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"బ్యాటరీ శక్తి వినియోగాన్ని తగ్గించి &amp; నెట్‌వర్క్ పనితీరును మెరుగుపరుస్తుంది"</string>
     <string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"ఈ మోడ్ ఎనేబుల్ అయ్యాక, MAC ర్యాండమైజేషన్‌ను ఎనేబుల్ చేసిన నెట్‌వర్క్‌తో కనెక్ట్ అయ్యే ప్రతిసారీ ఈ పరికరం MAC అడ్రస్ మారవచ్చు."</string>
@@ -366,7 +366,7 @@
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ప్రత్యామ్నాయ ప్రదర్శనలను అనుకరించండి"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"యాప్‌లు"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"కార్యకలాపాలను ఉంచవద్దు"</string>
-    <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ప్రతి కార్యకలాపాన్ని వినియోగదారు నిష్క్రమించిన వెంటనే తొలగించండి"</string>
+    <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"యూజర్ నిష్క్రమించాక పూర్తి యాక్టివిటీ తొలగింపు"</string>
     <string name="app_process_limit_title" msgid="8361367869453043007">"బ్యాక్‌గ్రౌండ్ ప్రాసెస్ పరిమితి"</string>
     <string name="show_all_anrs" msgid="9160563836616468726">"బ్యాక్‌గ్రౌండ్ ANRలను చూపు"</string>
     <string name="show_all_anrs_summary" msgid="8562788834431971392">"నేపథ్య యాప్‌ల కోసం యాప్ ప్రతిస్పందించడం లేదు అనే డైలాగ్‌ను చూపు"</string>
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ఎనేబుల్ చేయబడింది"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ఈ మార్పును వర్తింపజేయాలంటే మీరు మీ పరికరాన్ని తప్పనిసరిగా రీబూట్ చేయాలి. ఇప్పుడే రీబూట్ చేయండి లేదా రద్దు చేయండి."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"వైర్ ఉన్న హెడ్‌ఫోన్"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 2ae4131..fa92d40 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"เปิดใช้"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"คุณต้องรีบูตอุปกรณ์เพื่อให้การเปลี่ยนแปลงนี้มีผล รีบูตเลยหรือยกเลิก"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"หูฟังแบบมีสาย"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index e9f1da3..2859b71 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Na-enable"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Dapat i-reboot ang iyong device para mailapat ang pagbabagong ito. Mag-reboot ngayon o kanselahin."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Wired na headphone"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 0502359..bbff7b4 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Etkin"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu değişikliğin geçerli olması için cihazınızın yeniden başlatılması gerekir. Şimdi yeniden başlatın veya iptal edin."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Kablolu kulaklık"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 8e13afd..fff49cd 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -560,4 +560,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Увімкнено"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Щоб застосувати ці зміни, потрібний перезапуск. Перезапустіть пристрій або скасуйте зміни."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Дротові навушники"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index b971aee..aa38680 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"اس تبدیلی کو لاگو کرنے کے ليے آپ کے آلہ کو ریبوٹ کرنا ضروری ہے۔ ابھی ریبوٹ کریں یا منسوخ کریں۔"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"وائرڈ ہیڈ فون"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 3df33b6..0928779 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Yoniq"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Oʻzgarishlar kuchga kirishi uchun qurilmani oʻchirib yoqing. Buni hozir yoki keyinroq bajarishingiz mumkin."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Simli quloqlik"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 4d4808f..512e52f 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -305,7 +305,7 @@
     <string name="adbwifi_warning_message" msgid="8005936574322702388">"Tính năng gỡ lỗi qua Wi-Fi chỉ dành cho mục đích phát triển. Hãy sử dụng tính năng này để sao chép dữ liệu giữa máy tính và thiết bị của bạn, cài đặt ứng dụng trên thiết bị mà không thông báo và đọc dữ liệu nhật ký."</string>
     <string name="adb_keys_warning_message" msgid="2968555274488101220">"Thu hồi quyền truy cập gỡ lỗi USB từ tất cả máy tính mà bạn đã ủy quyền trước đó?"</string>
     <string name="dev_settings_warning_title" msgid="8251234890169074553">"Cho phép cài đặt phát triển?"</string>
-    <string name="dev_settings_warning_message" msgid="37741686486073668">"Những cài đặt này chỉ dành cho mục đích phát triển. Chúng có thể làm cho thiết bị và ứng dụng trên thiết bị của bạn bị lỗi và hoạt động sai."</string>
+    <string name="dev_settings_warning_message" msgid="37741686486073668">"Những tùy chọn cài đặt này chỉ dành cho mục đích phát triển. Chúng có thể làm cho thiết bị và ứng dụng trên thiết bị của bạn bị lỗi và hoạt động không đúng cách."</string>
     <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Xác minh ứng dụng qua USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kiểm tra các ứng dụng được cài đặt qua ADB/ADT để xem có hoạt động gây hại hay không."</string>
     <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Các thiết bị Bluetooth không có tên (chỉ có địa chỉ MAC) sẽ được hiển thị"</string>
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Đã bật"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bạn phải khởi động lại thiết bị để áp dụng sự thay đổi này. Hãy khởi động lại ngay hoặc hủy."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Tai nghe có dây"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index b6e8eba2..0cc2c51 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已启用"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"设备必须重新启动才能应用此更改。您可以立即重新启动或取消。"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"有线耳机"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 07bc887..bd8717f 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"您的裝置必須重新開機,才能套用此變更。請立即重新開機或取消。"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"有線耳機"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 833a82f..62dccd3 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"裝置必須重新啟動才能套用這項變更。請立即重新啟動或取消變更。"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"有線耳機"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 0065eb6..9eb4fea 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -113,7 +113,7 @@
     <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Isetshenziselwa okufakwayo"</string>
     <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Sebenzisa izinsiza zokuzwa"</string>
     <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Bhangqa"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"BHANQA"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"BHANGQA"</string>
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Khansela"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Ukubhanqa kunika ukufinyelela koxhumana nabo nomlando wekholi uma uxhumekile."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Ayikwazanga ukuhlangana ne <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
@@ -558,4 +558,8 @@
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Inikwe amandla"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Kufanele idivayisi yakho iqaliswe ukuze lolu shintsho lusebenze. Qalisa manje noma khansela."</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Ama-headphone anentambo"</string>
+    <!-- no translation found for wifi_hotspot_switch_on_text (9212273118217786155) -->
+    <skip />
+    <!-- no translation found for wifi_hotspot_switch_off_text (7245567251496959764) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 6a4c8c3..48421ce 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1385,4 +1385,9 @@
 
     <!-- Name of the 3.5mm and usb audio device. [CHAR LIMIT=50] -->
     <string name="media_transfer_wired_usb_device_name">Wired headphone</string>
+
+    <!-- Label for Wifi hotspot switch on. Toggles hotspot on [CHAR LIMIT=30] -->
+    <string name="wifi_hotspot_switch_on_text">On</string>
+    <!-- Label for Wifi hotspot switch off. Toggles hotspot off [CHAR LIMIT=30] -->
+    <string name="wifi_hotspot_switch_off_text">Off</string>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java
index f6cd971..12ef639 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java
@@ -16,6 +16,8 @@
 
 package com.android.settingslib.volume;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -23,20 +25,21 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
-import android.media.IRemoteVolumeController;
 import android.media.MediaMetadata;
 import android.media.session.MediaController;
 import android.media.session.MediaController.PlaybackInfo;
+import android.media.session.MediaSession;
 import android.media.session.MediaSession.QueueItem;
 import android.media.session.MediaSession.Token;
 import android.media.session.MediaSessionManager;
 import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener;
+import android.media.session.MediaSessionManager.RemoteVolumeControllerCallback;
 import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.os.Message;
-import android.os.RemoteException;
 import android.util.Log;
 
 import java.io.PrintWriter;
@@ -58,6 +61,7 @@
 
     private final Context mContext;
     private final H mHandler;
+    private final HandlerExecutor mHandlerExecutor;
     private final MediaSessionManager mMgr;
     private final Map<Token, MediaControllerRecord> mRecords = new HashMap<>();
     private final Callbacks mCallbacks;
@@ -67,6 +71,7 @@
     public MediaSessions(Context context, Looper looper, Callbacks callbacks) {
         mContext = context;
         mHandler = new H(looper);
+        mHandlerExecutor = new HandlerExecutor(mHandler);
         mMgr = (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
         mCallbacks = callbacks;
     }
@@ -95,7 +100,8 @@
         mMgr.addOnActiveSessionsChangedListener(mSessionsListener, null, mHandler);
         mInit = true;
         postUpdateSessions();
-        mMgr.registerRemoteVolumeController(mRvc);
+        mMgr.registerRemoteVolumeControllerCallback(mHandlerExecutor,
+                mRemoteVolumeControllerCallback);
     }
 
     protected void postUpdateSessions() {
@@ -110,7 +116,7 @@
         if (D.BUG) Log.d(TAG, "destroy");
         mInit = false;
         mMgr.removeOnActiveSessionsChangedListener(mSessionsListener);
-        mMgr.unregisterRemoteVolumeController(mRvc);
+        mMgr.unregisterRemoteVolumeControllerCallback(mRemoteVolumeControllerCallback);
     }
 
     /**
@@ -330,19 +336,19 @@
                 }
             };
 
-    private final IRemoteVolumeController mRvc = new IRemoteVolumeController.Stub() {
-        @Override
-        public void remoteVolumeChanged(Token sessionToken, int flags)
-                throws RemoteException {
-            mHandler.obtainMessage(H.REMOTE_VOLUME_CHANGED, flags, 0,
-                    sessionToken).sendToTarget();
-        }
+    private final RemoteVolumeControllerCallback mRemoteVolumeControllerCallback =
+            new RemoteVolumeControllerCallback() {
+                @Override
+                public void onVolumeChanged(@NonNull MediaSession.Token sessionToken,
+                        int flags) {
+                    mHandler.obtainMessage(H.REMOTE_VOLUME_CHANGED, flags, 0,
+                            sessionToken).sendToTarget();
+                }
 
-        @Override
-        public void updateRemoteController(final Token sessionToken)
-                throws RemoteException {
-            mHandler.obtainMessage(H.UPDATE_REMOTE_CONTROLLER, sessionToken).sendToTarget();
-        }
+                @Override
+                public void onSessionChanged(@Nullable MediaSession.Token sessionToken) {
+                    mHandler.obtainMessage(H.UPDATE_REMOTE_CONTROLLER, sessionToken).sendToTarget();
+                }
     };
 
     private final class H extends Handler {
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index b9e30fb..ffbc7f4c 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -89,6 +89,7 @@
         Settings.Secure.RTT_CALLING_MODE,
         Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
         Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED,
+        Settings.Secure.MATCH_CONTENT_FRAME_RATE,
         Settings.Secure.NIGHT_DISPLAY_CUSTOM_START_TIME,
         Settings.Secure.NIGHT_DISPLAY_CUSTOM_END_TIME,
         Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 721bf73..46c42fc 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -135,6 +135,9 @@
                 Secure.INCALL_POWER_BUTTON_BEHAVIOR,
                 new DiscreteValueValidator(new String[] {"1", "2"}));
         VALIDATORS.put(Secure.MINIMAL_POST_PROCESSING_ALLOWED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(
+                Secure.MATCH_CONTENT_FRAME_RATE,
+                new DiscreteValueValidator(new String[] {"0", "1", "2"}));
         VALIDATORS.put(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, NON_NEGATIVE_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 2412a32..48eb600 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -230,6 +230,7 @@
                     Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR,
                     Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_SV,
                     Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR,
+                    Settings.Global.DEVELOPMENT_IGNORE_VENDOR_DISPLAY_SETTINGS,
                     Settings.Global.DEVICE_DEMO_MODE,
                     Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS,
                     Settings.Global.BATTERY_SAVER_CONSTANTS,
diff --git a/packages/SoundPicker/res/values-kk/strings.xml b/packages/SoundPicker/res/values-kk/strings.xml
index 810192f..ad6d0e0 100644
--- a/packages/SoundPicker/res/values-kk/strings.xml
+++ b/packages/SoundPicker/res/values-kk/strings.xml
@@ -19,7 +19,7 @@
     <string name="ringtone_default" msgid="798836092118824500">"Әдепкі рингтон"</string>
     <string name="notification_sound_default" msgid="8133121186242636840">"Әдепкі хабарландыру дыбысы"</string>
     <string name="alarm_sound_default" msgid="4787646764557462649">"Әдепкі дабыл дыбысы"</string>
-    <string name="add_ringtone_text" msgid="6642389991738337529">"Рингтон енгізу"</string>
+    <string name="add_ringtone_text" msgid="6642389991738337529">"Рингтон қосу"</string>
     <string name="add_alarm_text" msgid="3545497316166999225">"Оятқыш енгізу"</string>
     <string name="add_notification_text" msgid="4431129543300614788">"Хабарландыру енгізу"</string>
     <string name="delete_ringtone_text" msgid="201443984070732499">"Жою"</string>
diff --git a/packages/SoundPicker/res/values-te/strings.xml b/packages/SoundPicker/res/values-te/strings.xml
index 6b8a62e..10b4e7c 100644
--- a/packages/SoundPicker/res/values-te/strings.xml
+++ b/packages/SoundPicker/res/values-te/strings.xml
@@ -17,8 +17,8 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="ringtone_default" msgid="798836092118824500">"డిఫాల్ట్ రింగ్‌టోన్"</string>
-    <string name="notification_sound_default" msgid="8133121186242636840">"డిఫాల్ట్ నోటిఫికేషన్ ధ్వని"</string>
-    <string name="alarm_sound_default" msgid="4787646764557462649">"డిఫాల్ట్ అలారం ధ్వని"</string>
+    <string name="notification_sound_default" msgid="8133121186242636840">"నోటిఫికేషన్ ఆటోమేటిక్ సౌండ్"</string>
+    <string name="alarm_sound_default" msgid="4787646764557462649">"అలారం ఆటోమేటిక్ సౌండ్"</string>
     <string name="add_ringtone_text" msgid="6642389991738337529">"రింగ్‌టోన్‌ను జోడించు"</string>
     <string name="add_alarm_text" msgid="3545497316166999225">"అలారాన్ని జోడించు"</string>
     <string name="add_notification_text" msgid="4431129543300614788">"నోటిఫికేషన్‌‌ని జోడించు"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index f9268eec..39a6ed1 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -352,7 +352,7 @@
                 android:exported="true" />
 
         <activity
-            android:name=".bubbles.BubbleOverflowActivity"
+            android:name="com.android.wm.shell.bubbles.BubbleOverflowActivity"
             android:theme="@style/BubbleOverflow"
             android:excludeFromRecents="true"
             android:documentLaunchMode="always"
diff --git a/packages/SystemUI/res/drawable/bubble_dismiss_circle.xml b/packages/SystemUI/res/drawable/bubble_dismiss_circle.xml
deleted file mode 100644
index 8c7e82f..0000000
--- a/packages/SystemUI/res/drawable/bubble_dismiss_circle.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-    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.
--->
-<!--
-    The transparent circle outline that encircles the bubbles when they're in the dismiss target.
--->
-<shape
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="oval">
-
-    <stroke
-        android:width="1dp"
-        android:color="#66FFFFFF" />
-
-    <solid android:color="#B3000000" />
-</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/bubble_dismiss_icon.xml b/packages/SystemUI/res/drawable/bubble_dismiss_icon.xml
deleted file mode 100644
index 5c8de58..0000000
--- a/packages/SystemUI/res/drawable/bubble_dismiss_icon.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-    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.
--->
-<!-- The 'X' bubble dismiss icon. This is just ic_close with a stroke. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M19.000000,6.400000l-1.400000,-1.400000 -5.600000,5.600000 -5.600000,-5.600000 -1.400000,1.400000 5.600000,5.600000 -5.600000,5.600000 1.400000,1.400000 5.600000,-5.600000 5.600000,5.600000 1.400000,-1.400000 -5.600000,-5.600000z"
-        android:fillColor="#FFFFFFFF"
-        android:strokeColor="#FF000000"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_create_bubble.xml b/packages/SystemUI/res/drawable/ic_create_bubble.xml
deleted file mode 100644
index 4abbc81..0000000
--- a/packages/SystemUI/res/drawable/ic_create_bubble.xml
+++ /dev/null
@@ -1,25 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="20dp"
-    android:height="20dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-  <path
-      android:fillColor="#FF000000"
-      android:pathData="M23,5v8h-2V5H3v14h10v2v0H3c-1.1,0 -2,-0.9 -2,-2V5c0,-1.1 0.9,-2 2,-2h18C22.1,3 23,3.9 23,5zM10,8v2.59L5.71,6.29L4.29,7.71L8.59,12H6v2h6V8H10zM19,15c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S20.66,15 19,15z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_screenshot_scroll.xml b/packages/SystemUI/res/drawable/ic_screenshot_scroll.xml
new file mode 100644
index 0000000..c260ba9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_screenshot_scroll.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ 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.
+  -->
+<!-- ic_unfold_more_24px.xml -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,5.83L15.17,9l1.41,-1.41L12,3 7.41,7.59 8.83,9 12,5.83zM12,18.17L8.83,15l-1.41,1.41L12,21l4.59,-4.59L15.17,15 12,18.17z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_stop_bubble.xml b/packages/SystemUI/res/drawable/ic_stop_bubble.xml
deleted file mode 100644
index 6cf67a7..0000000
--- a/packages/SystemUI/res/drawable/ic_stop_bubble.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="20dp"
-    android:height="20dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-  <path
-      android:fillColor="#FF000000"
-      android:pathData="M11.29,14.71L7,10.41V13H5V7h6v2H8.41l4.29,4.29L11.29,14.71zM21,3H3C1.9,3 1,3.9 1,5v14c0,1.1 0.9,2 2,2h10v0v-2H3V5h18v8h2V5C23,3.9 22.1,3 21,3zM19,15c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S20.66,15 19,15z"/>
-</vector>
diff --git a/packages/SystemUI/res/layout-land/global_screenshot_preview.xml b/packages/SystemUI/res/layout-land/global_screenshot_preview.xml
index 040303a..71b414f 100644
--- a/packages/SystemUI/res/layout-land/global_screenshot_preview.xml
+++ b/packages/SystemUI/res/layout-land/global_screenshot_preview.xml
@@ -28,6 +28,6 @@
     android:visibility="gone"
     android:background="@drawable/screenshot_rounded_corners"
     android:adjustViewBounds="true"
-    android:contentDescription="@string/screenshot_edit"
+    android:contentDescription="@string/screenshot_edit_label"
     app:layout_constraintBottom_toBottomOf="parent"
     app:layout_constraintStart_toStartOf="parent"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 1b5f9c1..6c20c1e 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -46,7 +46,7 @@
         android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
         android:elevation="7dp"
         android:visibility="gone"
-        android:contentDescription="@string/screenshot_dismiss_ui_description">
+        android:contentDescription="@string/screenshot_dismiss_description">
         <ImageView
             android:id="@+id/global_screenshot_dismiss_image"
             android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/global_screenshot_preview.xml b/packages/SystemUI/res/layout/global_screenshot_preview.xml
index c745854..5262407 100644
--- a/packages/SystemUI/res/layout/global_screenshot_preview.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_preview.xml
@@ -28,6 +28,6 @@
     android:visibility="gone"
     android:background="@drawable/screenshot_rounded_corners"
     android:adjustViewBounds="true"
-    android:contentDescription="@string/screenshot_edit"
+    android:contentDescription="@string/screenshot_edit_label"
     app:layout_constraintBottom_toBottomOf="parent"
     app:layout_constraintStart_toStartOf="parent"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/global_screenshot_static.xml b/packages/SystemUI/res/layout/global_screenshot_static.xml
index 26edf3a..096ec7d 100644
--- a/packages/SystemUI/res/layout/global_screenshot_static.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_static.xml
@@ -56,6 +56,9 @@
                      android:id="@+id/screenshot_share_chip"/>
             <include layout="@layout/global_screenshot_action_chip"
                      android:id="@+id/screenshot_edit_chip"/>
+            <include layout="@layout/global_screenshot_action_chip"
+                     android:id="@+id/screenshot_scroll_chip"
+                     android:visibility="gone" />
         </LinearLayout>
     </HorizontalScrollView>
     <include layout="@layout/global_screenshot_preview"/>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 220a773..8362847 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probeer weer skermkiekie neem"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Kan weens beperkte bergingspasie nie skermkiekie stoor nie"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Die program of jou organisasie laat nie toe dat skermkiekies geneem word nie"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Wysig skermkiekie"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Maak skermkiekie toe"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Skermkiekievoorskou"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skermopnemer"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Verwerk tans skermopname"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Battery, twee stawe."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Battery, drie stawe."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Battery vol."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batterypersentasie is onbekend."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Geen foon nie."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Foon, een staaf."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Foon, twee stawe."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Kennisgewing is toegemaak."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Borrel is toegemaak."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Kennisgewingskerm."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Vinnige instellings."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Sluitskerm."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profiel kan gemonitor word"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Netwerk kan dalk gemonitor word"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Netwerk kan dalk gemonitor word"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Hierdie toestel word deur jou ouer bestuur"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Jou organisasie besit hierdie toestel en kan netwerkverkeer monitor"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> besit hierdie toestel en kan netwerkverkeer monitor"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Hierdie toestel behoort aan jou organisasie en is gekoppel aan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Deaktiveer VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Ontkoppel VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Bekyk beleide"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Bekyk kontroles"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJou IT-admin kan instellings, korporatiewe toegang, programme, data wat met jou toestel geassosieer word, en jou toestel se ligginginligting monitor en bestuur.\n\nKontak jou IT-admin vir meer inligting."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Hierdie toestel behoort aan jou organisasie.\n\nJou IT-admin kan instellings, korporatiewe toegang, programme, data wat met jou toestel geassosieer word, en jou toestel se ligginginligting monitor en bestuur.\n\nKontak jou IT-admin vir meer inligting."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jou organisasie het \'n sertifikaatoutoriteit op hierdie toestel geïnstalleer. Jou veilige netwerkverkeer kan gemonitor of gewysig word."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Jou administrateur het netwerkloglêers aangeskakel wat verkeer op jou toestel monitor.\n\nKontak jou administrateur vir meer inligting."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Jy het \'n program toestemming gegee om \'n VPN-verbinding op te stel.\n\nHierdie program kan jou toestel- en netwerkaktiwiteit monitor, insluitend e-posse, programme en webwerwe."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Jou werkprofiel word deur <xliff:g id="ORGANIZATION">%1$s</xliff:g> bestuur.\n\nJou administrateur kan jou netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, bestuur.\n\nKontak jou administrateur vir meer inligting.\n\nJy is ook aan \'n VPN gekoppel, wat jou netwerkaktiwiteit kan monitor."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Hierdie toestel word deur jou ouer bestuur. Jou ouer kan inligting sien en bestuur soos die programme wat jy gebruik, jou ligging en jou skermtyd."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Jy is gekoppel aan <xliff:g id="APPLICATION">%1$s</xliff:g>, wat jou netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, kan monitor."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Jy is gekoppel aan <xliff:g id="APPLICATION">%1$s</xliff:g>, wat jou persoonlike netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, kan monitor."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Hou aan om kennisgewings van hierdie program af te wys?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Stil"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Verstek"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Borrel"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Outomaties"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Geen klank of vibrasie nie"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen klank of vibrasie nie en verskyn laer in gespreksafdeling"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Instellings"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> steun nie gesprekskenmerke nie"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Geen onlangse borrels nie"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Onlangse borrels en borrels wat toegemaak is, sal hier verskyn"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Hierdie kennisgewings kan nie gewysig word nie."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Hierdie groep kennisgewings kan nie hier opgestel word nie"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Instaanbediener-kennisgewing"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Toesteldienste"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Titelloos"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tik om hierdie program te herbegin en maak volskerm oop."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Instellings vir <xliff:g id="APP_NAME">%1$s</xliff:g>-borrels"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Oorloop"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Voeg terug op stapel"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Bestuur"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> vanaf <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> van <xliff:g id="APP_NAME">%2$s</xliff:g> en <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> meer af"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Beweeg"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Beweeg na links bo"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Beweeg na regs bo"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Beweeg na links onder"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Beweeg na regs onder"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Maak borrel toe"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Moenie dat gesprek \'n borrel word nie"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Klets met borrels"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nuwe gesprekke verskyn as swerwende ikone, of borrels Tik op borrel om dit oop te maak. Sleep om dit te skuif."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Beheer borrels enige tyd"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tik op Bestuur om borrels vanaf hierdie program af te skakel"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Het dit"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-instellings"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Bystandmodus"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bind nuwe toestel saam"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kon nie jou batterymeter lees nie"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik vir meer inligting"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml
index f277529..3aeeb86 100644
--- a/packages/SystemUI/res/values-af/strings_tv.xml
+++ b/packages/SystemUI/res/values-af/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofoon aktief"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s het toegang tot jou mikrofoon"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index b2a7c16..a36e0e2 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ቅጽበታዊ ገጽ ዕይታን እንደገና ማንሳት ይሞክሩ"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"ባለው ውሱን የማከማቻ ቦታ ምክንያት ቅጽበታዊ ገጽ ዕይታን ማስቀመጥ አይችልም"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ቅጽበታዊ ገጽ እይታዎችን ማንሳት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ቅጽበታዊ ገጽ ዕይታን አርትዕ ያድርጉ"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ቅጽበታዊ ገጽ እይታን አሰናብት"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"የቅጽበታዊ ገጽ ዕይታ ቅድመ-ዕይታ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"የማያ መቅጃ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገጽ ቀረጻን በማሰናዳት ላይ"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ባትሪ ሁለት አሞሌዎች።"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ባትሪ ሦስት አሞሌዎች።"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ባትሪ ሙሉ ነው።"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"የባትሪ መቶኛ አይታወቅም።"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ምንም ስልክ የለም።"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"የስልክ አንድ አሞሌ"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"የስልክ ሁለት አሞሌ"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ማሳወቂያ ተወግዷል።"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"አረፋ ተሰናብቷል።"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"የማሳወቂያ ጥላ።"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ፈጣን ቅንብሮች።"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ማያ ገጽ ቆልፍ።"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"መገለጫ ክትትል ሊደረግበት ይችላል"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"አውታረ መረብ በክትትል እየተደረገበት ሊሆን ይችላል"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"አውታረ መረብ ክትትል የሚደረግበት ሊሆን ይችላል"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው።"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"የእርስዎ ድርጅት የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ይህ መሣሪያ የድርጅትዎ ሲሆን ከ<xliff:g id="VPN_APP">%1$s</xliff:g> ጋር ተገናኝቷል"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN አሰናክል"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"የVPN ግንኙነት አቋርጥ"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"መመሪያዎችን ይመልከቱ"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"መቆጣጠሪያዎችን አሳይ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ይህ መሣሪያ የ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ነው።\n\nየእርስዎ የአይቲ አስተዳዳሪ ቅንብሮችን፣ የኮርፖሬት መዳረሻን፣ መተግበሪያዎችን፣ ከመሣሪያዎ ጋር የተጎዳኘ ውሂብን እና የመሣሪያዎ አካባቢ መረጃን መከታተል እና ማቀናበር ይችላል።\n\nተጨማሪ መረጃ የአይቲ አስተዳዳሪዎን ያነጋግሩ።"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ይህ መሣሪያ የድርጅትዎ ነው።\n\nየእርስዎ የአይቲ አስተዳዳሪ ቅንብሮችን፣ የኮርፖሬት መዳረሻን፣ መተግበሪያዎችን፣ ከመሣሪያዎ ጋር የተጎዳኘ ውሂብን እና የመሣሪያዎ አካባቢ መረጃን መከታተል እና ማቀናበር ይችላል።\n\nለተጨማሪ መረጃ የአይቲ አስተዳዳሪዎን ያነጋግሩ።"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"የእርስዎ ድርጅት የእውቅና ማረጋገጫ ሰጪ ባለሥልጣን በዚህ መሣሪያ ላይ ጭኗል። የእርስዎ ደኅንነቱ የተጠበቀ አውታረ መረብ ትራፊክ ክትትል ሊደረግበት እና ሊሻሻል ይችላል።"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"የእርስዎ አስተዳዳሪ የአውታረ መረብ ምዝግብ ማስታወሻ መያዝን አብርተዋል፣ ይህም በመሣሪያዎ ላይ ያለውን ትራፊክ ይከታተላል።\n\nተጨማሪ መረጃ ለማግኘት አስተዳዳሪዎን ያነጋግሩ።"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"አንድ መተግበሪያ የVPN ግንኙነት እንዲያዋቅር ፍቃድ ሰጥተውታል።\n\nይህ መተግበሪያ ኢሜይሎችን፣ መተግበሪያዎችን እና ድር ጣቢያዎችንም ጨምሮ የመሣሪያዎን እና የአውታረ መረብ እንቅስቃሴዎን መከታተል ይችላል።"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"የእርስዎ የስራ መገለጫ በ<xliff:g id="ORGANIZATION">%1$s</xliff:g> ነው የሚቀናበረው።\n\nየእርስዎ አስተዳዳሪ ኢሜይሎችን፣ መተግበሪያዎችን እና ድር ጣቢያዎችን ጨምሮ የአውታረ መረብ እንቅስቃሴዎን መከታተል ይችላል።\n\nተጨማሪ መረጃ ለማግኘት አስተዳዳሪዎን ያነጋግሩ።\n\nእርስዎ እንዲሁም የአውታረ መረብ እንቅስቃሴዎን መከታተል ከሚችል ቪፒኤን ጋር ተገናኝተዋል።"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው። ወላጅዎ የሚጠቀሙባቸውን መተግበሪያዎች፣ አካባቢዎን እና የማያ ገጽ ጊዜዎን የመሳሰሉ መረጃዎችን ማየት እና ማስተዳደር ይችላል።"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"እርስዎ ኢሜይሎችን፣ መተግበሪያዎችን እና ድር ጣቢያዎችንም ጨምሮ የአውታረ መረብ እንቅስቃሴዎን ከሚከታተለው <xliff:g id="APPLICATION">%1$s</xliff:g> ጋር ተገናኝተዋል።"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"እርስዎ ኢሜይሎችን፣ መተግበሪያዎችን እና ድር ጣቢያዎችንም ጨምሮ የግል የአውታረ መረብ እንቅስቃሴዎን መከታተል ከሚችለው <xliff:g id="APPLICATION">%1$s</xliff:g> ጋር ተገናኝተዋል።"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ከዚህ መተግበሪያ ማሳወቂያዎችን ማሳየት ይቀጥል?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ፀጥ ያለ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ነባሪ"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"አረፋ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ራስ-ሰር"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ምንም ድምጽ ወይም ንዝረት የለም"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ምንም ድምጽ ወይም ንዝረት የለም እና በውይይት ክፍል ላይ አይታይም"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ቅንብሮች"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ቅድሚያ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> የውይይት ባህሪያትን አይደግፍም"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ምንም የቅርብ ጊዜ አረፋዎች የሉም"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"የቅርብ ጊዜ አረፋዎች እና የተሰናበቱ አረፋዎች እዚህ ብቅ ይላሉ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"የማሳወቂያዎች ይህ ቡድን እዚህ ላይ ሊዋቀር አይችልም"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ተኪ ማሳወቂያ"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"የመሣሪያ አገልግሎቶች"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ርዕስ የለም"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ይህን መተግበሪያ እንደገና ለማስጀመር መታ ያድርጉ እና ወደ ሙሉ ማያ ገጽ ይሂዱ።"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"ቅንብሮች ለ <xliff:g id="APP_NAME">%1$s</xliff:g> አረፋዎች"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ትርፍ ፍሰት"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ወደ ቁልል መልሰው ያክሉ"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"ያቀናብሩ"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ከ<xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ከ <xliff:g id="APP_NAME">%2$s</xliff:g> እና <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ተጨማሪ"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"አንቀሳቅስ"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ወደ ላይኛው ግራ አንቀሳቅስ"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ወደ ላይኛው ቀኝ አንቀሳቅስ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"የግርጌውን ግራ አንቀሳቅስ"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ታችኛውን ቀኝ ያንቀሳቅሱ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"አረፋን አሰናብት"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"ውይይቶችን በአረፋ አታሳይ"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"አረፋዎችን በመጠቀም ይወያዩ"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"አዲስ ውይይቶች እንደ ተንሳፋፊ አዶዎች ወይም አረፋዎች ሆነው ይታያሉ። አረፋን ለመክፈት መታ ያድርጉ። ለመውሰድ ይጎትቱት።"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"በማንኛውም ጊዜ አረፋዎችን ይቆጣጠሩ"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"የዚህ መተግበሪያ አረፋዎችን ለማጥፋት አቀናብርን መታ ያድርጉ"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ገባኝ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"የ<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ቅንብሮች"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ተጠባባቂ"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"አዲስ መሣሪያ ያጣምሩ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"የባትሪ መለኪያዎን የማንበብ ችግር"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ለበለጠ መረጃ መታ ያድርጉ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
index d9ec459..66847d1 100644
--- a/packages/SystemUI/res/values-am/strings_tv.xml
+++ b/packages/SystemUI/res/values-am/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"ማይክራፎን ንቁ ነው"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s የእርስዎን ማይክራፎን ደርሶበታል"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 2cced23..a976a76 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"جرّب أخذ لقطة الشاشة مرة أخرى"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"يتعذر حفظ لقطة الشاشة لأن مساحة التخزين المتاحة محدودة."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"يحظر التطبيق أو تحظر مؤسستك التقاط لقطات شاشة"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"تعديل لقطة الشاشة"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"إغلاق لقطة الشاشة"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"معاينة لقطة الشاشة"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"مسجّل الشاشة"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"إشارة البطارية تتكون من شريطين."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"إشارة البطارية تتكون من ثلاثة أشرطة."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"إشارة البطارية كاملة."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"نسبة شحن البطارية غير معروفة."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ليست هناك إشارة بالهاتف."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"إشارة الهاتف تتكون من شريط واحد."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"إشارة الهاتف تتكون من شريطين."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"تم تجاهل الإشعار."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"تم إغلاق الفقاعة."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"مركز الإشعارات."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"الإعدادات السريعة."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"شاشة القفل."</string>
@@ -532,6 +540,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ربما تتم مراقبة الملف الشخصي"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"قد تكون الشبكة خاضعة للمراقبة"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"قد تكون الشبكة خاضعة للمراقبة"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"يتولّى أحد الوالدين إدارة هذا الجهاز."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"تملك مؤسستك هذا الجهاز ويمكنها تتبّع حركة بيانات الشبكة."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"تملك مؤسسة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> هذا الجهاز ويمكنها تتبّع حركة بيانات الشبكة"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"هذا الجهاز يخص مؤسستك وتم ربطه بشبكة <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
@@ -556,6 +565,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"إيقاف الشبكة الافتراضية الخاصة"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"‏قطع الاتصال بشبكة VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"عرض السياسات"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"عرض عناصر التحكم"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"هذا الجهاز يخص <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nيمكن لمشرف تكنولوجيا المعلومات تتبّع وإدارة الإعدادات والتطبيقات والبيانات المرتبطة بجهازك ومعلومات الموقع الجغرافي للجهاز وعمليات الدخول إلى نظام المؤسسة.\n\nللحصول على المزيد من المعلومات، يمكنك التواصل مع مشرف تكنولوجيا المعلومات."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"هذا الجهاز يخص مؤسستك.\n\nيمكن لمشرف تكنولوجيا المعلومات في مؤسستك تتبّع وإدارة الإعدادات والتطبيقات والبيانات المرتبطة بجهازك ومعلومات الموقع الجغرافي للجهاز وعمليات الدخول إلى نظام المؤسسة.\n\nللحصول على المزيد من المعلومات، يمكنك التواصل مع مشرف تكنولوجيا المعلومات."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ثبّتت مؤسستك مرجعًا مصدّقًا على هذا الجهاز. قد تتم مراقبة حركة بيانات شبكتك الآمنة أو تعديلها."</string>
@@ -579,6 +589,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"شغَّل المشرف ميزة تسجيل بيانات الشبكة، والتي يتم من خلالها مراقبة حركة البيانات على جهازك.\n\nللحصول على المزيد من المعلومات، اتصل بالمشرف."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"‏لقد منحت تطبيقًا الإذن لإعداد اتصال شبكة افتراضية خاصة (VPN).\n\nيمكن لهذا التطبيق مراقبة أنشطتك على الجهاز والشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"تتم إدارة ملفك الشخصي للعمل بواسطة <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nويمكن للمشرف مراقبة نشاط الشبكة، بما في ذلك رسائل البريد الإلكتروني والتطبيقات والمواقع الإلكترونية.\n\nللحصول على المزيد من المعلومات، اتصل بالمشرف.\n\nوتجدر الإشارة إلى أنك متصل أيضًا بشبكة افتراضية خاصة يمكن أن تراقب نشاط الشبكة."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"يتولّى أحد الوالدين إدارة هذا الجهاز. يمكن للوالدين عرض وإدارة معلوماتك، مثلاً التطبيقات التي تستخدمها وموقعك الجغرافي ووقت النظر إلى الشاشة."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"شبكة افتراضية خاصة"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"تم ربطك بـ <xliff:g id="APPLICATION">%1$s</xliff:g>، الذي يمكنه مراقبة أنشطتك على الشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"أنت متصل بـ <xliff:g id="APPLICATION">%1$s</xliff:g>، الذي يمكنه مراقبة أنشطتك الشخصية على الشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
@@ -721,7 +732,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"هل تريد الاستمرار في تلقي إشعارات من هذا التطبيق؟"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"صامتة"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"تلقائية"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"فقاعة"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"تلقائي"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"بدون صوت أو اهتزاز"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"بدون صوت أو اهتزاز وتظهر في موضع أسفل في قسم المحادثات"</string>
@@ -733,8 +743,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"الإعدادات"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"الأولوية"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"لا يدعم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> ميزات المحادثات."</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ليس هناك فقاعات محادثات"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"ستظهر هنا أحدث فقاعات المحادثات وفقاعات المحادثات التي تم إغلاقها."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"يتعذّر تعديل هذه الإشعارات."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"يتعذّر ضبط مجموعة الإشعارات هذه هنا."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"إشعار مستند إلى خادم وكيل"</string>
@@ -1001,25 +1009,7 @@
     <string name="device_services" msgid="1549944177856658705">"خدمات الأجهزة"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"بلا عنوان"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"انقر لإعادة تشغيل هذا التطبيق والانتقال إلى وضع ملء الشاشة."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"إعدادات فقاعات المحادثات على <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"القائمة الكاملة"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"إضافة دعم إلى الحزم"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"إدارة"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> من <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> من <xliff:g id="APP_NAME">%2$s</xliff:g> و<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> أيضًا"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"نقل"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"نقل إلى أعلى يمين الشاشة"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"الانتقال إلى أعلى اليسار"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"نقل إلى أسفل يمين الشاشة"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"نقل إلى أسفل اليسار"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"إغلاق فقاعة المحادثة"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"عدم عرض المحادثة كفقاعة محادثة"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"الدردشة باستخدام فقاعات المحادثات"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"تظهر المحادثات الجديدة كرموز عائمة أو كفقاعات. انقر لفتح فقاعة المحادثة، واسحبها لتحريكها."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"التحكّم في فقاعات المحادثات في أي وقت"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"انقر على \"إدارة\" لإيقاف فقاعات المحادثات من هذا التطبيق."</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"حسنًا"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"إعدادات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"وضع الاستعداد"</string>
@@ -1113,4 +1103,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"إقران جهاز جديد"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"حدثت مشكلة أثناء قراءة مقياس مستوى شحن البطارية."</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"انقر للحصول على مزيد من المعلومات."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml
index c29d804..9f93057 100644
--- a/packages/SystemUI/res/values-ar/strings_tv.xml
+++ b/packages/SystemUI/res/values-ar/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"الميكروفون نشط"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"‏تمكن %1$s من الوصول إلى الميكروفون الخاص بك."</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 4c43e4e..b84f409 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"স্ক্ৰীণশ্বট আকৌ ল\'বলৈ চেষ্টা কৰক"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"সঞ্চয়াগাৰত সীমিত খালী ঠাই থকাৰ বাবে স্ক্ৰীণশ্বট ছেভ কৰিব পৰা নগ\'ল"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"এপটোৱে বা আপোনাৰ প্ৰতিষ্ঠানে স্ক্ৰীণশ্বট ল\'বলৈ অনুমতি নিদিয়ে"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"স্ক্ৰীনশ্বট সম্পাদনা কৰক"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"স্ক্ৰীনশ্বট অগ্ৰাহ্য কৰক"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"সম্পাদনা কৰক"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"স্ক্ৰীনশ্বট সম্পাদনা কৰক"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"স্ক্ৰ’ল কৰক"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"স্ক্ৰীনশ্বট স্ক্ৰ’ল কৰক"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"স্ক্ৰীনশ্বট অগ্ৰাহ্য কৰক"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"স্ক্ৰীনশ্বটৰ পূৰ্বদৰ্শন"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্ৰীন ৰেকৰ্ডাৰ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রীন ৰেকৰ্ডিঙৰ প্ৰক্ৰিয়াকৰণ হৈ আছে"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"বেটাৰিৰ দুডাল দণ্ড।"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"বেটাৰিৰ তিনিডাল দণ্ড।"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"বেটাৰি পূৰাকৈ চ্চাৰ্জ হৈছে।"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"বেটাৰীৰ চাৰ্জৰ শতাংশ অজ্ঞাত।"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ফ\'নত ছিগনেল নাই৷"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ফ\'ন ছিগনেলৰ এডাল দণ্ড।"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ফ\'ন ছিগনেলৰ দুডাল দণ্ড।"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"জাননী অগ্ৰাহ্য কৰা হৈছে।"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"বাবল অগ্ৰাহ্য কৰা হৈছে"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"জাননী পেনেল।"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ক্ষিপ্ৰ ছেটিংসমূহ।"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"বন্ধ স্ক্ৰীণ।"</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"প্ৰ\'ফাইল নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"নেটৱৰ্ক নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"নেটৱৰ্ক নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইচটোৰ গৰাকী আপোনাৰ প্ৰতিষ্ঠান আৰু ই নেটৱৰ্কৰ ট্ৰেফিক নিৰীক্ষণ কৰিব পাৰে"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"এই ডিভাইচটোৰ গৰাকী <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> আৰু এইটোৱে নেটৱৰ্কৰ ট্ৰেফিক নিৰীক্ষণ কৰিব পাৰে"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ আৰু এইটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"ভিপিএন অক্ষম কৰক"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"ভিপিএন সংযোগ বিচ্ছিন্ন কৰক"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"নীতিসমূহ চাওক"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"নিয়ন্ত্ৰণসমূহ চাওক"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ৰ।\n\nআপোনাৰ আইটি প্ৰশাসকে আপোনাৰ ডিভাইচটোৰ লগত জড়িত ছেটিংসমূহ, কৰ্পৰে’টৰ এক্সেছ, এপ্‌সমূহ, ডেটা আৰু আপোনাৰ ডিভাইচটোৰ অৱস্থান সম্পৰ্কীয় তথ্য নিৰীক্ষণ কৰাৰ লগতে সেয়া পৰিচালনা কৰিব পাৰে।\n\nঅধিক তথ্যৰ বাবে আপোনাৰ আইটি প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ।\n\nআপোনাৰ আইটি প্ৰশাসকে আপোনাৰ ডিভাইচটোৰ লগত জড়িত ছেটিংসমূহ, কৰ্পৰে’টৰ এক্সেছ, এপ্‌সমূহ, ডেটা আৰু আপোনাৰ ডিভাইচটোৰ অৱস্থান সম্পৰ্কীয় তথ্য নিৰীক্ষণ কৰাৰ লগতে সেয়া পৰিচালনা কৰিব পাৰে।\n\nঅধিক তথ্যৰ বাবে আপোনাৰ আইটি প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰিছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"আপোনাৰ প্ৰশাসকে নেটৱৰ্ক লগিং অন কৰিছে, যিয়ে আপোনাৰ ডিভাইচটোত নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ কৰে।\n\nএই সম্পৰ্কে অধিক জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"আপুনি এটা এপক ভিপিএন সংযোগ ছেট আপ কৰিবলৈ অনুমতি দিছে। \n\n এই এপটোৱে ইমেইল, এপ্ আৰু ৱেবছাইটকে ধৰি আপোনাৰ নেটৱর্কৰ কাৰ্যকলাপ পৰ্যবেক্ষণ কৰিব পাৰে।"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g>য়ে আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল পৰিচালনা কৰে।\n\nআপোনাৰ প্ৰশাসকে ইমেইল, এপসমূহ আৰু আপুনি চোৱা ৱেবছাইটকে ধৰি আপোনাৰ নেটৱৰ্কৰ সকলো কাৰ্যকলাপ পৰ্যবেক্ষণ কৰিব পাৰে। \n\nঅধিক তথ্যৰ বাবে আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।\n\nইয়াৰ উপৰি, আপুনি এটা ভিপিএনৰ সৈতে সংযুক্ত হৈ আছে, যিয়ে আপোনাৰ নেটৱৰ্কৰ কাৰ্যকলাপ পৰ্যবেক্ষণ কৰিব পাৰে।"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে। আপোনাৰ অভিভাৱকে আপুনি ব্যৱহাৰ কৰা এপ্‌, আপোনাৰ অৱস্থান আৰু আপুনি ডিভাইচত অতিবাহিত কৰা সময়ৰ দৰে তথ্য চাব আৰু পৰিচালনা কৰিব পাৰে।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"ভিপিএন"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"আপুনি <xliff:g id="APPLICATION">%1$s</xliff:g>ৰে সংযুক্ত হৈ আছে যিয়ে আপোনাৰ ইমেইল, এপ্ আৰু ৱেবছাইটকে ধৰি নেটৱর্কৰ কাৰ্যকলাপ পৰ্যবেক্ষণ কৰিব পাৰে।"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"আপুনি <xliff:g id="APPLICATION">%1$s</xliff:g>ৰে সংযুক্ত হৈ আছে, যি ইমেইল, এপ্ আৰু ৱেবছাইটসমূহকে ধৰি আপোনাৰ ব্যক্তিগত নেটৱর্কৰ কাৰ্যকলাপ নিৰীক্ষণ কৰিব পাৰে।"</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"এই এপটোৰ জাননী দেখুওৱাই থাকিব লাগিবনে?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"নীৰৱ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ডিফ’ল্ট"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"বাবল"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"স্বয়ংক্ৰিয়"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"কোনো ধ্বনি অথবা কম্পন নাই"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"কোনো ধ্বনি অথবা কম্পন নাই আৰু বাৰ্তালাপ শাখাটোৰ তলৰ অংশত দেখা পোৱা যায়"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ছেটিংসমূহ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"অগ্ৰাধিকাৰ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বাৰ্তালাপৰ সুবিধাসমূহ সমৰ্থন নকৰে"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"কোনো শেহতীয়া bubbles নাই"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"শেহতীয়া bubbles আৰু অগ্ৰাহ্য কৰা bubbles ইয়াত প্ৰদর্শিত হ\'ব"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"এই জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"এই ধৰণৰ জাননীবোৰ ইয়াত কনফিগাৰ কৰিব পৰা নাযায়"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"প্ৰক্সি হিচাপে পঠিওৱা জাননী"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"ডিভাইচ সেৱা"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"কোনো শিৰোনাম নাই"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"এপ্‌টো ৰিষ্টাৰ্ট কৰক আৰু পূৰ্ণ স্ক্ৰীণ ব্যৱহাৰ কৰক।"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ bubblesৰ ছেটিংসমূহ"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"অভাৰফ্ল’"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ষ্টেকত পুনৰ যোগ দিয়ক"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"পৰিচালনা কৰক"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>ৰ পৰা <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> আৰু<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>টাৰ পৰা <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"আঁতৰাওক"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"শীৰ্ষৰ বাওঁফালে নিয়ক"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"শীৰ্ষৰ সোঁফালে নিয়ক"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"বুটামটো বাওঁফালে নিয়ক"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"তলৰ সোঁফালে নিয়ক"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"বাবল অগ্ৰাহ্য কৰক"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"বাৰ্তালাপ বাবল নকৰিব"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Bubbles ব্যৱহাৰ কৰি চাট কৰক"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"নতুন বাৰ্তালাপ উপঙি থকা চিহ্নসমূহ অথবা bubbles হিচাপে প্ৰদর্শিত হয়। Bubbles খুলিবলৈ টিপক। এইটো স্থানান্তৰ কৰিবলৈ টানি নিয়ক।"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"যিকোনো সময়তে bubbles নিয়ন্ত্ৰণ কৰক"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"এই এপ্‌টোৰ পৰা bubbles অফ কৰিবলৈ পৰিচালনা কৰকত টিপক"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"বুজি পালোঁ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ছেটিংসমূহ"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ষ্টেণ্ডবাই"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইচ পেয়াৰ কৰক"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"আপোনাৰ বেটাৰী মিটাৰ পঢ়োঁতে সমস্যা হৈছে"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"অধিক তথ্যৰ বাবে টিপক"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings_tv.xml b/packages/SystemUI/res/values-as/strings_tv.xml
index 1db8f229..118c627 100644
--- a/packages/SystemUI/res/values-as/strings_tv.xml
+++ b/packages/SystemUI/res/values-as/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"মাইক্ৰ’ফ’ন সক্ৰিয় কৰা আছে"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$sএ আপোনাৰ মাইক্ৰ’ফ’ন এক্সেছ কৰিছে"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 4cefd84..a329288 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Skrinşotu yenidən çəkin"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Yaddaş ehtiyatının az olması səbəbindən skrinşotu yadda saxlamaq olmur"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Skrinşot çəkməyə tətbiq və ya təşkilat tərəfindən icazə verilmir"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Skrinşota düzəliş edin"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ekran şəklini ötürün"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Redaktə edin"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Skrinşota düzəliş edin"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Sürüşdürün"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Sürüşdürülərək çəkilən skrinşot"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ekran şəklini ötürün"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekran şəklinə önbaxış"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Yazıcısı"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran çəkilişi emal edilir"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Batareya iki xətdir."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Batareya üç xətdir."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batareya doludur"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batareyanın faizi naməlumdur."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Telefon yoxdur."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Şəbəkə bir xətdir."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Şəbəkə iki xətdir."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Bildiriş uzaqlaşdırıldı."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Qabarcıqdan imtina edilib."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bildiriş kölgəsi."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Tez ayarlar."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ekranı kilidləyin."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil izlənə bilər"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Şəbəkə nəzərdən keçirilə bilər"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Şəbəkə nəzərdən keçirilə bilər"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz valideyniniz tərəfindən idarə olunur"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Təşkilatınız bu cihazın sahibidir və şəbəkə trafikinə nəzarət edə bilər"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bu cihazın sahibidir və şəbəkə trafikinə nəzarət edə bilər"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Bu cihaz təşkilatınıza məxsusdur və <xliff:g id="VPN_APP">%1$s</xliff:g> şəbəkəsinə qoşulub"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN-i deaktiv edin"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN-i bağlantıdan ayırın"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Siyasətlərə Baxın"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Nizamlayıcılara baxın"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> təşkilatına məxsusdur.\n\nIT admininiz cihaz və cihaz məkan məlumatı ilə əlaqəli ayarlara, korporativ girişə, tətbiqə və dataya nəzarət edə və idarə edə bilər.\n\nƏtraflı məlumat üçün IT admini ilə əlaqə saxlayın."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Bu cihaz təşkilatınıza məxsusdur.\n\nIT admininiz cihaz və cihaz məkan məlumatı ilə əlaqəli ayarlara, korporativ girişə, tətbiqə və dataya nəzarət edə və idarə edə bilər.\n\nƏtraflı məlumat üçün IT admini ilə əlaqə saxlayın."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Təşkilat bu cihazda sertifikat səlahiyyəti quraşdırdı. Təhlükəsiz şəbəkə ötürülməsinə nəzarət edilə və ya dəyişdirilə bilər."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Admin, cihazdakı trafikə nəzarət edən şəbəkə loqlarını aktiv etdi.\n\nƏtraflı məlumat üçün administrator ilə əlaqə saxlayın."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"VPN bağlantısı quraşdırmağa icazə vermisiniz.\n\nBu tətbiq cihazınızı və şəbəkə fəaliyyətinizi, həmçinin, e-məktubları, tətbiq və veb saytları izləyə bilər."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"İş profiliniz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tərəfindən idarə olunur.\n\nAdmin e-poçt, tətbiq və veb saytlar daxil olmaqla şəbəkə fəaliyətinizə nəzarət etməyə qadirdir.\n\nƏtraflı məlumat üçün administrator ilə əlaqə saxlayın.\n\nEyni zamanda, şəbəkə fəaliyyətinizə nəzarət edən VPN\'ə qoşulusunuz."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu cihaz valideyniniz tərəfindən idarə olunur. Valideyniniz istifadə etdiyiniz tətbiqlər, məkanınız və ekran vaxtınız kimi məlumatları görə və idarə edə bilər."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN (Virtual Şəxsi Şəbəkələr)"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"E-poçt, tətbiq və veb saytlar da daxil olmaqla şəbəkə fəaliyyətinə nəzarət edən <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə qoşulusunuz."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə qoşulmusunuz və o, e-məktublar, tətbiq və veb saytlar daxil olmaqla şəxsi şəbəkə fəaliyyətinizə nəzarət edə bilər."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Bu tətbiqin bildirişləri göstərilməyə davam edilsin?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Səssiz"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Defolt"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Qabarcıq"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Səs və ya vibrasiya yoxdur"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Səs və ya vibrasiya yoxdur və söhbət bölməsinin aşağısında görünür"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ayarlar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> söhbət funksiyalarını dəstəkləmir"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Yumrucuqlar yoxdur"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Son yumrucuqlar və buraxılmış yumrucuqlar burada görünəcək"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirişlər dəyişdirilə bilməz."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildiriş qrupunu burada konfiqurasiya etmək olmaz"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proksi bildirişi"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Cihaz Xidmətləri"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıq yoxdur"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Bu tətbiqi sıfırlayaraq tam ekrana keçmək üçün klikləyin."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> yumrucuqları üçün ayarlar"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Kənara çıxma"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Yenidən dəstəyə əlavə edin"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"İdarə edin"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> tətbiqindən <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> tətbiqindən <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> və daha <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> qabarcıq"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Hərəkət etdirin"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Yuxarıya sola köçürün"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Yuxarıya sağa köçürün"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Aşağıya sola köçürün"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Aşağıya sağa köçürün"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Yumrucuğu ləğv edin"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Söhbəti yumrucuqda göstərmə"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Yumrucuqlardan istifadə edərək söhbət edin"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Yeni söhbətlər üzən nişanlar və ya yumrucuqlar kimi görünür. Yumrucuğu açmaq üçün toxunun. Hərəkət etdirmək üçün sürüşdürün."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Yumrucuqları istənilən vaxt idarə edin"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu tətbiqdə yumrucuqları deaktiv etmək üçün \"İdarə edin\" seçiminə toxunun"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Anladım"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistem naviqasiyası yeniləndi. Dəyişiklik etmək üçün Ayarlara daxil olun."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistem naviqasiyasını yeniləmək üçün Ayarlara keçin"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gözləmə rejimi"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihazı qoşalaşdırın"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versiya nömrəsi"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya ölçüsünü oxuyarkən problem yarandı"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ətraflı məlumat üçün toxunun"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings_tv.xml b/packages/SystemUI/res/values-az/strings_tv.xml
index d690c64..037eb7c 100644
--- a/packages/SystemUI/res/values-az/strings_tv.xml
+++ b/packages/SystemUI/res/values-az/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon Aktivdir"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s mikrofona daxil olub"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 68ef1a3..d800e8d 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probajte da ponovo napravite snimak ekrana"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Čuvanje snimka ekrana nije uspelo zbog ograničenog memorijskog prostora"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Izmenite snimak ekrana"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Odbacite snimak ekrana"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Izmeni"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Izmenite snimak ekrana"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Pomeraj"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Pomerajte snimak ekrana"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacite snimak ekrana"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimka ekrana"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Baterija od dve crte."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Baterija od tri crte."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Baterija je puna."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procenat napunjenosti baterije nije poznat."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nema telefona."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Signal telefona ima jednu crtu."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Signal telefona od dve crte."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Obaveštenje je odbačeno."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Oblačić je odbačen."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Prozor sa obaveštenjima."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brza podešavanja."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključan ekran."</string>
@@ -523,6 +526,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil se možda nadgleda"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Mreža se možda nadgleda"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Mreža se možda nadgleda"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizacija je vlasnik uređaja i može da nadgleda mrežni saobraćaj"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je vlasnik ovog uređaja i može da nadgleda mrežni saobraćaj"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada organizaciji i povezan je sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -547,6 +551,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Onemogući VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Prekini vezu sa VPN-om"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži smernice"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Prikaži kontrole"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada organizaciji.\n\nIT administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od IT administratora."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizacija je na ovom uređaju instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
@@ -570,6 +575,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na uređaju.\n\nKontaktirajte administratora za više informacija."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Dali ste dozvolu aplikaciji da podešava VPN vezu.\n\nTa aplikacija može da nadgleda aktivnosti na uređaju i mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> upravlja poslovnim profilom.\n\nAdministrator može da prati aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nKontaktirajte administratora za više informacija.\n\nPovezani ste i sa VPN-om, koji može da prati aktivnosti na mreži."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja roditelj. Roditelj može da vidi informacije, kao što su aplikacije koje koristiš, tvoju lokaciju i vreme ispred ekrana, i da upravlja njima."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
@@ -712,7 +718,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Želite li da se obaveštenja iz ove aplikacije i dalje prikazuju?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Podrazumevano"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Oblačić"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatska"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka i vibriranja"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka i vibriranja i prikazuje se u nastavku odeljka za konverzacije"</string>
@@ -724,8 +729,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Podešavanja"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije konverzacije"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nema nedavnih oblačića"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Ovde se prikazuju nedavni i odbačeni oblačići"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ova obaveštenja ne mogu da se menjaju."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Obaveštenje preko proksija"</string>
@@ -986,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Usluge za uređaje"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Dodirnite da biste restartovali aplikaciju i prešli u režim celog ekrana."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Podešavanja za <xliff:g id="APP_NAME">%1$s</xliff:g> oblačiće"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Preklapanje"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodaj ponovo u grupu"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Upravljajte"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g> i još <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Premesti"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Premesti gore levo"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Premesti gore desno"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Premesti dole levo"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Premesti dole desno"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Odbaci oblačić"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ne koristi oblačiće za konverzaciju"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Ćaskajte u oblačićima"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nove konverzacije se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da biste otvorili oblačić. Prevucite da biste ga premestili."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolišite oblačiće u bilo kom trenutku"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljajte da biste isključili oblačiće iz ove aplikacije"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Važi"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Podešavanja za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string>
@@ -1095,4 +1080,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem sa očitavanjem merača baterije"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index d045cea..5f03299 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon je aktivan"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacija %1$s je pristupila mikrofonu"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 6396cbe..9fd9a5e 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Паспрабуйце зрабіць здымак экрана яшчэ раз"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Немагчыма захаваць здымак экрана, бо мала месца ў сховішчы"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Рабіць здымкі экрана не дазваляе праграма ці ваша арганізацыя"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Змяніць здымак экрана"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Адхіліць здымак экрана"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Змяніць"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Змяніць здымак экрана"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Прагартаць"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Здымак экрана з пракруткай"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Адхіліць здымак экрана"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Перадпрагляд здымка экрана"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запіс экрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Апрацоўваецца запіс экрана"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"2 планкі акумулятара."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Тры планкі акумулятара."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Акумулятар поўны."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Працэнт зараду акумулятара невядомы."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Няма тэлефона."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Адна планка на тэлефоне."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"2 планкі тэлефона."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Апавяшчэнне прапушчана."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Усплывальнае апавяшчэнне адхілена."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Цень апавяшчэння.."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Хуткія налады."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Экран блакіроўкі."</string>
@@ -526,6 +529,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"За профілем могуць назіраць"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"За сеткай могуць назіраць"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"За сеткай могуць назіраць"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Гэта прылада знаходзіцца пад кантролем вашых бацькоў"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша арганізацыя валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Гэта прылада належыць вашай арганізацыі і падключана да праграмы \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
@@ -550,6 +554,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Адключыць VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Адлучыць VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Праглядзець палітыку"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Праглядзець даныя пра кантроль"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nВаш ІТ-адміністратар можа адсочваць налады, карпаратыўны доступ, праграмы, даныя, звязаныя з вашай прыладай, і звесткі пра яе месцазнаходжанне, а таксама кіраваць імі.\n\nПа дадатковую інфармацыю звярніцеся да ІТ-адміністратара."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Гэта прылада належыць вашай арганізацыі.\n\nВаш ІТ-адміністратар можа адсочваць налады, карпаратыўны доступ, праграмы, даныя, звязаныя з вашай прыладай, і звесткі пра яе месцазнаходжанне, а таксама кіраваць імі.\n\nПа дадатковую інфармацыю звярніцеся да ІТ-адміністратара."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ваша арганізацыя ўсталявала на гэтай прыладзе цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
@@ -573,6 +578,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Ваш адміністратар уключыў вядзенне журнала сеткі, з дапамогай якога адсочваецца трафік на вашай прыладзе.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Вы далі праграме дазвол на наладжванне злучэння VPN.\n\nГэта праграма можа сачыць за актыўнасцю вашай прылады і вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nВаш адміністратар можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара.\n\nВы таксама падключаны да сеткі VPN, якая можа сачыць за вашай сеткавай дзейнасцю."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Гэта прылада знаходзіцца пад кантролем вашых бацькоў. Бацькі могуць праглядаць і кантраляваць вашу інфармацыю, напрыклад пра праграмы, якія вы выкарыстоўваеце, даныя пра ваша месцазнаходжанне і час карыстання прыладай."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Вы падключаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Вы падлучаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая сачыць за вашай асабістай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
@@ -715,7 +721,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Працягваць паказваць апавяшчэнні гэтай праграмы?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Бязгучны рэжым"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Стандартна"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Усплывальнае апавяшчэнне"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Аўтаматычна"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без гуку ці вібрацыі"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Паказваецца без гуку ці вібрацыі ў раздзеле размоў"</string>
@@ -727,8 +732,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Налады"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Прыярытэт"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не падтрымлівае функцыі размовы"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Няма нядаўніх усплывальных апавяшчэнняў"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Нядаўнія і адхіленыя ўсплывальныя апавяшчэнні будуць паказаны тут"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Гэтыя апавяшчэнні нельга змяніць."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Тут канфігурыраваць гэту групу апавяшчэнняў забаронена"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Праксіраванае апавяшчэнне"</string>
@@ -991,25 +994,7 @@
     <string name="device_services" msgid="1549944177856658705">"Сэрвісы прылады"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без назвы"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Націсніце, каб перазапусціць гэту праграму і перайсці ў поўнаэкранны рэжым."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Налады ўсплывальных апавяшчэнняў у праграме \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Дадатковае меню"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Зноў дадаць у стос"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Кіраваць"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ад праграмы \"<xliff:g id="APP_NAME">%2$s</xliff:g>\""</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ад праграмы \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" і яшчэ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Перамясціць"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Перамясціць лявей і вышэй"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Перамясціце правей і вышэй"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Перамясціць лявей і ніжэй"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Перамясціць правей і ніжэй"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Адхіліць апавяшчэнне"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не паказваць размову ў выглядзе ўсплывальных апавяшчэнняў"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Усплывальныя апавяшчэнні"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Новыя размовы будуць паказвацца як рухомыя значкі ці ўсплывальныя апавяшчэнні. Націсніце, каб адкрыць усплывальнае апавяшчэнне. Перацягніце яго, каб перамясціць."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Кіруйце ўсплывальнымі апавяшчэннямі ў любы час"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Каб выключыць усплывальныя апавяшчэнні з гэтай праграмы, націсніце \"Кіраваць\""</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Зразумела"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Налады \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string>
@@ -1101,4 +1086,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спалучыць з новай прыладай"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Праблема з чытаннем індыкатара зараду акумулятара"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Націсніце, каб убачыць больш"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml
index 37f925e..7433d15 100644
--- a/packages/SystemUI/res/values-be/strings_tv.xml
+++ b/packages/SystemUI/res/values-be/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Мікрафон актыўны"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Праграма \"%1$s\" атрымала доступ да мікрафона"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 26a313a..78a826b 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Опитайте да направите екранна снимка отново"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Екранната снимка не може да се запази поради ограничено място в хранилището"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Правенето на екранни снимки не е разрешено от приложението или организацията ви"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Редактиране на екранната снимка"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Отхвърляне на екранната снимка"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Редактиране"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Редактиране на екранната снимка"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Превъртане"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Екранна снимка с превъртане"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Отхвърляне на екранната снимка"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Визуализация на екранната снимка"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запис на екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Записът на екрана се обработва"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Батерията е с две чертички."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Батерията е с три чертички."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Батерията е пълна."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Процентът на батерията е неизвестен."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Няма телефон."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Телефонът е с една чертичка."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Телефонът е с две чертички."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Известието е отхвърлено."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Балончето е отхвърлено."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Падащ панел с известия."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Бързи настройки."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Заключване на екрана."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Възможно е потребителският профил да се наблюдава"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Мрежата може да се наблюдава"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Мрежата може да се наблюдава"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Това устройство се управлява от родителя ви"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацията ви притежава това устройство и може да наблюдава трафика в мрежата"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> притежава това устройство и може да наблюдава трафика в мрежата"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Това устройство принадлежи на организацията ви и е свързано с(ъс) <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Деактивиране на VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Прекратяване на връзката с VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Преглед на правилата"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Преглед на контролите"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nСистемният ви администратор може да наблюдава и управлява настройките, корпоративния достъп, приложенията, свързаните с устройството данни и информацията за местоположението му.\n\nЗа повече информация се обърнете към него."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Това устройство принадлежи на организацията ви.\n\nСистемният ви администратор може да наблюдава и управлява настройките, корпоративния достъп, приложенията, свързаните с устройството данни и информацията за местоположението му.\n\nЗа повече информация се обърнете към него."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Организацията ви е инсталирала сертифициращ орган на това устройство. Трафикът в защитената ви мрежа може да бъде наблюдаван или променян."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Администраторът ви е включил функцията за регистриране на мрежовата активност, която следи трафика на устройството ви.\n\nЗа повече информация се свържете с администратора си."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Разрешихте на приложение да настрои връзка с виртуална частна мрежа (VPN).\n\nТова приложение може да наблюдава активността ви на устройството и в мрежата, включително имейли, приложения и уебсайтове."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Служебният ви потребителски профил се управлява от <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nАдминистраторът ви може да наблюдава активността ви в мрежата, включително имейли, приложения и уебсайтове.\n\nЗа повече информация се свържете с администратора си.\n\nСъщо така е установена връзка с виртуална частна мрежа (VPN) и активността ви в нея може да се наблюдава."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Това устройство се управлява от родителя ви. Той може да вижда и управлява информация, като например приложенията, които използвате, местоположението ви и времето на ползване."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Установена е връзка с приложението <xliff:g id="APPLICATION">%1$s</xliff:g>, което може да наблюдава активността ви в мрежата, включително имейли, приложения и уебсайтове."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Установена е връзка с приложението <xliff:g id="APPLICATION">%1$s</xliff:g>, което може да наблюдава личната ви активност в мрежата, включително имейли, приложения и уебсайтове."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Да продължат ли да се показват известията от това приложение?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Тих режим"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Стандартно"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Балонче"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звук или вибриране"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звук или вибриране и се показва по-долу в секцията с разговори"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Настройки"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддържа функциите за разговор"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Няма скорошни балончета"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Скорошните и отхвърлените балончета ще се показват тук"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Тези известия не могат да бъдат променяни."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Тази група от известия не може да бъде конфигурирана тук"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Известие, получено чрез делегиране"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Услуги за устройството"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Няма заглавие"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Докоснете, за да рестартирате това приложение в режим на цял екран."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Настройки за балончетата за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Препълване"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Добавяне обратно към стека"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Управление"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> от <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ от<xliff:g id="APP_NAME">%2$s</xliff:g> и още <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Преместване"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Преместване горе вляво"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Преместване горе вдясно"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Преместване долу вляво"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Преместване долу вдясно"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Отхвърляне на балончетата"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Без балончета за разговора"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Чат с балончета"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Новите разговори се показват като плаващи икони, или балончета. Докоснете балонче, за да го отворите, или го плъзнете, за да го преместите."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Управление на балончетата по всяко време"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Докоснете „Управление“, за да изключите балончетата от това приложение"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Разбрах"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Настройки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Сдвояване на ново устройство"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Възникна проблем при четенето на данните за нивото на батерията"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Докоснете за още информация"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml
index f322079..630e92d 100644
--- a/packages/SystemUI/res/values-bg/strings_tv.xml
+++ b/packages/SystemUI/res/values-bg/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Микрофонът е активен"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s осъществи достъп до микрофона ви"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index c4c6a0c..31a6e1e 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"আবার স্ক্রিনশট নেওয়ার চেষ্টা করুন"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"বেশি জায়গা নেই তাই স্ক্রিনশটটি সেভ করা যাবে না৷"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"এই অ্যাপ বা আপনার প্রতিষ্ঠান স্ক্রিনশট নেওয়ার অনুমতি দেয়নি"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"স্ক্রিনশট এডিট করুন"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"স্ক্রিনশট বাতিল করুন"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"স্ক্রিনশটের প্রিভিউ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্রিন রেকর্ডার"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"দুই দন্ড ব্যাটারি রয়েছে৷"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"তিন দন্ড ব্যাটারি রয়েছে৷"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ব্যাটারি পূর্ণ রয়েছে৷"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ব্যাটারি কত শতাংশ আছে তা জানা যায়নি।"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"কোনো ফোনের সংকেত নেই৷"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"এক দন্ড ফোনের সংকেত রয়েছে৷"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"দুই দন্ড ফোনের সংকেত রয়েছে৷"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"বিজ্ঞপ্তি খারিজ করা হয়েছে৷"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"বাবল বাতিল করা হয়েছে।"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"বিজ্ঞপ্তি শেড৷"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"দ্রুত সেটিংস৷"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"লক স্ক্রিন।"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"প্রোফাইল পর্যবেক্ষণ করা হতে পারে"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"নেটওয়ার্ক নিরীক্ষণ করা হতে পারে"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"নেটওয়ার্ক নিরীক্ষণ করা হতে পারে"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"আপনার অভিভাবক এই ডিভাইস ম্যানেজ করেন"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের এবং এরা ডিভাইসের নেটওয়ার্ক ট্রাফিক মনিটর করতে পারে"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> এই ডিভাইসের মালিক এবং এটির নেটওয়ার্ক ট্রাফিক মনিটর করতে পারে"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের এবং <xliff:g id="VPN_APP">%1$s</xliff:g>-এ কানেক্ট করা আছে"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN অক্ষম করুন"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN এর সংযোগ বিচ্ছিন্ন করুন"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"নীতিগুলি দেখুন"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"কন্ট্রোল দেখুন"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-এর।\n\nআপনার আইটি অ্যাডমিন এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ, ডিভাইসের সাথে সম্পর্কিত ডেটা এবং ডিভাইসের লোকেশন সম্পর্কিত ডেটা মনিটর ও ম্যানেজ করতে পারে।\n\nআরও তথ্যের জন্য আপনার আইটি অ্যাডমিনের সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের।\n\nআপনার আইটি অ্যাডমিন এই ডিভাইসের সেটিংস, কর্পোরেট অ্যাক্সেস, অ্যাপ, ডিভাইসের সাথে সম্পর্কিত ডেটা এবং ডিভাইসের লোকেশন সম্পর্কিত ডেটা মনিটর ও ম্যানেজ করতে পারে।\n\nআরও তথ্যের জন্য আপনার আইটি অ্যাডমিনের সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"আপনার প্রতিষ্ঠান আপনার অফিস প্রোফাইলে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করেছে।আপনার সুরক্ষিত নেটওয়ার্ক ট্রাফিক নিরীক্ষণ বা পরিবর্তন করা হতে পারে।"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"আপনার প্রশাসক নেটওয়ার্ক লগিং চালু করেছেন, যা আপনার ডিভাইসের ট্রাফিক নিরীক্ষণ করে।\n\nআরও তথ্যের জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"আপনি VPN সংযোগ সেট-আপ করার জন্য একটি অ্যাপ্লিকেশানকে অনুমতি দিন৷\n\nএই অ্যাপ্লিকেশানটি ইমেল, অ্যাপ্লিকেশান ও ওয়েবসাইটগুলি সহ আপনার ডিভাইস এবং নেটওয়ার্কের অ্যাক্টিভিটি নিরীক্ষণ করতে পারে।"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"আপনার কর্মস্থলের প্রোফাইলটি <xliff:g id="ORGANIZATION">%1$s</xliff:g> দ্বারা পরিচালিত হয়।\n\nআপনার প্রশাসক আপনার ইমেল, অ্যাপ্স ও ওয়েবসাইট সহ কর্মস্থলের নেটওয়ার্ক অ্যাক্টিভিটি নিরীক্ষণ করতে পারেন।\n\nআরও তথ্যের জন্য আপনার প্রশাসকের সঙ্গে যোগাযোগ করুন।\n\nএছাড়া আপনি একটি VPN এর সাথেও সংযুক্ত যা আপনার নেটওয়ার্ক অ্যাক্টিভিটি নিরীক্ষণ করতে পারে।"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"আপনার অভিভাবক এই ডিভাইস ম্যানেজ করেন। আপনার অভিভাবক আপনার ব্যবহার করা অ্যাপ, লোকেশন ও স্ক্রিন টাইমের মতো তথ্যগুলি দেখতে এবং ম্যানেজ করতে পারেন।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"আপনি <xliff:g id="APPLICATION">%1$s</xliff:g> এর সাথে সংযুক্ত রয়েছেন, যেটি ইমেল, অ্যাপ, এবং ওয়েবসাইট সহ আপনার নেটওয়ার্ক কার্যকলাপে নজর রাখতে পারে৷"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"আপনি <xliff:g id="APPLICATION">%1$s</xliff:g> -এ সংযুক্ত হয়েছেন, যা ইমেল, অ্যাপ্লিকেশান এবং ওয়েবসাইটগুলি সমেত আপনার ব্যক্তিগত নেটওয়ার্ক অ্যাক্টিভিটি নিরীক্ষণ করতে পারে৷"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"এই অ্যাপের বিজ্ঞপ্তি পরেও দেখে যেতে চান?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"সাইলেন্ট"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ডিফল্ট"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"বাবল"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"অটোমেটিক"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"আওয়াজ করবে না বা ভাইব্রেট হবে না"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"আওয়াজ করবে না বা ভাইব্রেট হবে না এবং কথোপকথন বিভাগের নিচের দিকে দেখা যাবে"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"সেটিংস"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"অগ্রাধিকার"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এ কথোপকথন ফিচার কাজ করে না"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"কোনও সাম্প্রতিক বাবল নেই"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"সাম্প্রতিক ও বাতিল করা বাবল এখানে দেখা যাবে"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"এই সমস্ত বিজ্ঞপ্তিকে এখানে কনফিগার করা যাবে না"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"প্রক্সি করা বিজ্ঞপ্তি"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"ডিভাইস সংক্রান্ত পরিষেবা"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"কোনও শীর্ষক নেই"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন ও ফুল-স্ক্রিন ব্যবহার করুন।"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> বাবলের জন্য সেটিংস"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ওভারফ্লো"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"স্ট্যাকে আবার যোগ করুন"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"ম্যানেজ করুন"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> অ্যাপ থেকে <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> অ্যাপ এবং আরও <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>টি থেকে <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"সরান"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"উপরে বাঁদিকে সরান"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"উপরে ডানদিকে সরান"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"নিচে বাঁদিকে সরান"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"নিচে ডান দিকে সরান"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"বাবল খারিজ করুন"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"কথোপকথন বাবল হিসেবে দেখাবে না"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"বাবল ব্যবহার করে চ্যাট করুন"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"নতুন কথোপকথন ভেসে থাকা আইকন বা বাবল হিসেবে দেখানো হয়। বাবল খুলতে ট্যাপ করুন। সেটি সরাতে ধরে টেনে আনুন।"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"যেকোনও সময় বাবল নিয়ন্ত্রণ করুন"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"এই অ্যাপ থেকে বাবল বন্ধ করতে \'ম্যানেজ করুন\' বিকল্প ট্যাপ করুন"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"বুঝেছি"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> সেটিংস"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"স্ট্যান্ডবাই"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইস পেয়ার করুন"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ব্যাটারির মিটারের রিডিং নেওয়ার সময় সমস্যা হয়েছে"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings_tv.xml b/packages/SystemUI/res/values-bn/strings_tv.xml
index 56ca023..f9da81a 100644
--- a/packages/SystemUI/res/values-bn/strings_tv.xml
+++ b/packages/SystemUI/res/values-bn/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"মাইক্রোফোন চালু আছে"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s আপনার ডিভাইসের মাইক্রোফোন অ্যাক্সেস করেছে"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 75a2d1c..1179a92 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pokušajte ponovo snimiti ekran"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Snimak ekrana se ne može sačuvati zbog manjka prostora za pohranu"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ova aplikacija ili vaša organizacija ne dozvoljavaju snimanje ekrana"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Uredite snimak ekrana"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Odbacite snimak ekrana"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Uredi"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Uredite snimak ekrana"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Klizni"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Pokretni snimak ekrana"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacite snimak ekrana"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimka ekrana"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađivanje snimka ekrana"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Baterija na dvije crtice."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Baterija na tri crtice."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Baterija je puna."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Postotak napunjenosti baterije nije poznat"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nema telefonskog signala."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefonski signal na jednoj crtici."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefonski signal na dvije crtice."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Obavještenje je uklonjeno."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Oblačić je odbačen."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Obavještenja sa sjenčenjem."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brze postavke."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključan ekran."</string>
@@ -523,6 +526,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil može biti nadziran"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Mreža može biti nadzirana"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Mreža može biti nadzirana"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je vlasnik ovog uređaja i može nadzirati mrežni saobraćaj"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može nadzirati mrežni saobraćaj"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada vašoj organizaciji i povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -547,6 +551,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Isključi VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Prekini VPN vezu"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravila"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Prikaži kontrole"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš IT administrator može nadzirati postavke, korporativni pristup, aplikacije, podatke povezane s vašim uređajem i informacije o lokaciji uređaja te njima upravljati.\n\nZa više informacija kontaktirajte IT administratora."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada vašoj organizaciji.\n\nVaš IT administrator može nadzirati postavke, korporativni pristup, aplikacije, podatke povezane s vašim uređajem i informacije o lokaciji uređaja te njima upravljati.\n\nZa više informacija kontaktirajte IT administratora."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša organizacija je instalirala CA certifikat na ovom uređaju. Vaš saobraćaj preko sigurne mreže može se pratiti."</string>
@@ -570,6 +575,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Vaš administrator je uključio zapisivanje na mreži, čime se prati saobraćaj na vašem uređaju.\n\nZa više informacija, obratite se administratoru."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Jednoj aplikaciji ste dali odobrenje da uspostavi VPN vezu.\n\nTa aplikacija može pratiti vašu aktivnost na uređaju i mreži, uključujući e-poštu, aplikacije i web-lokacije."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Vašim radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVaš administrator može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nZa više informacija, obratite se administratoru.\n\nPovezani ste i na VPN, koji može pratiti vašu aktivnost na mreži."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja tvoj roditelj. Roditelj može vidjeti i upravljati informacijama kao što su aplikacije koje koristiš, lokacija i vrijeme korištenja uređaja."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Povezani ste s aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke, aplikacije i web lokacije."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži, uključujući e-mailove, aplikacije i web-lokacije."</string>
@@ -712,7 +718,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Nastaviti prikazivanje obavještenja iz ove aplikacije?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Zadano"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Oblačić"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka ili vibracije"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka ili vibracije i pojavljuje se pri dnu odjeljka za razgovor"</string>
@@ -724,8 +729,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Postavke"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetni"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije razgovora"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nema nedavnih oblačića"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Nedavni i odbačeni oblačići će se pojaviti ovdje"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ta obavještenja se ne mogu izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ovu grupu obavještenja nije moguće konfigurirati ovdje"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Obavještenje preko proksi servera"</string>
@@ -986,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Usluge uređaja"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Dodirnite da ponovo pokrenete ovu aplikaciju i aktivirate prikaz preko cijelog ekrana."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Postavke za oblačiće aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Preklapanje"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodaj nazad u grupu"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Upravljaj"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> od aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"Obavještenje <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g> i još <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Pomjeri"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Pomjeri gore lijevo"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Pomjerite gore desno"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Pomjeri dolje lijevo"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Pomjerite dolje desno"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Odbaci oblačić"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nemoj prikazivati razgovor u oblačićima"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatajte koristeći oblačiće"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Novi razgovori se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da otvorite oblačić. Prevucite da ga premjestite."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljajte oblačićima u svakom trenutku"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljaj da isključite oblačiće iz ove aplikacije"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumijem"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke aplikacije <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Postavke da ažurirate navigiranje sistemom"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string>
@@ -1095,4 +1080,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Došlo je do problema prilikom očitavanja mjerača stanja baterije"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings_tv.xml b/packages/SystemUI/res/values-bs/strings_tv.xml
index acd93d6..55e9fbf 100644
--- a/packages/SystemUI/res/values-bs/strings_tv.xml
+++ b/packages/SystemUI/res/values-bs/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon je aktivan"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacija %1$s je pristupila vašem mikrofonu"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 2b6dfd5..fed1839 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prova de tornar a fer una captura de pantalla"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"La captura de pantalla no es pot desar perquè no hi ha prou espai d\'emmagatzematge"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'aplicació o la teva organització no permeten fer captures de pantalla"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edita la captura de pantalla"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ignora la captura de pantalla"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Previsualització de la captura de pantalla"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravació de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Bateria: dues barres."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Bateria: tres barres."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Bateria carregada."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Es desconeix el percentatge de bateria."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"No hi ha senyal de telèfon."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Senyal de telèfon: una barra"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Senyal de telèfon: dues barres."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notificació omesa."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"La bombolla s\'ha ignorat."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Àrea de notificacions"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configuració ràpida"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantalla de bloqueig"</string>
@@ -446,7 +454,7 @@
     <string name="zen_priority_introduction" msgid="3159291973383796646">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
     <string name="zen_alarms_introduction" msgid="3987266042682300470">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalitza"</string>
-    <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música. Encara podràs fer trucades."</string>
+    <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música. Encara podràs fer trucades telefòniques."</string>
     <string name="zen_silence_introduction" msgid="6117517737057344014">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música."</string>
     <string name="keyguard_more_overflow_text" msgid="5819512373606638727">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="7248696377626341060">"Notificacions menys urgents a continuació"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"El perfil es pot supervisar"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"És possible que la xarxa estigui supervisada."</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"És possible que la xarxa estigui supervisada"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"El teu pare o la teva mare gestionen aquest dispositiu"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"La teva organització és propietària del dispositiu i és possible que supervisi el trànsit de xarxa"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> és propietària d\'aquest dispositiu i és possible que supervisi el trànsit de xarxa"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Aquest dispositiu pertany a la teva organització i està connectat a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Desactiva la VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Desconnecta la VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Consulta les polítiques"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Mostra els controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"El dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nL\'administrador de TI pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu i la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador de TI."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"El dispositiu pertany a la teva organització.\n\nL\'administrador de TI pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu i la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"La teva organització ha instal·lat una autoritat de certificació en aquest dispositiu. És possible que el trànsit a la xarxa segura se supervisi o es modifiqui."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"L\'administrador ha activat el registre de xarxa, que supervisa el trànsit del teu dispositiu.\n\nPer obtenir més informació, contacta amb l\'administrador."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Has donat permís a una aplicació per configurar una connexió VPN.\n\nAquesta aplicació pot supervisar el dispositiu i l\'activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona el teu perfil de treball.\n\nL\'administrador pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web.\n\nPer obtenir més informació, contacta amb l\'administrador.\n\nA més, estàs connectat a una VPN, que també pot supervisar la teva activitat a la xarxa."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"El teu pare o la teva mare gestionen aquest dispositiu, i poden veure i gestionar informació com ara les aplicacions que utilitzes, la teva ubicació i el teu temps de connexió."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Estàs connectat a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Estàs connectat a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pot supervisar la teva activitat personal a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silenci"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminat"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bombolla"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automàtic"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sense so ni vibració"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sense so ni vibració i es mostra més avall a la secció de converses"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configuració"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritat"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admet les funcions de converses"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"No hi ha bombolles recents"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Les bombolles recents i les ignorades es mostraran aquí"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Aquestes notificacions no es poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquest grup de notificacions no es pot configurar aquí"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificació mitjançant aplicació intermediària"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Serveis per a dispositius"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sense títol"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toca per reiniciar l\'aplicació i passar a pantalla completa."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Configuració de les bombolles: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menú addicional"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Torna a afegir a la pila"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gestiona"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de: <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>) i <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> més"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mou"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Mou a dalt a l\'esquerra"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Mou a dalt a la dreta"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Mou a baix a l\'esquerra"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Mou a baix a la dreta"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Ignora la bombolla"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"No mostris la conversa com a bombolla"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Xateja amb bombolles"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Les converses noves es mostren com a icones flotants o bombolles. Toca per obrir una bombolla. Arrossega-la per moure-la."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla les bombolles en qualsevol moment"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestiona per desactivar les bombolles d\'aquesta aplicació"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entesos"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuració de l\'aplicació <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"S\'ha actualitzat el sistema de navegació. Per fer canvis, ves a Configuració."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ves a Configuració per actualitzar el sistema de navegació"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincula un dispositiu nou"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Hi ha hagut un problema en llegir el mesurador de la bateria"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca per obtenir més informació"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml
index c41d571..a93e294 100644
--- a/packages/SystemUI/res/values-ca/strings_tv.xml
+++ b/packages/SystemUI/res/values-ca/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Micròfon actiu"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ha accedit al teu micròfon"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index f00c279..d91fae9 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Zkuste snímek pořídit znovu"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Snímek obrazovky kvůli nedostatku místa v úložišti nelze uložit"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikace nebo organizace zakazuje pořizování snímků obrazovky"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Upravit snímek obrazovky"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Zavřít snímek obrazovky"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Náhled snímku obrazovky"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Záznam obrazovky se zpracovává"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Dvě čárky baterie."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Tři čárky baterie."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Baterie je nabitá."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procento baterie není známé."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Žádná telefonní síť."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Jedna čárka signálu telefonní sítě."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Dvě čárky signálu telefonní sítě."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Oznámení je zavřeno."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bublina byla zavřena."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Panel oznámení."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Rychlé nastavení."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Obrazovka uzamčení"</string>
@@ -526,6 +534,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil může být monitorován"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Síť může být sledována"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Síť může být monitorována"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zařízení spravuje rodič"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Toto zařízení vlastní vaše organizace, která může sledovat síťový provoz"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, která může sledovat síťový provoz"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Toto zařízení patří vaší organizaci a je připojené k síti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -550,6 +559,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Deaktivovat VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Odpojit VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobrazit zásady"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Zobrazit ovládací prvky"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVáš administrátor IT může sledovat a spravovat nastavení, firemní přístup, aplikace, data přidružená k tomuto zařízení a jeho polohu.\n\nDalší informace vám poskytne váš administrátor IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Toto zařízení patří vaší organizaci\n\nVáš administrátor IT může sledovat a spravovat nastavení, firemní přístup, aplikace, data přidružená k tomuto zařízení a jeho polohu.\n\nDalší informace vám poskytne váš administrátor IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizace do tohoto zařízení nainstalovala certifikační autoritu. Zabezpečený síťový provoz může být sledován nebo upravován."</string>
@@ -573,6 +583,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administrátor zapnul protokolování sítě, které monitoruje síťový provoz v zařízení.\n\nDalší informace vám poskytne administrátor."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Udělili jste aplikaci oprávnění k nastavení připojení VPN.\n\nTato aplikace může sledovat vaši aktivitu v zařízení a v síti, včetně e-mailů, aplikací a webů."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Váš pracovní profil spravuje organizace <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrátor může monitorovat vaši síťovou aktivitu, včetně e-mailů, aplikací a webů.\n\nDalší informace vám poskytne administrátor.\n\nJste také připojeni k síti VPN, která může sledovat vaši aktivitu v síti."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Toto zařízení spravuje rodič. Rodič může zobrazit údaje, jako jsou používané aplikace, tvá poloha a čas strávený na zařízení."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Jste připojeni k aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g>, která může sledovat vaši aktivitu v síti, včetně e-mailů, aplikací a webů."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Jste připojeni k aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g>, která může sledovat vaši osobní aktivitu v síti, včetně e-mailů, aplikací a webů."</string>
@@ -715,7 +726,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Mají se oznámení z této aplikace nadále zobrazovat?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Ticho"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Výchozí"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bublina"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automaticky"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Žádný zvuk ani vibrace"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Žádný zvuk ani vibrace a zobrazovat níže v sekci konverzací"</string>
@@ -727,8 +737,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Nastavení"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorita"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> funkce konverzace nepodporuje"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Žádné nedávné bubliny"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Zde se budou zobrazovat nedávné bubliny a zavřené bubliny"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tato oznámení nelze upravit."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Tuto skupinu oznámení tady nelze nakonfigurovat"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Zprostředkované oznámení"</string>
@@ -991,25 +999,7 @@
     <string name="device_services" msgid="1549944177856658705">"Služby zařízení"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Klepnutím aplikaci restartujete a přejdete na režim celé obrazovky"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Nastavení bublin aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Rozbalovací nabídka"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Přidat zpět do sady"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Spravovat"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"Oznámení <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikace <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> a dalších (<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>)"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Přesunout"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Přesunout vlevo nahoru"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Přesunout vpravo nahoru"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Přesunout vlevo dolů"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Přesunout vpravo dolů"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Zavřít bublinu"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nezobrazovat konverzaci v bublinách"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatujte pomocí bublin"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nové konverzace se zobrazují jako plovoucí ikony, neboli bubliny. Klepnutím bublinu otevřete. Přetažením ji posunete."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Nastavení bublin můžete kdykoli upravit"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bubliny pro tuto aplikaci můžete vypnout klepnutím na Spravovat"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Rozumím"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavení <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systémová navigace byla aktualizována. Chcete-li provést změny, přejděte do Nastavení."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Přejděte do Nastavení a aktualizujte systémovou navigaci"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostní režim"</string>
@@ -1101,4 +1091,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovat nové zařízení"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problém s načtením měřiče baterie"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím zobrazíte další informace"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml
index 2d95d46..d916e61 100644
--- a/packages/SystemUI/res/values-cs/strings_tv.xml
+++ b/packages/SystemUI/res/values-cs/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon je aktivní"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikace %1$s použila mikrofon"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 9d365c3..d20fc0c 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv at tage et screenshot igen"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Screenshottet kan ikke gemmes, fordi der er begrænset lagerplads"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller din organisation tillader ikke, at du tager screenshots"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Rediger dit screenshot"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Luk screenshot"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger screenshot"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Rul"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Rul screenshot"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Luk screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning af screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skærmoptagelse"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skærmoptagelse"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Batteri to bjælker."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Batteri tre bjælker."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batteri fuldt."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriniveauet er ukendt."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Ingen telefon."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon en bjælke."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon to bjælker."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notifikationen er annulleret."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Boblen blev lukket."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notifikationspanel."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Kvikmenu."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Låseskærm."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profilen kan overvåges"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Netværket kan være overvåget"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Netværket kan være overvåget"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enhed administreres af din forælder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Din organisation ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Denne enhed tilhører din organisation og har forbindelse til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Deaktiver VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Afbryd VPN-forbindelse"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Se politikker"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Se styringselementer"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nDin it-administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er tilknyttet din enhed, og din enheds placeringsdata.\n\nKontakt din it-administrator for at få mere at vide."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Denne enhed tilhører din organisation.\n\nDin it-administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er tilknyttet din enhed, og din enheds placeringsdata.\n\nKontakt din it-administrator for at få mere at vide."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Din organisation har installeret et nøglecenter på denne enhed. Din sikre netværkstrafik kan overvåges eller ændres."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Din administrator har aktiveret netværksregistrering, som overvåger trafik på din enhed.\n\nKontakt din administrator for at få flere oplysninger."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Du gav en app tilladelse til at konfigurere en VPN-forbindelse.\n\nDenne app kan overvåge din enhed og netværksaktivitet, bl.a. e-mails, apps og websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Din arbejdsprofil administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nDin administrator kan overvåge din netværksaktivitet, bl.a. e-mails, apps og websites.\n\nKontakt din administrator for at få flere oplysninger.\n\nDu har også forbindelse til et VPN, som kan overvåge din netværksaktivitet."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Denne enhed administreres af din forælder. Din forælder kan se og administrere oplysninger såsom de apps, du bruger, din placering og din skærmtid."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Du har forbindelse til <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan overvåge din netværksaktivitet, bl.a. mails, apps og websites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Du har forbindelse til <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan overvåge din private netværksaktivitet, bl.a. e-mails, apps og websites."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Vil du fortsætte med at se notifikationer fra denne app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Lydløs"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Boble"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ingen lyd eller vibration"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ingen lyd eller vibration, og den vises længere nede i samtalesektionen"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Indstillinger"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> understøtter ikke samtalefunktioner"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Ingen seneste bobler"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Nye bobler og afviste bobler vises her"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse notifikationer kan ikke redigeres."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Du kan ikke konfigurere denne gruppe notifikationer her"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxyforbundet notifikation"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Enhedstjenester"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tryk for at genstarte denne app, og gå til fuld skærm."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Indstillinger for <xliff:g id="APP_NAME">%1$s</xliff:g>-bobler"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overløb"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Føj til stak igen"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Administrer"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> fra <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> fra <xliff:g id="APP_NAME">%2$s</xliff:g> og <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> andre"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Flyt"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Flyt op til venstre"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Flyt op til højre"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Flyt ned til venstre"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Flyt ned til højre"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Afvis boble"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Vis ikke samtaler i bobler"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat ved hjælp af bobler"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nye samtaler vises som svævende ikoner eller bobler. Tryk for at åbne boblen. Træk for at flytte den."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Styr bobler når som helst"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tryk på Administrer for at deaktivere bobler fra denne app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Indstillinger for <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Indstillinger for at opdatere systemnavigationen"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Par ny enhed"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Der er problemer med at aflæse dit batteriniveau"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryk for at få flere oplysninger"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml
index f70427d..2072f1e 100644
--- a/packages/SystemUI/res/values-da/strings_tv.xml
+++ b/packages/SystemUI/res/values-da/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofonen er slået til"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s fik adgang til din mikrofon"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 55e7d17..21c371e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Versuche noch einmal, den Screenshot zu erstellen"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Speichern des Screenshots aufgrund von zu wenig Speicher nicht möglich"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Die App oder deine Organisation lässt das Erstellen von Screenshots nicht zu"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Screenshot bearbeiten"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Screenshot schließen"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshotvorschau"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Bildschirmaufzeichnung"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Akku - zwei Balken"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Akku - drei Balken"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Akku voll"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akkustand unbekannt."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Kein Telefon"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefonsignal - ein Balken"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefonsignal - zwei Balken"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Benachrichtigung geschlossen"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bubble verworfen."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Benachrichtigungsleiste"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Schnelleinstellungen"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Sperrbildschirm"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil wird eventuell überwacht."</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Das Netzwerk wird eventuell überwacht."</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Das Netzwerk wird eventuell überwacht"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dieses Gerät wird von deinen Eltern verwaltet"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Deine Organisation verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ist der Eigentümer dieses Geräts und kann den Netzwerkverkehr überwachen"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Dieses Gerät gehört deiner Organisation und ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN deaktivieren"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN-Verbindung trennen"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Richtlinien ansehen"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Jugendschutzeinstellungen"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Dieses Gerät gehört <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nDein IT-Administrator kann Einstellungen, Zugriffsrechte im Unternehmen, Apps, mit diesem Gerät verknüpfte Daten und die Standortdaten deines Geräts sehen und verwalten.\n\nWeitere Informationen erhältst du von deinem IT-Administrator."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Dieses Gerät gehört deiner Organisation.\n\nDein IT-Administrator kann Einstellungen, Zugriffsrechte im Unternehmen, Apps, mit diesem Gerät verknüpfte Daten und die Standortdaten deines Geräts sehen und verwalten.\n\nWeitere Informationen erhältst du von deinem IT-Administrator."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Deine Organisation hat ein Zertifikat einer Zertifizierungsstelle auf deinem Gerät installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Dein Administrator hat die Netzwerkprotokollierung aktiviert. Damit wird der Verkehr auf deinem Gerät erfasst.\n\nWeitere Informationen erhältst du von deinem Administrator."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Du hast einer App gestattet, eine VPN-Verbindung einzurichten.\n\nDiese App kann dein Gerät und deine Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nDein Administrator kann deine Netzwerkaktivitäten einschließlich E-Mails, Apps und Websites überwachen.\n\nWeitere Informationen erhältst du von deinem Administrator.\n\nAußerdem bist du mit einem VPN verbunden, das deine Netzwerkaktivitäten erfassen kann."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Dieses Gerät wird von deinen Eltern verwaltet. Sie können unter anderem Informationen über deine genutzten Apps, deinen Standort und deine Gerätenutzungsdauer einsehen und verwalten."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Du bist mit <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die deine Netzwerkaktivitäten überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Du bist mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die deine persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Benachrichtigungen dieser App weiterhin anzeigen?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Lautlos"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bubble"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Kein Ton und keine Vibration"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Kein Ton und keine Vibration, erscheint weiter unten im Bereich \"Unterhaltungen\""</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Einstellungen"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorität"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> unterstützt keine Funktionen für Unterhaltungen"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Keine kürzlich geschlossenen Bubbles"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Hier werden aktuelle und geschlossene Bubbles angezeigt"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Diese Benachrichtigungen können nicht geändert werden."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Die Benachrichtigungsgruppe kann hier nicht konfiguriert werden"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Weitergeleitete Benachrichtigung"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Gerätedienste"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Kein Titel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tippe, um die App im Vollbildmodus neu zu starten."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Einstellungen für <xliff:g id="APP_NAME">%1$s</xliff:g>-Bubbles"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Mehr anzeigen"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Wieder dem Stapel hinzufügen"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Verwalten"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> von <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> aus <xliff:g id="APP_NAME">%2$s</xliff:g> und <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> weiteren"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Verschieben"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Nach oben links verschieben"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Nach rechts oben verschieben"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Nach unten links verschieben"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Nach unten rechts verschieben"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Bubble schließen"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Unterhaltung nicht als Bubble anzeigen"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Bubbles zum Chatten verwenden"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Neue Unterhaltungen erscheinen als unverankerte Symbole, \"Bubbles\" genannt. Wenn du die Bubble öffnen möchtest, tippe sie an. Wenn du sie verschieben möchtest, zieh an ihr."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bubble-Einstellungen festlegen"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tippe auf \"Verwalten\", um Bubbles für diese App zu deaktivieren"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Einstellungen für <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemsteuerungseinstellungen wurden angepasst. Änderungen kannst du in den Einstellungen vornehmen."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gehe zu den Einstellungen, um die Systemsteuerung anzupassen"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Neues Gerät koppeln"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem beim Lesen des Akkustands"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Für weitere Informationen tippen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml
index b947b2c..8756749 100644
--- a/packages/SystemUI/res/values-de/strings_tv.xml
+++ b/packages/SystemUI/res/values-de/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon aktiv"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s hat auf dein Mikrofon zugegriffen"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 3bb15ff..d0ff804 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Δοκιμάστε να κάνετε ξανά λήψη του στιγμιότυπου οθόνης"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Αδύνατη η αποθήκευση του στιγμιότυπου οθόνης λόγω περιορισμένου αποθηκευτικού χώρου"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Η λήψη στιγμιότυπων οθόνης δεν επιτρέπεται από την εφαρμογή ή τον οργανισμό σας"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Επεξεργασία στιγμιότυπου οθόνης"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Παράβλεψη στιγμιότυπου οθόνης"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Προεπισκόπηση στιγμιότυπου οθόνης"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Εγγραφή οθόνης"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Επεξεργασία εγγραφής οθόνης"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Δύο γραμμές μπαταρίας."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Τρεις γραμμές μπαταρίας."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Πλήρης μπαταρία."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Άγνωστο ποσοστό μπαταρίας."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Δεν υπάρχει τηλέφωνο."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Μία γραμμή τηλεφώνου."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Δύο γραμμές τηλεφώνου."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Η ειδοποίηση έχει απορριφθεί."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Το συννεφάκι παραβλέφθηκε."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Πλαίσιο σκίασης ειδοποιήσεων."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Γρήγορες ρυθμίσεις."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Οθόνη κλειδώματος"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Το προφίλ ενδέχεται να παρακολουθείται"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Αυτή η συσκευή είναι διαχειριζόμενη από τον γονέα σου"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ο οργανισμός σας κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Αυτή η συσκευή ανήκει στον οργανισμό σας και είναι συνδεδεμένη στην εφαρμογή <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Απενεργοποίηση VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Αποσύνδεση VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Προβολή πολιτικών"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Προβολή στοιχείων ελέγχου"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nΟ διαχειριστής IT μπορεί να παρακολουθεί και να διαχειρίζεται τις ρυθμίσεις, την εταιρική πρόσβαση, τις εφαρμογές, τα δεδομένα που σχετίζονται με τη συσκευή καθώς και τις πληροφορίες τοποθεσίας της συσκευής σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Αυτή η συσκευή ανήκει στον οργανισμό σας.\n\nΟ διαχειριστής IT μπορεί να παρακολουθεί και να διαχειρίζεται τις ρυθμίσεις, την εταιρική πρόσβαση, τις εφαρμογές, τα δεδομένα που σχετίζονται με τη συσκευή καθώς και τις πληροφορίες τοποθεσίας της συσκευής σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ο οργανισμός σας εγκατέστησε μια αρχή έκδοσης πιστοποιητικών σε αυτήν τη συσκευή. Η ασφαλής επισκεψιμότητα δικτύου σας μπορεί να παρακολουθείται ή να τροποποιείται."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Ο διαχειριστής σας έχει ενεργοποιήσει την καταγραφή δικτύου, η οποία παρακολουθεί την επισκεψιμότητα στη συσκευή σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Αυτή η συσκευή είναι διαχειριζόμενη από τον γονέα σου. Ο γονέας σου μπορεί να βλέπει και να διαχειρίζεται πληροφορίες όπως οι εφαρμογές που χρησιμοποιείς, η τοποθεσία σου και ο χρόνος χρήσης."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Να συνεχίσουν να εμφανίζονται ειδοποιήσεις από αυτήν την εφαρμογή;"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Σίγαση"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Προεπιλογή"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Συννεφάκι"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Αυτόματο"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Χωρίς ήχο ή δόνηση"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Χωρίς ήχο ή δόνηση και εμφανίζεται χαμηλά στην ενότητα συζητήσεων"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ρυθμίσεις"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Προτεραιότητα"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν υποστηρίζει τις λειτουργίες συζήτησης"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Δεν υπάρχουν πρόσφατα συννεφάκια"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Τα πρόσφατα συννεφάκια και τα συννεφάκια που παραβλέψατε θα εμφανίζονται εδώ."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Δεν είναι δυνατή η τροποποίηση αυτών των ειδοποιήσεων"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Δεν είναι δυνατή η διαμόρφωση αυτής της ομάδας ειδοποιήσεων εδώ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Ειδοποίηση μέσω διακομιστή μεσολάβησης"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Υπηρεσίες συσκευής"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Χωρίς τίτλο"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Πατήστε για επανεκκίνηση αυτής της εφαρμογής και ενεργοποίηση πλήρους οθόνης."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Ρυθμίσεις για συννεφάκια <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Υπερχείλιση"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Προσθήκη ξανά στη στοίβα"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Διαχείριση"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> από <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> από την εφαρμογή <xliff:g id="APP_NAME">%2$s</xliff:g> και <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ακόμη"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Μετακίνηση"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Μετακίνηση επάνω αριστερά"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Μετακίνηση επάνω δεξιά"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Μετακίνηση κάτω αριστερά"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Μετακίνηση κάτω δεξιά"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Παράβλ. για συννεφ."</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Να μην γίνει προβολή της συζήτησης σε συννεφάκια."</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Συζητήστε χρησιμοποιώντας συννεφάκια."</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Οι νέες συζητήσεις εμφανίζονται ως κινούμενα εικονίδια ή συννεφάκια. Πατήστε για να ανοίξετε το συννεφάκι. Σύρετε για να το μετακινήσετε."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ελέγξτε τα συννεφάκια ανά πάσα στιγμή."</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Πατήστε Διαχείριση για να απενεργοποιήσετε τα συννεφάκια από αυτήν την εφαρμογή."</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Το κατάλαβα."</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Ρυθμίσεις <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Κατάσταση αναμονής"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Σύζευξη νέας συσκευής"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Υπάρχει κάποιο πρόβλημα με την ανάγνωση του μετρητή μπαταρίας"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Πατήστε για περισσότερες πληροφορίες."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml
index d039613..8a7eea4 100644
--- a/packages/SystemUI/res/values-el/strings_tv.xml
+++ b/packages/SystemUI/res/values-el/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Ενεργό μικρόφωνο"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Πραγματοποιήθηκε πρόσβαση στο μικρόφωνό σας από το %1$s"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index a743bbe..85d6276 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Can\'t save screenshot due to limited storage space"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edit screenshot"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Dismiss screenshot"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Scroll"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Scroll screenshot"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Battery two bars."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Battery three bars."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Battery full."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"No phone."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Phone one bar."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Phone two bars."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notification dismissed."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bubble dismissed."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Quick settings."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profile may be monitored"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Network may be monitored"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Network may be monitored"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Disable VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Disconnect VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Your admin has turned on network logging, which monitors traffic on your device.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nYour admin is capable of monitoring your network activity including emails, apps and websites.\n\nFor more information, contact your admin.\n\nYou\'re also connected to a VPN, which can monitor your network activity."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Keep showing notifications from this app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bubble"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"No sound or vibration"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No sound or vibration and appears lower in conversation section"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Settings"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"No recent bubbles"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Recent bubbles and dismissed bubbles will appear here"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxied notification"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Device Services"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Settings for <xliff:g id="APP_NAME">%1$s</xliff:g> bubbles"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overflow"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Add back to stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Manage"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> from <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> from <xliff:g id="APP_NAME">%2$s</xliff:g> and <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> more"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Move top left"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Move top right"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Move bottom left"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Move bottom right"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Dismiss bubble"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Don’t bubble conversation"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat using bubbles"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles at any time"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings_tv.xml b/packages/SystemUI/res/values-en-rAU/strings_tv.xml
index f81611f..b3dd86a 100644
--- a/packages/SystemUI/res/values-en-rAU/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microphone active"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 3fe7a6a..5db104c 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Can\'t save screenshot due to limited storage space"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edit screenshot"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Dismiss screenshot"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Scroll"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Scroll screenshot"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Battery two bars."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Battery three bars."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Battery full."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"No phone."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Phone one bar."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Phone two bars."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notification dismissed."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bubble dismissed."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Quick settings."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profile may be monitored"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Network may be monitored"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Network may be monitored"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Disable VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Disconnect VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Your admin has turned on network logging, which monitors traffic on your device.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nYour admin is capable of monitoring your network activity including emails, apps and websites.\n\nFor more information, contact your admin.\n\nYou\'re also connected to a VPN, which can monitor your network activity."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Keep showing notifications from this app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bubble"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"No sound or vibration"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No sound or vibration and appears lower in conversation section"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Settings"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"No recent bubbles"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Recent bubbles and dismissed bubbles will appear here"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxied notification"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Device Services"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Settings for <xliff:g id="APP_NAME">%1$s</xliff:g> bubbles"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overflow"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Add back to stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Manage"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> from <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> from <xliff:g id="APP_NAME">%2$s</xliff:g> and <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> more"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Move top left"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Move top right"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Move bottom left"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Move bottom right"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Dismiss bubble"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Don’t bubble conversation"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat using bubbles"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles at any time"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings_tv.xml b/packages/SystemUI/res/values-en-rCA/strings_tv.xml
index f81611f..b3dd86a 100644
--- a/packages/SystemUI/res/values-en-rCA/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microphone active"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index a743bbe..85d6276 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Can\'t save screenshot due to limited storage space"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edit screenshot"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Dismiss screenshot"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Scroll"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Scroll screenshot"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Battery two bars."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Battery three bars."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Battery full."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"No phone."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Phone one bar."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Phone two bars."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notification dismissed."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bubble dismissed."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Quick settings."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profile may be monitored"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Network may be monitored"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Network may be monitored"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Disable VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Disconnect VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Your admin has turned on network logging, which monitors traffic on your device.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nYour admin is capable of monitoring your network activity including emails, apps and websites.\n\nFor more information, contact your admin.\n\nYou\'re also connected to a VPN, which can monitor your network activity."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Keep showing notifications from this app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bubble"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"No sound or vibration"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No sound or vibration and appears lower in conversation section"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Settings"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"No recent bubbles"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Recent bubbles and dismissed bubbles will appear here"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxied notification"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Device Services"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Settings for <xliff:g id="APP_NAME">%1$s</xliff:g> bubbles"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overflow"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Add back to stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Manage"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> from <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> from <xliff:g id="APP_NAME">%2$s</xliff:g> and <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> more"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Move top left"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Move top right"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Move bottom left"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Move bottom right"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Dismiss bubble"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Don’t bubble conversation"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat using bubbles"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles at any time"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings_tv.xml b/packages/SystemUI/res/values-en-rGB/strings_tv.xml
index f81611f..b3dd86a 100644
--- a/packages/SystemUI/res/values-en-rGB/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microphone active"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index a743bbe..85d6276 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Can\'t save screenshot due to limited storage space"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edit screenshot"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Dismiss screenshot"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Scroll"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Scroll screenshot"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshot preview"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Battery two bars."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Battery three bars."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Battery full."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"No phone."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Phone one bar."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Phone two bars."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notification dismissed."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bubble dismissed."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Quick settings."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profile may be monitored"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Network may be monitored"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Network may be monitored"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"This device belongs to your organisation and is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Disable VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Disconnect VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"View Policies"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"View controls"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"This device belongs to your organisation.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Your organisation installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Your admin has turned on network logging, which monitors traffic on your device.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nYour admin is capable of monitoring your network activity including emails, apps and websites.\n\nFor more information, contact your admin.\n\nYou\'re also connected to a VPN, which can monitor your network activity."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Keep showing notifications from this app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bubble"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"No sound or vibration"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No sound or vibration and appears lower in conversation section"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Settings"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"No recent bubbles"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Recent bubbles and dismissed bubbles will appear here"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxied notification"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Device Services"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tap to restart this app and go full screen."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Settings for <xliff:g id="APP_NAME">%1$s</xliff:g> bubbles"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overflow"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Add back to stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Manage"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> from <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> from <xliff:g id="APP_NAME">%2$s</xliff:g> and <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> more"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Move"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Move top left"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Move top right"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Move bottom left"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Move bottom right"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Dismiss bubble"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Don’t bubble conversation"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat using bubbles"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles at any time"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings_tv.xml b/packages/SystemUI/res/values-en-rIN/strings_tv.xml
index f81611f..b3dd86a 100644
--- a/packages/SystemUI/res/values-en-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microphone active"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accessed your microphone"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 78006fd..3719aa7 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎Try taking screenshot again‎‏‎‎‏‎"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎Can\'t save screenshot due to limited storage space‎‏‎‎‏‎"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎Taking screenshots isn\'t allowed by the app or your organization‎‏‎‎‏‎"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎Edit screenshot‎‏‎‎‏‎"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎Dismiss screenshot‎‏‎‎‏‎"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎Edit‎‏‎‎‏‎"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎Edit screenshot‎‏‎‎‏‎"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎Scroll‎‏‎‎‏‎"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎Scroll screenshot‎‏‎‎‏‎"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎Dismiss screenshot‎‏‎‎‏‎"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎Screenshot preview‎‏‎‎‏‎"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎Screen Recorder‎‏‎‎‏‎"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎Processing screen recording‎‏‎‎‏‎"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‎Battery two bars.‎‏‎‎‏‎"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‏‎Battery three bars.‎‏‎‎‏‎"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‏‎‎Battery full.‎‏‎‎‏‎"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎Battery percentage unknown.‎‏‎‎‏‎"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎No phone.‎‏‎‎‏‎"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎Phone one bar.‎‏‎‎‏‎"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‎Phone two bars.‎‏‎‎‏‎"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‎Notification dismissed.‎‏‎‎‏‎"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎Bubble dismissed.‎‏‎‎‏‎"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎Notification shade.‎‏‎‎‏‎"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‏‎Quick settings.‎‏‎‎‏‎"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎Lock screen.‎‏‎‎‏‎"</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎Profile may be monitored‎‏‎‎‏‎"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎Network may be monitored‎‏‎‎‏‎"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎Network may be monitored‎‏‎‎‏‎"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎This device is managed by your parent‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎Your organization owns this device and may monitor network traffic‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ owns this device and may monitor network traffic‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎This device belongs to your organization and is connected to ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎Disable VPN‎‏‎‎‏‎"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎Disconnect VPN‎‏‎‎‏‎"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎View Policies‎‏‎‎‏‎"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‎View controls‎‏‎‎‏‎"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‎This device belongs to ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your IT admin.‎‏‎‎‏‎"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎This device belongs to your organization.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your IT admin.‎‏‎‎‏‎"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‎Your organization installed a certificate authority on this device. Your secure network traffic may be monitored or modified.‎‏‎‎‏‎"</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‎‎Your admin has turned on network logging, which monitors traffic on your device.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your admin.‎‏‎‎‏‎"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎You gave an app permission to set up a VPN connection.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎This app can monitor your device and network activity, including emails, apps, and websites.‎‏‎‎‏‎"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎Your work profile is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Your admin is capable of monitoring your network activity including emails, apps, and websites.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎For more information, contact your admin.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎You\'re also connected to a VPN, which can monitor your network activity.‎‏‎‎‏‎"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎This device is managed by your parent. Your parent can see and manage information such as the apps you use, your location, and your screen time.‎‏‎‎‏‎"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎VPN‎‏‎‎‏‎"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎You\'re connected to ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎, which can monitor your network activity, including emails, apps, and websites.‎‏‎‎‏‎"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‎You\'re connected to ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎, which can monitor your personal network activity, including emails, apps, and websites.‎‏‎‎‏‎"</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎Keep showing notifications from this app?‎‏‎‎‏‎"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎Silent‎‏‎‎‏‎"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎Default‎‏‎‎‏‎"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎Bubble‎‏‎‎‏‎"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎Automatic‎‏‎‎‏‎"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‏‎‎No sound or vibration‎‏‎‎‏‎"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎No sound or vibration and appears lower in conversation section‎‏‎‎‏‎"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎Settings‎‏‎‎‏‎"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎Priority‎‏‎‎‏‎"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ doesn’t support conversation features‎‏‎‎‏‎"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‏‎‎No recent bubbles‎‏‎‎‏‎"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‎Recent bubbles and dismissed bubbles will appear here‎‏‎‎‏‎"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎These notifications can\'t be modified.‎‏‎‎‏‎"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‎‏‏‎This group of notifications cannot be configured here‎‏‎‎‏‎"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎Proxied notification‎‏‎‎‏‎"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎Device Services‎‏‎‎‏‎"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎No title‎‏‎‎‏‎"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‎‎‎Tap to restart this app and go full screen.‎‏‎‎‏‎"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎Settings for ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ bubbles‎‏‎‎‏‎"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‎Overflow‎‏‎‎‏‎"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎Add back to stack‎‏‎‎‏‎"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎Manage‎‏‎‎‏‎"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ from ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ from ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>‎‏‎‎‏‏‏‎ more‎‏‎‎‏‎"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎Move‎‏‎‎‏‎"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎Move top left‎‏‎‎‏‎"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎Move top right‎‏‎‎‏‎"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎Move bottom left‎‏‎‎‏‎"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‎‎Move bottom right‎‏‎‎‏‎"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎Dismiss bubble‎‏‎‎‏‎"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎Don’t bubble conversation‎‏‎‎‏‎"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎Chat using bubbles‎‏‎‎‏‎"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it.‎‏‎‎‏‎"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎Control bubbles anytime‎‏‎‎‏‎"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎Tap Manage to turn off bubbles from this app‎‏‎‎‏‎"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‎Got it‎‏‎‎‏‎"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ settings‎‏‎‎‏‎"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‎‎‎System navigation updated. To make changes, go to Settings.‎‏‎‎‏‎"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎Go to Settings to update system navigation‎‏‎‎‏‎"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎Standby‎‏‎‎‏‎"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎Pair new device‎‏‎‎‏‎"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎Build number‎‏‎‎‏‎"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎Build number copied to clipboard.‎‏‎‎‏‎"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎Problem reading your battery meter‎‏‎‎‏‎"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎Tap for more information‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings_tv.xml b/packages/SystemUI/res/values-en-rXC/strings_tv.xml
index 88c5843..9fb2610 100644
--- a/packages/SystemUI/res/values-en-rXC/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings_tv.xml
@@ -21,4 +21,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎Microphone Active‎‏‎‎‏‎"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎%1$s accessed your microphone‎‏‎‎‏‎"</string>
+    <string name="notification_vpn_connected" msgid="3891023882833274730">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎VPN is connected‎‏‎‎‏‎"</string>
+    <string name="notification_vpn_disconnected" msgid="7150747626448044843">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎VPN is disconnected‎‏‎‎‏‎"</string>
+    <string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎Via ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d30a395..d8e1234 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Vuelve a hacer una captura de pantalla"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"No se puede guardar la captura de pantalla debido a que no hay suficiente espacio de almacenamiento"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"La app o tu organización no permiten las capturas de pantalla"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Editar captura de pantalla"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Descartar captura de pantalla"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa de la captura de pantalla"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Grabadora de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación pantalla"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Dos barras de batería"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Tres barras de batería"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batería completa"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Se desconoce el porcentaje de la batería."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Sin teléfono"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Una barra de teléfono"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Dos barras de teléfono"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notificación ignorada"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Se descartó el cuadro."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Pantalla de notificaciones"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configuración rápida"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantalla de bloqueo"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Es posible que se supervise el perfil."</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Es posible que la red esté supervisada."</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Es posible que la red esté supervisada"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tu padre o madre administra este dispositivo"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tu organización es propietaria de este dispositivo y podría controlar el tráfico de red"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> es la organización propietaria de este dispositivo y podría controlar el tráfico de red"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertenece a tu organización y está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Inhabilitar VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Controles de vista"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nTu administrador de TI puede controlar y administrar la configuración, el acceso corporativo, las apps, los datos asociados al dispositivo y la información de ubicación.\n\nPara obtener más información, comunícate con el administrador de TI."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertenece a tu organización.\n\nTu administrador de TI puede controlar y administrar la configuración, el acceso corporativo, las apps, los datos asociados al dispositivo y la información de ubicación.\n\nPara obtener más información, comunícate con el administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tu organización instaló una autoridad de certificación en este dispositivo. Es posible que se controle o modifique el tráfico de tu red segura."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Tu administrador activó el registro de red, que controla el tráfico en tu dispositivo.\n\nComunícate con él para obtener más información."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Permitiste que una aplicación configurara una conexión VPN.\n\nEsta aplicación puede supervisar la actividad de la red y del dispositivo, incluidos los correos electrónicos, las aplicaciones y los sitios web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> administra tu perfil de trabajo.\n\nTu administrador puede controlar tu actividad en la red, como los correos electrónicos, las apps y los sitios web.\n\nComunícate con él para obtener más información.\n\nTambién estás conectado a una VPN, que puede controlar tu actividad en la red."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Tu padre o madre administra este dispositivo. Esa persona puede ver y administrar información, como las apps que usas, tu ubicación y el tiempo de uso."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Estás conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que puede controlar la actividad de la red, incluidos los correos electrónicos, las apps y los sitios web."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Tienes conexión a la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g>, que puede supervisar la actividad de la red personal, incluidos los correos electrónicos, las aplicaciones y los sitios web."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"¿Quieres seguir viendo las notificaciones de esta app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silenciada"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminada"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Cuadro"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sin sonido ni vibración"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"No suena ni vibra, y aparece en la parte inferior de la sección de conversaciones."</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configuración"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritaria"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"No hay burbujas recientes"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Las burbujas recientes y las que se descartaron aparecerán aquí"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"No se pueden modificar estas notificaciones."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"No se puede configurar aquí este grupo de notificaciones"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificación almacenada en proxy"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Servicios del dispositivo"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Presiona para reiniciar esta app y acceder al modo de pantalla completa."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Configuración para burbujas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menú ampliado"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Volver a agregar a la pila"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Administrar"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> y <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> más"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Ubicar arriba a la izquierda"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Ubicar arriba a la derecha"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Ubicar abajo a la izquierda"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Ubicar abajo a la derecha"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Descartar burbuja"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"No mostrar la conversación en burbujas"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat con burbujas"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Las conversaciones nuevas aparecen como elementos flotantes o burbujas. Presiona para abrir la burbuja. Arrástrala para moverla."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Presiona Administrar para desactivar las burbujas de esta app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Configuración para actualizar la navegación del sistema"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo nuevo"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema al leer el medidor de batería"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Presiona para obtener más información"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
index 8e9e048..17544e7 100644
--- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Micrófono activado"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accedió al micrófono"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 875c310..d1034a7 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Vuelve a intentar hacer la captura de pantalla"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"No se puede guardar la captura de pantalla porque no hay espacio de almacenamiento suficiente"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"La aplicación o tu organización no permiten realizar capturas de pantalla"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Editar captura de pantalla"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Cerrar captura de pantalla"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa de captura de pantalla"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Grabación de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación de pantalla"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Dos barras de batería"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Tres barras de batería"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batería completa"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentaje de batería desconocido."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Sin teléfono"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Una barra de cobertura"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Dos barras de cobertura"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notificación ignorada"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Burbuja cerrada."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Pantalla de notificaciones"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Ajustes rápidos"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantalla de bloqueo."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Es posible que se supervise el perfil"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Puede que la red esté supervisada"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Puede que la red esté supervisada"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo lo gestionan tu padre o tu madre"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"El dispositivo pertenece a tu organización, que puede monitorizar su tráfico de red"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"El dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, que puede monitorizar su tráfico de red"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertenece a tu organización y está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Inhabilitar VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controles"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"El dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nEl administrador de TI puede monitorizar y gestionar los ajustes, el acceso corporativo, las aplicaciones, la información de ubicación del dispositivo y los datos asociados a él.\n\nPara obtener más información, ponte en contacto con el administrador de TI."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"El dispositivo pertenece a tu organización.\n\nEl administrador de TI puede monitorizar y gestionar los ajustes, el acceso corporativo, las aplicaciones, la información de ubicación del dispositivo y los datos asociados a él.\n\nPara obtener más información, ponte en contacto con el administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tu organización ha instalado una entidad de certificación en este dispositivo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Tu administrador ha activado el registro de la red para supervisar el tráfico en tu dispositivo.\n\nPonte en contacto con él para obtener más información."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Has concedido permiso a una aplicación para configurar una conexión VPN.\n\nEsta aplicación puede controlar tu dispositivo y tu actividad de red, como correos electrónicos, aplicaciones y sitios web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"El administrador de tu perfil de trabajo es <xliff:g id="ORGANIZATION">%1$s</xliff:g>,\n\n que puede supervisar tu actividad de red, como correos electrónicos, aplicaciones y sitios web.\n\nPara obtener más información, ponte en contacto con tu administrador.\n\nTambién estás conectado a una red VPN, que puede supervisar tu actividad de red."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Tu padre o madre gestionan este dispositivo y pueden ver y controlar cierta información, como las aplicaciones que utilizas, tu ubicación y tu tiempo de pantalla."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Te has conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que puede supervisar tu actividad de red, como los correos electrónicos, las aplicaciones y los sitios web."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Estas conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que puede controlar tu actividad de red personal, como correos electrónicos, aplicaciones y sitios web."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"¿Quieres seguir viendo las notificaciones de esta aplicación?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silencio"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminado"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Burbuja"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sin sonido ni vibración"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sin sonido ni vibración, y se muestra más abajo en la sección de conversaciones"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ajustes"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridad"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"No se pueden usar funciones de conversación con <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"No hay burbujas recientes"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Las burbujas recientes y las cerradas aparecerán aquí"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificaciones no se pueden modificar."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Este grupo de notificaciones no se puede configurar aquí"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificación mediante proxy"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Servicios del dispositivo"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Ajustes de las burbujas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menú adicional"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Volver a añadir a la pila"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gestionar"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> y <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> más"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Mover arriba a la izquierda"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Mover arriba a la derecha"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Mover abajo a la izquierda."</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Mover abajo a la derecha"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Cerrar burbuja"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"No mostrar conversación en burbuja"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatea con burbujas"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Las conversaciones nuevas aparecen como iconos flotantes llamadas \"burbujas\". Toca para abrir la burbuja. Arrastra para moverla."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestionar para desactivar las burbujas de esta aplicación"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Ajustes de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Ajustes para actualizar la navegación del sistema"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular nuevo dispositivo"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"No se ha podido leer el indicador de batería"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca la pantalla para consultar más información"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings_tv.xml b/packages/SystemUI/res/values-es/strings_tv.xml
index 6a72a3d..40340d8 100644
--- a/packages/SystemUI/res/values-es/strings_tv.xml
+++ b/packages/SystemUI/res/values-es/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Micrófono activado"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ha accedido a tu micrófono"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f9940a3..847d2b7 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Proovige ekraanipilt uuesti jäädvustada"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Piiratud salvestusruumi tõttu ei saa ekraanipilti salvestada"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Rakendus või teie organisatsioon ei luba ekraanipilte jäädvustada"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Ekraanipildi muutmine"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Sule ekraanipilt"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekraanipildi eelvaade"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekraanisalvesti"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekraanisalvestuse töötlemine"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Aku: kaks pulka."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Aku: kolm pulka."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Aku täis."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Aku laetuse protsent on teadmata."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Telefonisignaal puudub"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefonisignaal: üks pulk."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefonisignaal: kaks pulka."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Märguandest on loobutud."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Mullist loobuti."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Märguande vari."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Kiirseaded."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Kuva lukustamine."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profiili võidakse jälgida"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Võrku võidakse jälgida"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Võrku võidakse jälgida"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Seda seadet haldab sinu vanem"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Teie organisatsioon on selle seadme omanik ja võib jälgida võrguliiklust"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> on selle seadme omanik ja võib jälgida võrguliiklust"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"See seade kuulub teie organisatsioonile ja on ühendatud rakendusega <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Keela VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Katkesta VPN-i ühendus"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Kuva eeskirjad"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Kuva järelevalve haldamine"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"See seade kuulub organisatsioonile <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-administraator saab jälgida ning hallata seadeid, ettevõttesisest juurdepääsu, rakendusi, seadmega seotud andmeid ja seadme asukohateavet.\n\nLisateabe saamiseks võtke ühendust IT-administraatoriga."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"See seade kuulub teie organisatsioonile.\n\nIT-administraator saab jälgida ning hallata seadeid, ettevõttesisest juurdepääsu, rakendusi, seadmega seotud andmeid ja seadme asukohateavet.\n\nLisateabe saamiseks võtke ühendust IT-administraatoriga."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Teie organisatsioon installis sellesse seadmesse sertifikaadi volituse. Teie turvalist võrguliiklust võidakse jälgida ja muuta."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Teie administraator on sisse lülitanud võrgu logimise funktsiooni, mis jälgib teie seadmes liiklust.\n\nLisateabe saamiseks võtke ühendust administraatoriga."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Andsite rakendusele loa VPN-i ühenduse seadistamiseks.\n\nSee rakendus võib jälgida teie seadet ja võrgutegevusi, sh meile, rakendusi ja veebisaite."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Teie tööprofiili haldab <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministraator saab jälgida teie töökoha võrgutegevusi, sh meile, rakendusi ja veebisaite.\n\nLisateabe saamiseks võtke ühendust administraatoriga.\n\nTeil on ühendus ka VPN-iga, mis saab teie võrgutegevusi jälgida."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Seda seadet haldab sinu vanem. Sinu vanem näeb ja saab hallata teavet, näiteks kasutatavaid rakendusi, asukohta ja ekraaniaega."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Olete ühendatud rakendusega <xliff:g id="APPLICATION">%1$s</xliff:g>, mis võib jälgida teie võrgutegevusi, sh meile, rakendusi ja veebisaite."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Teie seade on ühendatud rakendusega <xliff:g id="APPLICATION">%1$s</xliff:g>, mis võib jälgida teie isiklikke võrgutegevusi, sh meile, rakendusi ja veebisaite."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Kas jätkata selle rakenduse märguannete kuvamist?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Hääletu"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Vaikeseade"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Mull"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automaatne"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ilma heli ja vibreerimiseta"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ilma heli ja vibreerimiseta, kuvatakse vestluste jaotises allpool"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Seaded"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteetne"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei toeta vestlusfunktsioone"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Hiljutisi mulle pole"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Siin kuvatakse hiljutised ja suletud mullid."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Neid märguandeid ei saa muuta."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Seda märguannete rühma ei saa siin seadistada"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Puhvriga märguanne"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Seadme teenused"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Pealkiri puudub"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Puudutage rakenduse taaskäivitamiseks ja täisekraanrežiimi aktiveerimiseks."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> mullide seaded"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Ületäide"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Lisa tagasi virna"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Halda"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> rakendusest <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> rakenduselt <xliff:g id="APP_NAME">%2$s</xliff:g> ja veel <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Teisalda"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Teisalda üles vasakule"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Teisalda üles paremale"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Teisalda alla vasakule"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Teisalda alla paremale"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Sule mull"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ära kuva vestlust mullina"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Vestelge mullide abil"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Uued vestlused kuvatakse hõljuvate ikoonidena ehk mullidena. Puudutage mulli avamiseks. Lohistage mulli, et seda liigutada."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Juhtige mulle igal ajal"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Selle rakenduse puhul mullide väljalülitamiseks puudutage valikut Halda"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selge"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Rakenduse <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> seaded"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Süsteemi navigeerimise värskendamiseks avage jaotis Seaded"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ooterežiim"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uue seadme sidumine"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem akumõõdiku lugemisel"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Puudutage lisateabe saamiseks"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings_tv.xml b/packages/SystemUI/res/values-et/strings_tv.xml
index 61c1435..329311a 100644
--- a/packages/SystemUI/res/values-et/strings_tv.xml
+++ b/packages/SystemUI/res/values-et/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon on aktiivne"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s pääses teie mikrofonile juurde"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index cb86a16..d17c533 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Saiatu berriro pantaila-argazkia ateratzen"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Ezin da gorde pantaila-argazkia ez delako gelditzen tokirik"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikazioak edo erakundeak ez du onartzen pantaila-argazkiak ateratzea"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Editatu pantaila-argazkia"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Baztertu pantaila-argazkia"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pantaila-argazkiaren aurrebista"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Pantaila-grabagailua"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pantaila-grabaketa prozesatzen"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Bateriak bi barra ditu."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Bateriak hiru barra ditu."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Bateria beteta dago."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Bateriaren ehunekoa ezezaguna da."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Ez dago telefono-zenbakirik."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefono-seinaleak barra bat du."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefono-seinaleak bi barra ditu."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Jakinarazpena baztertu da."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Baztertu da globoa."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Jakinarazpenen panela."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Ezarpen bizkorrak."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantaila blokeatzeko aukera."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Baliteke profila kontrolatuta egotea"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Baliteke sarea kontrolatuta egotea"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Baliteke sarea kontrolatuta egotea"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Zure gurasoak kudeatzen du gailua"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Gailu hau zure erakundearena da, eta baliteke hark sareko trafikoa gainbegiratzea"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da, eta baliteke sareko trafikoa gainbegiratzea"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Gailu hau zure erakundearena da, eta <xliff:g id="VPN_APP">%1$s</xliff:g> sarera dago konektatuta"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Desgaitu VPN konexioa"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Deskonektatu VPN sarea"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ikusi gidalerroak"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ikusi kontrolatzeko aukerak"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da.\n\nIKT saileko administratzaileak gainbegiratu eta kudeatu egin ditzake ezarpenak, enpresa-sarbidea, aplikazioak, gailuarekin erlazionatutako datuak eta gailuaren kokapen-informazioa.\n\nInformazio gehiago lortzeko, jarri IKT saileko administratzailearekin harremanetan."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Gailu hau zure erakundearena da.\n\nIKT saileko administratzaileak gainbegiratu eta kudeatu egin ditzake ezarpenak, enpresa-sarbidea, aplikazioak, gailuarekin erlazionatutako datuak eta gailuaren kokapen-informazioa.\n\nInformazio gehiago lortzeko, jarri IKT saileko administratzailearekin harremanetan."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Erakundeak ziurtagiri-emaile bat instalatu du gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administratzaileak sare-erregistroak aktibatu ditu; horrela, zure gailuko trafikoa gainbegira dezake.\n\nInformazio gehiago lortzeko, jarri administratzailearekin harremanetan."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Aplikazio bati VPN konexio bat konfiguratzeko baimena eman diozu.\n\nAplikazio horrek gailuko eta sareko jarduerak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> erakundeak kudeatzen du zure laneko profila.\n\nAdministratzaileak sareko jarduerak kontrola diezazkizuke, besteak beste, posta elektronikoa, aplikazioak eta webguneak.\n\nInformazio gehiago lortzeko, jarri administratzailearekin harremanetan.\n\nHorrez gain, VPN batera zaude konektatuta, eta hark ere kontrola ditzake zure sareko jarduerak."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Zure gurasoak kudeatzen du gailua. Zure gurasoak gailuko informazioa ikus eta kudea dezake; besteak beste, zer aplikazio erabiltzen dituzun, zure kokapena zein den eta pantaila aurrean zenbat eta noiz egoten zaren."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN konexioa"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"<xliff:g id="APPLICATION">%1$s</xliff:g> aplikaziora konektatuta zaude. Aplikazio horrek sarean egiten dituzun jarduerak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"<xliff:g id="APPLICATION">%1$s</xliff:g> aplikaziora konektatuta zaude. Aplikazio horrek sarean egiten dituzun jarduera pertsonalak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Aplikazio honen jakinarazpenak erakusten jarraitzea nahi duzu?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Isila"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Balio lehenetsia"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Burbuila"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikoa"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ez du tonurik jotzen edo dar-dar egiten"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ez du tonurik jotzen edo dar-dar egiten, eta elkarrizketaren atalaren behealdean agertzen da"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ezarpenak"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Lehentasuna"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez ditu onartzen elkarrizketetarako eginbideak"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Ez dago azkenaldiko burbuilarik"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Azken burbuilak eta baztertutakoak agertuko dira hemen"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Jakinarazpen horiek ezin dira aldatu."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Jakinarazpen talde hau ezin da konfiguratu hemen"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxy bidezko jakinarazpena"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Gailuetarako zerbitzuak"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ez du izenik"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Berrabiarazi aplikazio hau eta ezarri pantaila osoko modua."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren ezarpenen burbuilak"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Gainezkatzea"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Gehitu berriro errenkadan"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Kudeatu"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>)"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioaren \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\" jakinarazpena, eta beste <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Eraman"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Eraman goialdera, ezkerretara"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Eraman goialdera, eskuinetara"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Eraman behealdera, ezkerretara"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Eraman behealdera, eskuinetara"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Baztertu burbuila"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ez erakutsi elkarrizketak burbuila gisa"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Txateatu burbuilen bidez"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Elkarrizketa berriak ikono gainerakor edo burbuila gisa agertzen dira. Sakatu burbuila irekitzeko. Arrasta ezazu mugitzeko."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolatu burbuilak edonoiz"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Aplikazioaren burbuilak desaktibatzeko, sakatu Kudeatu"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ados"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> aplikazioaren ezarpenak"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Eguneratu da sistemaren nabigazioa. Aldaketak egiteko, joan Ezarpenak atalera."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistemaren nabigazioa eguneratzeko, joan Ezarpenak atalera"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Egonean"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parekatu beste gailu batekin"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Arazo bat gertatu da bateria-neurgailua irakurtzean"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Informazio gehiago lortzeko, sakatu hau"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings_tv.xml b/packages/SystemUI/res/values-eu/strings_tv.xml
index e77de50..b311ecc 100644
--- a/packages/SystemUI/res/values-eu/strings_tv.xml
+++ b/packages/SystemUI/res/values-eu/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofonoa aktibatuta dago"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s aplikazioak mikrofonoa atzitu du"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index afa0759..07a5dae 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"دوباره نماگرفت بگیرید"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"به دلیل محدود بودن فضای ذخیره‌سازی نمی‌توان نماگرفت را ذخیره کرد"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"برنامه یا سازمان شما اجازه نمی‌دهند نماگرفت بگیرید."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ویرایش نماگرفت"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"رد کردن نماگرفت"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"پیش‌نمایش نماگرفت"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ضبط‌کننده صفحه‌نمایش"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحه‌نمایش"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"دو نوار برای باتری."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"سه نوار برای باتری."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"باتری پر است."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"درصد شارژ باتری مشخص نیست."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"بدون تلفن."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"یک نوار برای تلفن."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"دو نوار برای تلفن."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"اعلان ردشد."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"حبابک رد شد."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"مجموعه اعلان."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"تنظیمات سریع."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"صفحه قفل."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"شاید نمایه کنترل شود"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ممکن است شبکه کنترل شود"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ممکن است شبکه کنترل شود"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"این دستگاه را ولی‌تان مدیریت می‌کند"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"مالک این دستگاه سازمان شما است و ممکن است ترافیک شبکه را پایش کند"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"مالک این دستگاه <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> است و ممکن است ترافیک شبکه را پایش کند"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"این دستگاه به سازمان شما تعلق دارد و به <xliff:g id="VPN_APP">%1$s</xliff:g> متصل است"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"‏غیرفعال کردن VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"‏قطع اتصال VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"مشاهده خط‌مشی‌ها"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"مشاهده کنترل‌ها"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> تعلق دارد.\n\nسرپرست فناوری اطلاعات می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، داده‌های مرتبط با دستگاه، و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nبرای اطلاعات بیشتر، با سرپرست فناوری و اطلاعات تماس بگیرید."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"این دستگاه به سازمان شما تعلق دارد.\n\nسرپرست فناوری اطلاعات می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، و داده‌های مرتبط با دستگاه و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nبرای اطلاعات بیشتر، با سرپرست فناوری و اطلاعات تماس بگیرید."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"سازمان شما مرجع گواهینامه‌ای در این دستگاه نصب کرده است. ممکن است ترافیک امن شبکه شما پایش یا تغییر داده شود."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"سرپرست سیستم شما گزارش‌گیری شبکه را (که بر ترافیک دستگاهتان نظارت می‌کند) روشن کرده است.\n\nبرای اطلاعات بیشتر، با سرپرست خود تماس بگیرید."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"‏شما به برنامه‌ای برای تنظیم اتصال VPN اجازه دادید.\n\n این برنامه می‌تواند دستگاه و فعالیت شبکه‌تان را کنترل کند، از جمله ایمیل‌، برنامه‌ و وب‌سایت‌ها."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"‏نمایه کاری شما توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت می‌شود.\n\nسرپرست سیستم شما می‌تواند بر فعالیت شبکه شما (ازجمله ایمیل‌ها، برنامه‌ها و وب‌سایت‌ها) نظارت داشته باشد.\n\nبرای اطلاعات بیشتر، با سرپرست خود تماس بگیرید.\n\nهمچنین به VPN متصل هستید که می‌تواند بر فعالیت شبکه شما نظارت داشته باشد."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"این دستگاه را ولی‌تان مدیریت می‌کند. ولی‌تان می‌تواند اطلاعاتی مثل برنامه‌هایی که استفاده می‌کنید، مکانتان، و مدت تماشای صفحه‌تان را ببیند و مدیریت کند."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"شما به <xliff:g id="APPLICATION">%1$s</xliff:g> متصل هستید، که می‌تواند فعالیت شما در شبکه (ازجمله ایمیل‌، برنامه‌ و وب‌سایت‌ها) را پایش کند."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"شما به <xliff:g id="APPLICATION">%1$s</xliff:g> وصل شده‌اید، که می‌تواند فعالیت شبکه شخصی شما از جمله ایمیل‌، برنامه‌ و وب‌سایت‌ها را کنترل کند."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"نمایش اعلان از این برنامه ادامه یابد؟"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"بی‌صدا"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"پیش‌فرض"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"حباب"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"خودکار"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"بدون صدا یا لرزش"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"بدون صدا و لرزش در پایین بخش مکالمه نشان داده می‌شود"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"تنظیمات"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"اولویت"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> از ویژگی‌های مکالمه پشتیبانی نمی‌کند"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"هیچ حبابک جدیدی وجود ندارد"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"حبابک‌ها اخیر و حبابک‌ها ردشده اینجا ظاهر خواهند شد"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"این اعلان‌ها قابل اصلاح نیستند."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"نمی‌توانید این گروه اعلان‌ها را در اینجا پیکربندی کنید"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"اعلان‌های دارای پراکسی"</string>
@@ -795,8 +803,8 @@
     <string name="keyboard_key_media_previous" msgid="5637875709190955351">"قبلی"</string>
     <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"عقب بردن"</string>
     <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"جلو بردن سریع"</string>
-    <string name="keyboard_key_page_up" msgid="173914303254199845">"صفحه بعدی"</string>
-    <string name="keyboard_key_page_down" msgid="9035902490071829731">"صفحه قبلی"</string>
+    <string name="keyboard_key_page_up" msgid="173914303254199845">"صفحه بعد"</string>
+    <string name="keyboard_key_page_down" msgid="9035902490071829731">"صفحه قبل"</string>
     <string name="keyboard_key_forward_del" msgid="5325501825762733459">"حذف"</string>
     <string name="keyboard_key_move_home" msgid="3496502501803911971">"ابتدا"</string>
     <string name="keyboard_key_move_end" msgid="99190401463834854">"انتها"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"سرویس‌های دستگاه"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"بدون عنوان"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"برای بازراه‌اندازی این برنامه و تغییر به حالت تمام‌صفحه، ضربه بزنید."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"تنظیمات برای حبابک‌های <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"لبریزشده"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"افزودن برگشت به پشته"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"مدیریت"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g> و <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> مورد بیشتر"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"انتقال"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"انتقال به بالا سمت راست"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"انتقال به بالا سمت چپ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"انتقال به پایین سمت راست"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"انتقال به پایین سمت چپ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"رد کردن حبابک"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"مکالمه در حباب نشان داده نشود"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"گپ بااستفاده از حبابک‌ها"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"مکالمه‌های جدید به‌صورت نمادهای شناور یا حبابک‌ها نشان داده می‌شوند. برای باز کردن حبابک‌ها ضربه بزنید. برای جابه‌جایی، آن را بکشید."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"کنترل حبابک‌ها در هرزمانی"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"برای خاموش کردن «حبابک‌ها» از این برنامه، روی «مدیریت» ضربه بزنید"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"متوجه‌ام"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"تنظیمات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"پیمایش سیستم به‌روزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"برای به‌روزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"آماده‌به‌کار"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"مشکلی در خواندن میزان باتری وجود دارد"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"برای اطلاعات بیشتر ضربه بزنید"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml
index bf3987d..c6931a9 100644
--- a/packages/SystemUI/res/values-fa/strings_tv.xml
+++ b/packages/SystemUI/res/values-fa/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"میکروفون فعال است"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"‏%1$s به میکروفون شما دسترسی پیدا کرد"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 11c7e19..835e32f 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Yritä ottaa kuvakaappaus uudelleen."</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Kuvakaappauksen tallennus epäonnistui, sillä tallennustilaa ei ole riittävästi"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Sovellus tai organisaatio ei salli kuvakaappauksien tallentamista."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Muokkaa kuvakaappausta"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Hylkää kuvakaappaus"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Kuvakaappauksen esikatselu"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Näytön tallentaja"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Näytön tallennusta käsitellään"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Akun virta - kaksi palkkia."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Akun virta - kolme palkkia."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Akku täynnä."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akun varaustaso ei tiedossa."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Ei puhelinverkkoyhteyttä."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Puhelinverkkosignaali - yksi palkki."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Puhelinverkkosignaali - kaksi palkkia."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Ilmoitus hylätty."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Kupla ohitettu."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Ilmoitusalue."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Pika-asetukset."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lukitse näyttö."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profiilia saatetaan valvoa"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Verkkoa saatetaan valvoa"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Verkkoa saatetaan valvoa"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Vanhempasi ylläpitää tätä laitetta"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisaatiosi omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Organisaatiosi omistaa laitteen, joka on yhdistetty tähän: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Poista VPN käytöstä"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Katkaise VPN-yhteys"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Näytä säännöt"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Katso asetukset"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa tämän laitteen.\n\nJärjestelmänvalvoja voi valvoa ja muuttaa asetuksia, yrityskäyttöä, sovelluksia sekä laitteeseen yhdistettyjä tietoja ja sen sijaintitietoja.\n\nSaat lisätietoja järjestelmänvalvojalta."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Organisaatiosi omistaa tämän laitteen.\n\nJärjestelmänvalvoja voi valvoa ja muuttaa asetuksia, yrityskäyttöä, sovelluksia sekä laitteeseen yhdistettyjä tietoja ja sen sijaintitietoja.\n\nSaat lisätietoja järjestelmänvalvojalta."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisaatiosi asensi laitteeseen varmenteen myöntäjän. Suojattua verkkoliikennettäsi voidaan valvoa tai muuttaa."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Järjestelmänvalvoja on ottanut käyttöön verkkolokitietojen tallentamisen. Sen avulla seurataan laitteellasi tapahtuvaa liikennettä.\n\nPyydä lisätietoja järjestelmänvalvojalta."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Olet myöntänyt sovellukselle oikeuden VPN-yhteyden muodostamiseen.\n\nSovellus voi valvoa laitettasi ja toimintaasi verkossa, esimerkiksi avaamiasi sähköposteja, sovelluksia ja verkkosivustoja."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Työprofiiliasi hallitsee <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nJärjestelmänvalvoja voi valvoa sähköpostin, sovellusten ja verkkosivustojen käyttöä sekä muuta toimintaasi verkossa.\n\nPyydä lisätietoja järjestelmänvalvojalta.\n\nOlet myös yhteydessä VPN:ään, joka voi valvoa toimintaasi verkossa."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Vanhempasi ylläpitää tätä laitetta. Vanhempasi voi nähdä ja ylläpitää tietoja, esim. käyttämiäsi sovelluksia, sijaintiasi ja käyttöaikaasi."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Olet muodostanut yhteyden sovellukseen <xliff:g id="APPLICATION">%1$s</xliff:g>, joka voi valvoa toimintaasi verkossa, esimerkiksi sähköposteja, sovelluksia ja verkkosivustoja."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Olet muodostanut yhteyden sovellukseen <xliff:g id="APPLICATION">%1$s</xliff:g>, joka voi valvoa henkilökohtaista toimintaasi verkossa. Sovellus voi seurata esimerkiksi avaamiasi sähköposteja, sovelluksia ja verkkosivustoja."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Jatketaanko ilmoitusten näyttämistä tästä sovelluksesta?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Äänetön"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Oletus"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Kupla"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automaattinen"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ei ääntä tai värinää"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ei ääntä tai värinää ja näkyy alempana keskusteluosiossa"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Asetukset"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Tärkeä"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei tue keskusteluominaisuuksia"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Ei viimeaikaisia kuplia"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Viimeaikaiset ja äskettäin ohitetut kuplat näkyvät täällä"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Näitä ilmoituksia ei voi muokata"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Tätä ilmoitusryhmää ei voi määrittää tässä"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Välitetty ilmoitus"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Laitepalvelut"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ei nimeä"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Napauta, niin sovellus käynnistyy uudelleen ja siirtyy koko näytön tilaan."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Kuplien asetukset: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Ylivuoto"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Lisää takaisin pinoon"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Ylläpidä"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>: <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>) ja <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> muuta"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Siirrä"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Siirrä vasempaan yläreunaan"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Siirrä oikeaan yläreunaan"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Siirrä vasempaan alareunaan"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Siirrä oikeaan alareunaan"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Ohita kupla"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Älä näytä kuplia keskusteluista"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chattaile kuplien avulla"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Uudet keskustelut näkyvät kelluvina kuvakkeina tai kuplina. Avaa kupla napauttamalla. Siirrä sitä vetämällä."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Muuta kuplien asetuksia milloin tahansa"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Valitse Ylläpidä, jos haluat poistaa kuplat käytöstä tästä sovelluksesta"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selvä"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: asetukset"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Vaihda järjestelmän navigointitapaa asetuksista"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Virransäästötila"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Muodosta uusi laitepari"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ongelma akkumittarin lukemisessa"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Saat lisätietoja napauttamalla"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml
index 0b1f02f..6c84e58 100644
--- a/packages/SystemUI/res/values-fi/strings_tv.xml
+++ b/packages/SystemUI/res/values-fi/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofoni aktiivinen"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s sai pääsyn mikrofoniisi"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index b8ea6ac..e1b15b3 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Essayez de faire une autre capture d\'écran"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Impossible d\'enregistrer la capture d\'écran, car l\'espace de stockage est limité"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Modifier la capture d\'écran"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Fermer la capture d\'écran"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Aperçu de la capture d\'écran"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Trait. de l\'enregist. d\'écran…"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Niveau de batterie : moyen"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Niveau de batterie : bon"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batterie pleine"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pourcentage de la pile inconnu."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Aucun signal"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Signal : faible"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Signal : moyen"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notification masquée"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bulle ignorée."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Volet des notifications"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Paramètres rapides"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Écran de verrouillage"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"le profil peut être contrôlé"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Le réseau peut être surveillé"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Le réseau peut être surveillé"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par ton parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Votre organisation possède cet appareil et peut contrôler le trafic réseau"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> possède cet appareil et peut contrôler le trafic réseau"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Cet appareil appartient à votre organisation et est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Désactiver le RPV"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Déconnecter le RPV"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afficher les politiques"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Afficher les commandes"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Votre appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Cet appareil appartient à votre organisation.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à votre appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Votre entreprise a installé une autorité de certification sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Votre administrateur a activé la journalisation réseau, qui surveille le trafic sur votre appareil.\n\nPour en savoir plus, communiquez avec lui."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Vous avez autorisé une application à configurer une connexion RPV.\n\nCette application peut contrôler l\'activité de votre appareil et votre activité sur le réseau, y compris les courriels, les applications et les sites Web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVotre administrateur peut surveiller votre activité sur le réseau, y compris les courriels que vous échangez, les applications que vous utilisez et les sites Web que vous visitez.\n\nPour en savoir plus, communiquez avec votre administrateur.\n\nVous êtes aussi connecté à un RPV, qui peut surveiller votre activité sur le réseau."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Cet appareil est géré par ton parent. Ton parent peut voir et gérer de l\'information, comme les applications que tu utilises, ta position et ton temps d\'utilisation des écrans."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"RPV"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Vous êtes connecté à <xliff:g id="APPLICATION">%1$s</xliff:g>. Cette application peut contrôler votre activité sur le réseau, y compris les courriels, les applications et les sites Web."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Vous êtes connecté à <xliff:g id="APPLICATION">%1$s</xliff:g>. Cette application peut contrôler votre activité personnelle sur le réseau, y compris les courriels, les applications et les sites Web."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Continuer à afficher les notifications de cette application?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Mode silencieux"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Par défaut"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bulle"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Aucun son ni vibration"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Aucun son ni vibration, et s\'affiche plus bas dans la section des conversations"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Paramètres"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorité"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne prend pas en charge les fonctionnalités de conversation"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Aucune bulle récente"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Les bulles récentes et les bulles ignorées s\'afficheront ici"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ces notifications ne peuvent pas être modifiées"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ce groupe de notifications ne peut pas être configuré ici"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notification par mandataire"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Services de l\'appareil"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Touchez pour redémarrer cette application et passer en plein écran."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Paramètres pour les bulles de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menu déroulant"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Replacer sur la pile"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gérer"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> et <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> autres"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Déplacer"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Déplacer dans coin sup. gauche"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Déplacer dans coin sup. droit"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Déplacer dans coin inf. gauche"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Déplacer dans coin inf. droit"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Ignorer la bulle"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ne pas afficher les conversations dans des bulles"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Clavarder en utilisant des bulles"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes (de bulles). Touchez une bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Paramètres des bulles"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toucher Gérer pour désactiver les bulles de cette application"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"La navigation système a été mise à jour. Pour apporter des modifications, accédez au menu Paramètres."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez au menu Paramètres pour mettre à jour la navigation système"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Veille"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un autre appareil"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu lors de la lecture du niveau de charge de la pile"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Touchez pour en savoir plus"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
index 23dd656..09dbec2 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microphone actif"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s a accédé à votre microphone"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 289ce40..4cfdaea 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Essayez de nouveau de faire une capture d\'écran"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Impossible d\'enregistrer la capture d\'écran, car l\'espace de stockage est limité"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Les captures d\'écran ne sont pas autorisées par l\'application ni par votre organisation"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Modifier la capture d\'écran"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Fermer la capture d\'écran"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Aperçu de la capture d\'écran"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Niveau de batterie : moyen"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Niveau de batterie : bon"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batterie pleine"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pourcentage de la batterie inconnu."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Aucun signal"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Signal : faible"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Signal : moyen"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notification masquée"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bulle fermée."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Volet des notifications"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Paramètres rapides"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Écran de verrouillage"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Le profil peut être contrôlé."</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Il est possible que le réseau soit surveillé."</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Il est possible que le réseau soit surveillé."</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par tes parents"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Cet appareil appartient à votre organisation, qui peut contrôler votre trafic réseau"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, qui peut contrôler votre trafic réseau"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Cet appareil appartient à votre organisation et il est connecté à <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Désactiver le VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Déconnecter le VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afficher les règles"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Afficher les commandes"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les informations sur sa localisation.\n\nPour plus d\'informations, contactez votre administrateur informatique."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Cet appareil appartient à votre organisation.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les informations sur sa localisation.\n\nPour plus d\'informations, contactez votre administrateur informatique."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Votre entreprise a installé une autorité de certification sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Votre administrateur a activé la journalisation réseau, qui surveille le trafic sur votre appareil.\n\nPour en savoir plus, contactez-le."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Vous avez autorisé une application à configurer une connexion VPN.\n\nCette application peut contrôler l\'activité de votre appareil et votre activité sur le réseau, y compris votre activité relative aux e-mails, aux applications et aux sites Web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVotre administrateur peut contrôler votre activité sur le réseau, y compris au niveau des e-mails, des applications et des sites Web.\n\nPour en savoir plus, contactez-le.\n\nVous êtes également connecté à un VPN qui peut contrôler votre activité sur le réseau."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Cet appareil est géré par tes parents. Ils peuvent voir et gérer certaines informations, telles que les applications que tu utilises, ta position et ton temps d\'utilisation de l\'appareil."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Vous êtes connecté à <xliff:g id="APPLICATION">%1$s</xliff:g>. Cette application peut contrôler votre activité sur le réseau, y compris l\'activité relative aux e-mails, aux applications et aux sites Web."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Vous êtes connecté à <xliff:g id="APPLICATION">%1$s</xliff:g>. Cette application peut contrôler votre activité personnelle sur le réseau, y compris votre activité relative aux e-mails, aux applications et aux sites Web."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Continuer d\'afficher les notifications de cette application ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silencieux"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Par défaut"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bulle"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Aucun son ni vibration"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Aucun son ni vibration, s\'affiche plus bas dans la section des conversations"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Paramètres"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritaire"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas compatible avec les fonctionnalités de conversation"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Aucune bulle récente"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Les bulles récentes et ignorées s\'afficheront ici"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossible de modifier ces notifications."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Vous ne pouvez pas configurer ce groupe de notifications ici"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notification de proxy"</string>
@@ -864,7 +872,7 @@
     <string name="right_icon" msgid="1103955040645237425">"Icône droite"</string>
     <string name="drag_to_add_tiles" msgid="8933270127508303672">"Sélectionnez et faites glisser les icônes pour les ajouter"</string>
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Sélectionnez et faites glisser les icônes pour réorganiser"</string>
-    <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Faites glisser les tuiles ici pour les supprimer."</string>
+    <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Faites glisser les icônes ici pour les supprimer."</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Au minimum <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tuiles sont nécessaires"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Modifier"</string>
     <string name="tuner_time" msgid="2450785840990529997">"Heure"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Services pour l\'appareil"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Appuyez pour redémarrer cette application et activer le mode plein écran."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Paramètres des bulles de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Dépassement"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Ajouter à nouveau l\'élément à la pile"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gérer"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de l\'application <xliff:g id="APP_NAME">%2$s</xliff:g> et <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> autres"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Déplacer"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Déplacer en haut à gauche"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Déplacer en haut à droite"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Déplacer en bas à gauche"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Déplacer en bas à droite"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Fermer la bulle"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ne pas afficher la conversation dans une bulle"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatter en utilisant des bulles"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes ou bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Contrôler les paramètres des bulles"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Appuyez sur \"Gérer\" pour désactiver les bulles de cette application"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigation système mise à jour. Pour apporter des modifications, accédez aux paramètres."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez aux paramètres pour mettre à jour la navigation système"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Mode Veille imminent"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu au niveau de la lecture de votre outil de mesure de batterie"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Appuyer pour en savoir plus"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml
index 4ab6a24..9ebb17d 100644
--- a/packages/SystemUI/res/values-fr/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Micro actif"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s a accédé à votre micro"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index e3d3755..6cf18b8 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Volve tentar crear unha captura de pantalla"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Non se puido gardar a captura de pantalla porque o espazo de almacenamento é limitado"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"A aplicación ou a túa organización non permite realizar capturas de pantalla"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edita a captura de pantalla"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ignora a captura de pantalla"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar a captura de pantalla"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Desprazarse"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Realizar unha captura de pantalla continua"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ignorar a captura de pantalla"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa da captura de pantalla"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravadora da pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando gravación pantalla"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Dúas barras de batería"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Tres barras de batería"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batería cargada"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Descoñécese a porcentaxe da batería."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Sen teléfono"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Unha barra de cobertura"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Dúas barras de cobertura"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notificación rexeitada"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Ignorouse a burbulla."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Panel despregable"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configuración rápida"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantalla de bloqueo."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"O perfil pódese supervisar"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"É posible que se supervise a rede"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"É posible que se supervise a rede"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"O teu pai ou nai xestiona este dispositivo"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A túa organización é propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é a organización propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence á túa organización e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Desactivar VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controis"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO teu administrador de TI pode supervisar e xestionar a configuración, o acceso corporativo, as aplicacións, os datos asociados co teu dispositivo e a información de localización deste último.\n\nPara obter máis información, contacta co teu administrador de TI."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence á túa organización.\n\nO teu administrador de TI pode supervisar e xestionar a configuración, o acceso corporativo, as aplicacións, os datos asociados co teu dispositivo e a información de localización deste último.\n\nPara obter máis información, contacta co teu administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"A túa organización instalou unha autoridade de certificación neste dispositivo. É posible que se controle ou se modifique o teu tráfico de rede segura."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"O administrador activou o rexistro na rede, que controla o tráfico do teu dispositivo.\n\nPara obter máis información, contacta co administrador."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Outorgaches permiso a unha aplicación para configurar unha conexión VPN.\n\nEsta aplicación pode supervisar a túa actividade na rede, incluídos os correos electrónicos, as aplicacións e os sitios web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> xestiona o teu perfil de traballo.\n\nO administrador pode controlar a túa actividade na rede, mesmo os correos electrónicos, as aplicacións e os sitios web.\n\nPara obter máis información, ponte en contacto co administrador.\n\nTamén estás conectado a unha VPN, que pode controlar a túa actividade na rede."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"O teu pai ou nai xestiona este dispositivo. O teu pai ou nai pode ver e xestionar información como as aplicacións que usas, a túa localización e o tempo diante da pantalla."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Estás conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode controlar a túa actividade na rede, mesmo os correos electrónicos, as aplicacións e os sitios web."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Estás conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode supervisar a túa actividade persoal na rede, incluídos os correos electrónicos, as aplicacións e os sitios web."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Queres seguir mostrando as notificacións desta aplicación?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silenciosas"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Configuración predeterminada"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Burbulla"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sen son nin vibración"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sen son nin vibración, e aparecen máis abaixo na sección de conversas"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configuración"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non admite funcións de conversa"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Non hai burbullas recentes"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"As burbullas recentes e ignoradas aparecerán aquí."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificacións non se poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquí non se pode configurar este grupo de notificacións"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificación mediante proxy"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Servizos do dispositivo"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sen título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toca o botón para reiniciar esta aplicación e abrila en pantalla completa."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Configuración das burbullas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Mostrar menú adicional"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Engadir de novo á pilla"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Xestionar"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> e <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> máis"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Mover á parte super. esquerda"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Mover á parte superior dereita"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Mover á parte infer. esquerda"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Mover á parte inferior dereita"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Ignorar burbulla"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Non mostrar a conversa como burbulla"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatear usando burbullas"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"As conversas novas aparecen como iconas flotantes ou burbullas. Toca para abrir a burbulla e arrastra para movela."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla as burbullas"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Para desactivar as burbullas nesta aplicación, toca Xestionar"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Actualizouse a navegación do sistema. Para facer cambios, vai a Configuración."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Para actualizar a navegación do sistema, vai a Configuración"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo novo"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Produciuse un problema ao ler o medidor da batería"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca para obter máis información"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings_tv.xml b/packages/SystemUI/res/values-gl/strings_tv.xml
index 123a86e..6c48267 100644
--- a/packages/SystemUI/res/values-gl/strings_tv.xml
+++ b/packages/SystemUI/res/values-gl/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Micrófono activo"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s accedeu ao teu micrófono"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 02c72db..44cb199d 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ફરીથી સ્ક્રીનશૉટ લેવાનો પ્રયાસ કરો"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"મર્યાદિત સ્ટોરેજ સ્પેસને કારણે સ્ક્રીનશૉટ સાચવી શકાતો નથી"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ઍપ્લિકેશન કે તમારી સંસ્થા દ્વારા સ્ક્રીનશૉટ લેવાની મંજૂરી નથી"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"સ્ક્રીનશૉટમાં ફેરફાર કરો"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"સ્ક્રીનશૉટ છોડી દો"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"સ્ક્રીનશૉટનો પ્રીવ્યૂ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"સ્ક્રીન રેકૉર્ડર"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"બૅટરી બે બાર."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"બૅટરી ત્રણ બાર."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"બૅટરી પૂર્ણ."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"બૅટરીની ટકાવારી અજાણ છે."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"કોઈ ફોન નથી."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ફોન એક બાર."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ફોન બે બાર."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"સૂચના કાઢી નાખી."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"બબલ છોડી દેવાયો."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"નોટિફિકેશન શેડ."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ઝડપી સેટિંગ્સ."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"લૉક સ્ક્રીન."</string>
@@ -331,10 +339,10 @@
     <string name="notification_summary_message_format" msgid="5158219088501909966">"<xliff:g id="CONTACT_NAME">%1$s</xliff:g>: <xliff:g id="MESSAGE_CONTENT">%2$s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"સૂચનાઓની સેટિંગ્સ"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> સેટિંગ"</string>
-    <string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"સ્ક્રીન આપમેળે ફરશે."</string>
+    <string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"સ્ક્રીન ઑટોમૅટિક રીતે ફરશે."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"સ્ક્રીન લેન્ડસ્કેપ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"સ્ક્રીન પોટ્રેટ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
-    <string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"સ્ક્રીન હવે આપમેળે ફરશે."</string>
+    <string name="accessibility_rotation_lock_off_changed" msgid="5772498370935088261">"સ્ક્રીન હવે ઑટોમૅટિક રીતે ફરશે."</string>
     <string name="accessibility_rotation_lock_on_landscape_changed" msgid="5785739044300729592">"સ્ક્રીન હવે લેન્ડસ્કેપ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
     <string name="accessibility_rotation_lock_on_portrait_changed" msgid="5580170829728987989">"સ્ક્રીન હવે પોટ્રેટ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
     <string name="dessert_case" msgid="9104973640704357717">"ડેઝર્ટ કેસ"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"પ્રોફાઇલ મૉનિટર કરી શકાય છે"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"નેટવર્ક મૉનિટર કરી શકાય છે"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"નેટવર્ક મૉનિટર કરવામાં આવી શકે છે"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"આ ડિવાઇસ તમારા માતાપિતા દ્વારા મેનેજ કરવામાં આવે છે"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"તમારી સંસ્થા આ ડિવાઇસની માલિકી ધરાવે છે અને નેટવર્ક ટ્રાફિકનું નિરીક્ષણ કરી શકે છે"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે અને નેટવર્ક ટ્રાફિકનું નિરીક્ષણ કરી શકે છે"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે અને <xliff:g id="VPN_APP">%1$s</xliff:g>થી કનેક્ટ કરેલું છે"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN અક્ષમ કરો"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN ડિસ્કનેક્ટ કરો"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"નીતિઓ જુઓ"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"નિયંત્રણો જુઓ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે.\n\nતમારા IT વ્યવસ્થાપક સેટિંગ, કૉર્પોરેટ ઍક્સેસ, ઍપ, તમારા ડિવાઇસ સાથે સંકળાયેલો ડેટા અને તમારા ડિવાઇસની સ્થાન માહિતીનું નિરીક્ષણ તેમજ તેને મેનેજ કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા IT વ્યવસ્થાપકનો સંપર્ક કરો."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે.\n\nતમારા IT વ્યવસ્થાપક સેટિંગ, કૉર્પોરેટ ઍક્સેસ, ઍપ, તમારા ડિવાઇસ સાથે સંકળાયેલો ડેટા અને તમારા ડિવાઇસની સ્થાન માહિતીનું નિરીક્ષણ તેમજ તેને મેનેજ કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા IT વ્યવસ્થાપકનો સંપર્ક કરો."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"તમારી સંસ્થાએ આ ઉપકરણ પર પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કર્યું છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string>
@@ -554,7 +564,7 @@
     <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"તમે <xliff:g id="VPN_APP_0">%1$s</xliff:g> અને <xliff:g id="VPN_APP_1">%2$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટ સહિત તમારી નેટવર્ક પ્રવૃત્તિનું નિરીક્ષણ કરી શકે છે."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
     <string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"તમારી વ્યક્તિગત પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
-    <string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"તમારું ઉપકરણ <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે."</string>
+    <string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"તમારું ડિવાઇસ <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> દ્વારા મેનેજ થાય છે."</string>
     <string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, તમારા ઉપકરણનું સંચાલન કરવા માટે <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> નો ઉપયોગ કરે છે."</string>
     <string name="monitoring_description_do_body" msgid="7700878065625769970">"વ્યવસ્થાપક સેટિંગ્સ, કૉર્પોરેટ ઍક્સેસ, ઍપ્સ, તમારા ઉપકરણ સંબંદ્ધ ડેટા અને ઉપકરણની સ્થાન માહિતીનું નિરીક્ષણ અને સંચાલન કરી શકે છે."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
@@ -567,12 +577,13 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"તમારા વ્યવસ્થાપકે નેટવર્ક લૉગિંગ ચાલુ કર્યુ છે, જે તમારા ઉપકરણ પર ટ્રાફિકનું નિરીક્ષણ કરે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"તમે VPN કનેક્શન સેટ કરવા માટે ઍપ્લિકેશન પરવાનગી આપી.\n\nઆ ઍપ્લિકેશન ઇમેઇલ્સ, ઍપ્લિકેશનો અને વેબસાઇટ્સ સહિત તમારા ઉપકરણ અને નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"તમારી કાર્ય પ્રોફાઇલનું સંચાલન <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા કરવામાં આવે છે.\n\n તમારા વ્યવસ્થાપક ઇમેઇલ, ઍપ્લિકેશનો, અને વેબસાઇટો સહિતની તમારી કાર્ય નેટવર્ક પ્રવૃત્તિનું નિરીક્ષણ કરવામાં સક્ષમ છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો.\n\nતમે VPN સાથે પણ કનેક્ટ કરેલ છે, જે તમારી નેટવર્ક પ્રવૃત્તિનું નિરીક્ષણ કરી શકે છે."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"આ ડિવાઇસ તમારા માતાપિતા દ્વારા મેનેજ કરવામાં આવે છે. તમે જેનો ઉપયોગ કરો છો તે ઍપ, તમારું સ્થાન અને તમારા સ્ક્રીન સમય જેવી માહિતીને તમારા માતાપિતા જોઈ અને મેનેજ કરી શકે છે."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયા છો, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, ઍપ્લિકેશનો અને વેબસાઇટ્સ સહિતની તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
     <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, ઍપ્લિકેશનો અને વેબસાઇટ્સ સહિત તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
-    <string name="monitoring_description_app_work" msgid="3713084153786663662">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION">%2$s</xliff:g> સાથે કનેક્ટ થયેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિત તમારા કાર્યાલયના નેટવર્કની પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
-    <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nતમે <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> સાથે પણ કનેક્ટ કરેલું છે, જે તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
+    <string name="monitoring_description_app_work" msgid="3713084153786663662">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા મેનેજ થાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION">%2$s</xliff:g> સાથે કનેક્ટ થયેલ છે, જે ઇમેઇલ, ઍપ અને વેબસાઇટ સહિત તમારા કાર્યાલયના નેટવર્કની પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
+    <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા મેનેજ થાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ અને વેબસાઇટ સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nતમે <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> સાથે પણ કનેક્ટ કરેલું છે, જે તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent દ્વારા અનલૉક રાખેલું"</string>
     <string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"તમે ઉપકરણને મેન્યુઅલી અનલૉક કરશો નહીં ત્યાં સુધી તે લૉક રહેશે"</string>
     <string name="keyguard_indication_trust_unlocked_plugged_in" msgid="2323452175329362855">"<xliff:g id="KEYGUARD_INDICATION">%1$s</xliff:g>\n<xliff:g id="POWER_INDICATION">%2$s</xliff:g>"</string>
@@ -585,7 +596,7 @@
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"સાઉન્ડ સેટિંગ"</string>
     <string name="accessibility_volume_expand" msgid="7653070939304433603">"વિસ્તૃત કરો"</string>
     <string name="accessibility_volume_collapse" msgid="2746845391013829996">"સંકુચિત કરો"</string>
-    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"મીડિયામાં કૅપ્શન આપમેળે ઉમેરો"</string>
+    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"મીડિયામાં કૅપ્શન ઑટોમૅટિક રીતે ઉમેરો"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"કૅપ્શન ટિપ બંધ કરો"</string>
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"કૅપ્શન ઓવરલે"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"ચાલુ કરો"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"આ ઍપમાંથી નોટિફિકેશન બતાવવાનું ચાલુ રાખીએ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"સાઇલન્ટ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ડિફૉલ્ટ"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"બબલ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ઑટોમૅટિક રીતે"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"કોઈપણ સાઉન્ડ અથવા વાઇબ્રેશન નથી"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"કોઈપણ સાઉન્ડ અથવા વાઇબ્રેશન નથી અને વાતચીત વિભાગમાં તે વધુ નીચેની દિશાએ દેખાય છે"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"સેટિંગ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"પ્રાધાન્યતા"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> વાતચીતની સુવિધાઓને સપોર્ટ આપતી નથી"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"તાજેતરના કોઈ બબલ નથી"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"એકદમ નવા બબલ અને છોડી દીધેલા બબલ અહીં દેખાશે"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"નોટિફિકેશનના આ ગ્રૂપની ગોઠવણી અહીં કરી શકાશે નહીં"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"પ્રૉક્સી નોટિફિકેશન"</string>
@@ -903,11 +911,11 @@
     <string name="tuner_lock_screen" msgid="2267383813241144544">"લૉક સ્ક્રીન"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ફોન વધુ પડતી ગરમીને લીધે બંધ થઇ ગયો છે"</string>
     <string name="thermal_shutdown_message" msgid="6142269839066172984">"તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા આપમેળે બંધ થઇ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઇ શકે છે, જો તમે:\n • એવી ઍપ્લિકેશન વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિઓ, અથવા નેવિગેટ કરતી ઍપ્લિકેશનો)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"તમારો ફોન અત્યંત ગરમ હતો, તેથી તે ઠંડો થવા ઑટોમૅટિક રીતે બંધ થઈ ગયો છે. તમારો ફોન હવે સામાન્યપણે કાર્ય કરી રહ્યો છે.\n\nતમારો ફોન અત્યંત ગરમ થઈ શકે છે, જો તમે:\n • એવી ઍપ વાપરતા હો જે સંસાધન સઘન રીતે વાપરતી હોય (જેમ કે ગેમિંગ, વીડિયો, અથવા નેવિગેટ કરતી ઍપ)\n • મોટી ફાઇલો અપલોડ અથવા ડાઉનલોડ કરતા હો\n • તમારા ફોનનો ઉપયોગ ઉચ્ચ તાપમાનમાં કરતા હો"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"સારસંભાળના પગલાં જુઓ"</string>
     <string name="high_temp_title" msgid="2218333576838496100">"ફોન ગરમ થઈ રહ્યો છે"</string>
     <string name="high_temp_notif_message" msgid="1277346543068257549">"ફોન ઠંડો થાય ત્યાં સુધી અમુક સુવિધાઓ મર્યાદિત હોય છે.\nવધુ માહિતી માટે ટૅપ કરો"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"તમારો ફોન આપમેળે ઠંડો થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ફોનનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડો ધીમો ચાલે.\n\nતમારો ફોન ઠંડો થઈ જવા પર, તે સામાન્ય રીતે ચાલશે."</string>
+    <string name="high_temp_dialog_message" msgid="3793606072661253968">"તમારો ફોન ઑટોમૅટિક રીતે ઠંડો થવાનો પ્રયાસ કરશે. તમે હજી પણ તમારા ફોનનો ઉપયોગ કરી શકો છો, પરંતુ તે કદાચ થોડો ધીમો ચાલે.\n\nતમારો ફોન ઠંડો થઈ જવા પર, તે સામાન્ય રીતે ચાલશે."</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"સારસંભાળના પગલાં જુઓ"</string>
     <string name="high_temp_alarm_title" msgid="2359958549570161495">"ચાર્જરને અનપ્લગ કરો"</string>
     <string name="high_temp_alarm_notify_message" msgid="7186272817783835089">"આ ડિવાઇસને ચાર્જ કરવામાં કોઈ સમસ્યા છે. પાવર અડૅપ્ટર અનપ્લગ કરો અને કાળજી લેજો કદાચ કેબલ થોડો ગરમ થયો હોઈ શકે છે."</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"ડિવાઇસ સેવાઓ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"કોઈ શીર્ષક નથી"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"આ ઍપ ફરીથી ચાલુ કરવા માટે ટૅપ કરીને પૂર્ણ સ્ક્રીન કરો."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> બબલ માટેનાં સેટિંગ"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ઓવરફ્લો"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"સ્ટૅકમાં ફરી ઉમેરો"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"મેનેજ કરો"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> તરફથી <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> અને વધુ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> તરફથી <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ખસેડો"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ઉપર ડાબે ખસેડો"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ઉપર જમણે ખસેડો"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"નીચે ડાબે ખસેડો"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"નીચે જમણે ખસેડો"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"બબલને છોડી દો"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"વાતચીતને બબલ કરશો નહીં"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"બબલનો ઉપયોગ કરીને ચેટ કરો"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"નવી વાતચીત ફ્લોટિંગ આઇકન અથવા બબલ જેવી દેખાશે. બબલને ખોલવા માટે ટૅપ કરો. તેને ખસેડવા માટે ખેંચો."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"બબલને કોઈપણ સમયે નિયંત્રિત કરો"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"આ ઍપમાંથી બબલને બંધ કરવા માટે મેનેજ કરો પર ટૅપ કરો"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"સમજાઈ ગયું"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> સેટિંગ"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"સ્ટૅન્ડબાય"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"નવા ડિવાઇસ સાથે જોડાણ કરો"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"તમારું બૅટરી મીટર વાંચવામાં સમસ્યા આવી"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"વધુ માહિતી માટે ટૅપ કરો"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings_tv.xml b/packages/SystemUI/res/values-gu/strings_tv.xml
index 72a6803..09346fa 100644
--- a/packages/SystemUI/res/values-gu/strings_tv.xml
+++ b/packages/SystemUI/res/values-gu/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"માઇક્રોફોન સક્રિય છે"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$sએ તમારો માઇક્રોફોન ઍક્સેસ કર્યો હતો"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 3f497e7..89c1756 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रीनशॉट दोबारा लेने की कोशिश करें"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"मेमोरी कम होने की वजह से स्क्रीनशॉट सेव नहीं किया जा सका"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ऐप्लिकेशन या आपका संगठन स्क्रीनशॉट लेने की अनुमति नहीं देता"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"स्क्रीनशॉट में बदलाव करें"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"स्क्रीनशॉट खारिज करें"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रीनशॉट की झलक"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रिकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"बैटरी दो बार."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"बैटरी तीन बार."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"बैटरी पूरी है."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"इस बारे में जानकारी नहीं है कि अभी बैटरी कितने प्रतिशत चार्ज है."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"कोई फ़ोन नहीं."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"फ़ोन एक बार."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"फ़ोन दो बार."</string>
@@ -257,7 +266,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"सूचना खारिज की गई."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"बबल खारिज किया गया."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"सूचना शेड."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"त्वरित सेटिंग."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"लॉक स्क्रीन."</string>
@@ -522,6 +530,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफ़ाइल को मॉनीटर किया जा सकता है"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"नेटवर्क को मॉनीटर किया जा सकता है"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्क को मॉनिटर किया जा सकता है"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"इस डिवाइस का प्रबंधन आपके अभिभावक करते हैं"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है. आपका संगठन, नेटवर्क के ट्रैफ़िक की निगरानी कर सकता है"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> के पास है. आपका संगठन, नेटवर्क के ट्रैफ़िक की निगरानी कर सकता है"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है. इस डिवाइस को <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट किया गया है"</string>
@@ -546,6 +555,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN अक्षम करें"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN डिस्‍कनेक्‍ट करें"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतियां देखें"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"कंट्रोल देखें"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> के पास है.\n\nआपके संगठन का आईटी एडमिन कुछ चीज़ों की निगरानी और उन्हें प्रबंधित कर सकता है, जैसे कि सेटिंग, कॉर्पोरेट ऐक्सेस, ऐप्लिकेशन, आपके डिवाइस से जुड़ा डेटा, और आपके डिवाइस की जगह की जानकारी.\n\nज़्यादा जानकारी के लिए, अपने आईटी एडमिन से संपर्क करें."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है.\n\nआपके संगठन का आईटी एडमिन कुछ चीज़ों की निगरानी और उन्हें प्रबंधित कर सकता है, जैसे कि सेटिंग, कॉर्पोरेट ऐक्सेस, ऐप्लिकेशन, आपके डिवाइस से जुड़ा डेटा, और आपके डिवाइस की जगह की जानकारी.\n\nज़्यादा जानकारी के लिए, अपने आईटी एडमिन से संपर्क करें."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"आपके संगठन ने इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क पर ट्रेफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
@@ -569,6 +579,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"आपके एडमिन ने नेटवर्क लॉग करना चालू कर दिया है, जो आपके डिवाइस पर ट्रैफ़िक की निगरानी करता है.\n\nज़्यादा जानकारी के लिए अपने एडमिन से संपर्क करें."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"आपने किसी ऐप को VPN कनेक्‍शन सेट करने की अनुमति दी है.\n\nयह ऐप ईमेल, ऐप्‍स और सुरक्षित वेबसाइटों सहित आपके डिवाइस और नेटवर्क की गतिविधि की निगरानी कर सकता है."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> आपकी वर्क प्रोफ़ाइल को प्रबंधित करता है.\n\n आपका एडमिन ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nऔर जानकारी के लिए अपने एडमिन से संपर्क करें.\n\nआप ऐसे VPN से भी कनेक्‍ट हैं, जो आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"इस डिवाइस का प्रबंधन आपके अभिभावक करते हैं. अभिभावक आपके डिवाइस से जुड़ी जानकारी देख सकते हैं और उसे प्रबंधित कर सकते हैं. इनमें, आपके इस्तेमाल किए गए ऐप्लिकेशन, जगह की जानकारी, और डिवाइस के इस्तेमाल में बिताए गए समय जैसी जानकारी शामिल है."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"वीपीएन"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्‍ट हैं, जो ईमेल, ऐप्‍स और वेबसाइटों सहित आपकी व्‍यक्‍तिगत नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
@@ -711,7 +722,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"इस ऐप्लिकेशन से जुड़ी सूचनाएं दिखाना जारी रखें?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"आवाज़ के बिना सूचनाएं दिखाएं"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"डिफ़ॉल्ट"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"बबल"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"अपने-आप"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"किसी तरह की आवाज़ या वाइब्रेशन न हो"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"इससे किसी तरह की आवाज़ या वाइब्रेशन नहीं होता और बातचीत, सेक्शन में सबसे नीचे दिखती है"</string>
@@ -723,8 +733,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिंग"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर बातचीत की सुविधाएं काम नहीं करतीं"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"हाल ही के बबल्स मौजूद नहीं हैं"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"हाल ही के बबल्स और हटाए गए बबल्स यहां दिखेंगे"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"सूचनाओं के इस समूह को यहां कॉन्फ़िगर नहीं किया जा सकता"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"प्रॉक्सी सूचना"</string>
@@ -983,25 +991,7 @@
     <string name="device_services" msgid="1549944177856658705">"डिवाइस सेवाएं"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"कोई शीर्षक नहीं"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन चालू करने के लिए टैप करें."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> बबल्स की सेटिंग"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ओवरफ़्लो"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"स्टैक में वापस जोड़ें"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"प्रबंधित करें"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> से <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> और <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> अन्य ऐप्लिकेशन से <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ले जाएं"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"सबसे ऊपर बाईं ओर ले जाएं"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"सबसे ऊपर दाईं ओर ले जाएं"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"बाईं ओर सबसे नीचे ले जाएं"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"सबसे नीचे दाईं ओर ले जाएं"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"बबल खारिज करें"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"बातचीत को बबल न करें"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"बबल्स का इस्तेमाल करके चैट करें"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"नई बातचीत फ़्लोटिंग आइकॉन या बबल्स की तरह दिखेंगी. बबल को खोलने के लिए टैप करें. इसे एक जगह से दूसरी जगह ले जाने के लिए खींचें और छोड़ें."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"जब चाहें, बबल्स को कंट्रोल करें"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"इस ऐप्लिकेशन पर बबल्स को बंद करने के लिए \'प्रबंधित करें\' पर टैप करें"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ठीक है"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> की सेटिंग"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टैंडबाई"</string>
@@ -1091,4 +1081,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नया डिवाइस जोड़ें"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"आपके डिवाइस के बैटरी मीटर की रीडिंग लेने में समस्या आ रही है"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ज़्यादा जानकारी के लिए टैप करें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml
index 9282c3c4..df68864 100644
--- a/packages/SystemUI/res/values-hi/strings_tv.xml
+++ b/packages/SystemUI/res/values-hi/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"माइक्रोफ़ोन चालू है"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ने आपका माइक्रोफ़ोन ऐक्सेस किया था"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 9958a2c..40ebad5 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pokušajte ponovo napraviti snimku zaslona"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Zaslon nije snimljen zbog ograničenog prostora za pohranu"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ili vaša organizacija ne dopuštaju snimanje zaslona"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Uređivanje snimke zaslona"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Odbacivanje snimke zaslona"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimke zaslona"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač zaslona"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Baterija dva stupca."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Baterija tri stupca."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Baterija je puna."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Postotak baterije nije poznat."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nema telefona."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefonski signal jedan stupac."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefonski signal dva stupca."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Obavijest je odbačena."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Oblačić odbačen."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Zaslon obavijesti."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brze postavke."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključavanje zaslona."</string>
@@ -523,6 +531,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil se možda nadzire"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Mreža se možda nadzire"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Mreža se možda nadzire"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša je organizacija vlasnik ovog uređaja i može nadzirati mrežni promet"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlasnik je ovog uređaja i može nadzirati mrežni promet"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ovaj uređaj pripada vašoj organizaciji i povezan je s mrežom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -547,6 +556,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Onemogući VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Prekini vezu s VPN-om"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravila"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Prikaz kontrola"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš IT administrator može nadzirati postavke, korporacijski pristup, aplikacije, podatke o uređaju i lokaciji uređaja te upravljati njima.\n\nZa više informacija obratite se IT administratoru."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ovaj uređaj pripada vašoj organizaciji.\n\nVaš IT administrator može nadzirati postavke, korporacijski pristup, aplikacije, podatke o uređaju i lokaciji uređaja te upravljati njima.\n\nZa više informacija obratite se IT administratoru."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša je organizacija instalirala izdavač certifikata na ovom uređaju. Vaš sigurni mrežni promet možda se nadzire ili modificira."</string>
@@ -570,6 +580,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administrator je uključio mrežni zapisnik koji prati promet na vašem uređaju.\n\nViše informacija možete saznati od administratora."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Dali ste dopuštenje aplikaciji za postavljanje VPN veze.\n\nTa aplikacija može nadzirati vašu aktivnost na uređaju i mreži, uključujući e-poštu, aplikacije i web-lokacije."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Vašim radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVaš administrator može nadzirati vašu mrežnu aktivnost, uključujući e-poštu, aplikacije i web-lokacije.\n\nViše informacija možete saznati od administratora.\n\nPovezani ste i s VPN-om koji može nadzirati vašu mrežnu aktivnost."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja tvoj roditelj. Tvoj roditelj može vidjeti podatke kao što su aplikacije kojima se koristiš, lokaciju i vrijeme upotrebe te upravljati njima."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Povezani ste s aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g> koja može nadzirati vašu aktivnost na mreži, uključujući e-poruke, aplikacije i web-lokacije."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Povezani ste s aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g> koja može nadzirati vašu osobnu aktivnost na mreži, uključujući e-poštu, aplikacije i web-lokacije."</string>
@@ -712,7 +723,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Želite li da se obavijesti te aplikacije nastave prikazivati?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Bešumno"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Zadano"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Oblačić"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka ili vibracije"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka ili vibracije i prikazuje se pri dnu odjeljka razgovora"</string>
@@ -724,8 +734,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Postavke"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava značajke razgovora"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nema nedavnih oblačića"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Ovdje će se prikazivati nedavni i odbačeni oblačići"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Te se obavijesti ne mogu izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ta se grupa obavijesti ne može konfigurirati ovdje"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Obavijest poslana putem proxyja"</string>
@@ -986,25 +994,7 @@
     <string name="device_services" msgid="1549944177856658705">"Usluge uređaja"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Dodirnite da biste ponovo pokrenuli tu aplikaciju i prikazali je na cijelom zaslonu."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Postavke za oblačiće za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Dodatno"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodajte natrag u nizove"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Upravljanje"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g> i još <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Premjesti"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Premjesti u gornji lijevi kut"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Premjesti u gornji desni kut"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Premjesti u donji lijevi kut"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Premjestite u donji desni kut"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Odbaci oblačić"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Zaustavi razgovor u oblačićima"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Oblačići u chatu"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Novi razgovori pojavljuju se kao pomične ikone ili oblačići. Dodirnite za otvaranje oblačića. Povucite da biste ga premjestili."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljanje oblačićima u svakom trenutku"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljanje da biste isključili oblačiće iz ove aplikacije"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Shvaćam"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Ažurirana je navigacija sustavom. Možete je promijeniti u Postavkama."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Navigaciju sustavom možete ažurirati u Postavkama"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string>
@@ -1095,4 +1085,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem s očitavanjem mjerača baterije"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml
index 59dcd0c..b6bfbba 100644
--- a/packages/SystemUI/res/values-hr/strings_tv.xml
+++ b/packages/SystemUI/res/values-hr/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon aktivan"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacija %1$s pristupila je mikrofonu"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 0159ec6..050982e 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Próbálja meg újra elkészíteni a képernyőképet"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Nem menthet képernyőképet, mert kevés a tárhely"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Az alkalmazás vagy az Ön szervezete nem engedélyezi képernyőkép készítését"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Képernyőkép szerkesztése"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Képernyőkép elvetése"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Képernyőkép előnézete"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Képernyőrögzítő"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Képernyőrögzítés feldolgozása"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Akkumulátor két sáv."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Akkumulátor három sáv."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Akkumulátor feltöltve."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Az akkumulátor töltöttségi szintje ismeretlen."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nincs telefon."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon egy sáv."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon két sáv."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Értesítés elvetve."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Buborék elvetve."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Értesítési felület."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Gyorsbeállítások."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lezárási képernyő."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profilját felügyelhetik"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Lehet, hogy a hálózatot figyelik"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Lehet, hogy a hálózat felügyelt"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Az eszközt a szülőd felügyeli"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Az eszköz az Ön szervezetének tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ez az eszköz az Ön szervezetének tulajdonában van, és össze van kapcsolva a(z) <xliff:g id="VPN_APP">%1$s</xliff:g> alkalmazással"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN letiltása"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN-kapcsolat bontása"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Házirendek megtekintése"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Vezérlők megtekintése"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ez az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van.\n\nA rendszergazda figyelheti és kezelheti az eszköz beállításait, vállalati hozzáférését, alkalmazásait, adatait és helyadatait.\n\nHa további információra van szüksége, vegye fel a kapcsolatot a rendszergazdával."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ez az eszköz az Ön szervezetének tulajdonában van.\n\nA rendszergazda figyelheti és kezelheti az eszköz beállításait, vállalati hozzáférését, alkalmazásait, adatait és helyadatait.\n\nHa további információra van szüksége, vegye fel a kapcsolatot a rendszergazdával."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Szervezete tanúsítványkibocsátót telepített az eszközre. Ezáltal figyelhetik és befolyásolhatják az Ön biztonságos hálózati forgalmát."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"A rendszergazda bekapcsolta az eszköz forgalmát figyelő hálózati naplózást.\n\nHa további információra van szüksége, forduljon a rendszergazdához."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Engedélyezte egy alkalmazásnak, hogy VPN-kapcsolatot létesítsen.\n\nEz az alkalmazás (az e-mailekre, alkalmazásokra és a webhelyekre is kiterjedően) figyelemmel kísérheti az Ön eszközét és hálózati tevékenységét."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Munkaprofilját a(z) <xliff:g id="ORGANIZATION">%1$s</xliff:g> kezeli.\n\nA rendszergazda figyelheti hálózati tevékenységét, köztük az e-maileket, az alkalmazásokat és a webhelyeket.\n\nHa további információra van szüksége, forduljon a rendszergazdához.\n\nVPN-hez is kapcsolódik, amely szintén figyelheti hálózati tevékenységét."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Az eszközt a szülőd felügyeli. A szülőd megtekintheti és kezelheti például a használt alkalmazásokra, a tartózkodási helyre és a képernyőidőre vonatkozó adatokat."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Ön csatlakozik a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazáshoz, amely figyelheti hálózati tevékenységét, beleértve az e-maileket, az alkalmazásokat és a webhelyeket."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Csatlakoztatta a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazást, amely figyelheti személyes hálózati tevékenységét, beleértve az e-maileket, az alkalmazásokat és a webhelyeket."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Továbbra is megjelenjenek az alkalmazás értesítései?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Néma"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Alapértelmezett"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Buborék"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikus"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Nincs hang és rezgés"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nincs hang és rezgés, továbbá lejjebb jelenik meg a beszélgetések szakaszában"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Beállítások"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritás"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> nem támogatja a beszélgetési funkciókat"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nincsenek buborékok a közelmúltból"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"A legutóbbi és az elvetett buborékok itt jelennek majd meg"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ezeket az értesítéseket nem lehet módosítani."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Az értesítések jelen csoportját itt nem lehet beállítani"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Továbbított értesítés"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Eszközszolgáltatások"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nincs cím"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Koppintson az alkalmazás újraindításához és a teljes képernyős mód elindításához."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g>-buborékok beállításai"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"További elemeket tartalmazó menü"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Visszaküldés a verembe"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Kezelés"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> a(z) <xliff:g id="APP_NAME">%2$s</xliff:g> alkalmazásból és <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> további"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Áthelyezés"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Áthelyezés fel és balra"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Áthelyezés fel és jobbra"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Áthelyezés le és balra"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Áthelyezés le és jobbra"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Buborék elvetése"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ne jelenjen meg a beszélgetés buborékban"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Buborékokat használó csevegés"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Az új beszélgetések lebegő ikonként, vagyis buborékként jelennek meg. A buborék megnyitásához koppintson rá. Áthelyezéshez húzza a kívánt helyre."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Buborékok vezérlése bármikor"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"A Kezelés gombra koppintva kapcsolhatja ki az alkalmazásból származó buborékokat"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Értem"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> beállításai"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A rendszer-navigáció módja megváltozott. Módosításához nyissa meg a Beállításokat."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"A rendszer-navigációs lehetőségeket a Beállításokban módosíthatja"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Készenléti mód"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Új eszköz párosítása"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probléma merült fel az akkumulátor-töltésmérő olvasásakor"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Koppintással további információkat érhet el."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings_tv.xml b/packages/SystemUI/res/values-hu/strings_tv.xml
index 5482072..f34d7e0 100644
--- a/packages/SystemUI/res/values-hu/strings_tv.xml
+++ b/packages/SystemUI/res/values-hu/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"A mikrofon aktív"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"A(z) %1$s hozzáfért a mikrofonhoz"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1d80192..d8ea997 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Փորձեք նորից"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Չհաջողվեց պահել սքրինշոթը անբավարար հիշողության պատճառով"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում սքրինշոթի ստացումը"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Փոփոխել սքրինշոթը"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Փակել սքրինշոթը"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Սքրինշոթի նախադիտում"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Էկրանի տեսագրիչ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Էկրանի տեսագրության մշակում"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Մարտկոցի երկու գիծ:"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Մարտկոցի երեք գիծ:"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Մարտկոցը լիքն է:"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Մարտկոցի լիցքի մակարդակն անհայտ է։"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Հեռախոս չկա:"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Հեռախոսի մեկ գիծ:"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Հեռախոսի երկու գիծ:"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Ծանուցումը անտեսվեց:"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Ամպիկը փակվեց։"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Ծանուցումների վահանակ:"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Արագ կարգավորումներ:"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Էկրանի կողպում:"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Պրոֆիլը կարող է վերահսկվել"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Ցանցը կարող է վերահսկվել"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Ցանցը կարող է վերահսկվել"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Այս սարքը կառավարում է ձեր ծնողը"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ձեր կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"«<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>» կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Այս սարքը պատկանում է ձեր կազմակերպությանը և միացված է <xliff:g id="VPN_APP">%1$s</xliff:g> ցանցին"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Անջատել VPN-ը"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Անջատել VPN-ը"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Դիտել քաղաքականությունները"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Դիտել կառավարման տարրերը"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Այս սարքը պատկանում է «<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>» կազմակերպությանը։\n\nՁեր ՏՏ ադմինիստրատորը կարող է վերահսկել և կառավարել կարգավորումները, կորպորատիվ ռեսուրսներից օգտվելու թույլտվությունները, հավելվածները, սարքի հետ կապված տվյալները և սարքի տեղադրության տվյալները։\n\nԼրացուցիչ տեղեկությունների համար դիմեք ձեր ՏՏ ադմինիստրատորին։"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Այս սարքը պատկանում է ձեր կազմակերպությանը։\n\nՁեր ՏՏ ադմինիստրատորը կարող է վերահսկել և կառավարել կարգավորումները, կորպորատիվ ռեսուրսներից օգտվելու թույլտվությունները, հավելվածները, սարքի հետ կապված տվյալները և սարքի տեղադրության տվյալները։\n\nԼրացուցիչ տեղեկությունների համար դիմեք ձեր ՏՏ ադմինիստրատորին։"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ձեր կազմակերպությունը այս սարքում տեղադրել է վկայագրման կենտրոն։ Ձեր ցանցի ապահով թրաֆիկը կարող է վերահսկվել կամ փոփոխվել։"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Ձեր ադմինիստրատորը միացրել է ցանցային իրադարձությունների գրանցումը, որը վերահսկում է ձեր սարքի թրաֆիկը։\n\nԼրացուցիչ տեղեկություններ ստանալու համար դիմեք ձեր ադմինիստրատորին։"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Ինչ-որ հավելվածի թույլ եք տվել հաստատել VPN կապակցում:\n\nԱյդ հավելվածը կարող է վերահսկել ձեր սարքի և ցանցի գործունեությունը, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Ձեր աշխատանքային պրոֆիլի կառավարիչն է <xliff:g id="ORGANIZATION">%1$s</xliff:g> կազմակերպությունը։\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը, այդ թվում նաև էլփոստը, հավելվածները և կայքերը։\n\nԼրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին։\n\nԴուք կապակցված են նաև VPN ցանցին, որը կարող է վերահսկել ձեր ցանցային գործունեությունը։"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Այս սարքը կառավարում է ձեր ծնողը։ Նա կարող է տեսնել և կառավարել որոշակի տեղեկություններ, օրինակ՝ հավելվածները, որոնք դուք օգտագործում եք, ձեր տեղադրությունը և սարքի օգտագործման ժամանակը։"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Դուք կապակցված եք <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին, որը կարող է վերահսկել ձեր ցանցային գործունեությունը, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Դուք կապակցված եք <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին, որը կարող է վերահսկել անձնական ցանցում կատարած ձեր գործողությունները, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Ցուցադրե՞լ ծանուցումներ այս հավելվածից։"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Անձայն"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Կանխադրված"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Պղպջակ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Ավտոմատ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Առանց ձայնի կամ թրթռոցի"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Հայտնվում է զրույցների ցանկի ներքևում, առանց ձայնի և թրթռոցի"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Կարգավորումներ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Կարևոր"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը զրույցի գործառույթներ չի աջակցում"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Ամպիկներ չկան"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Այստեղ կցուցադրվեն վերջերս օգտագործված և փակված ամպիկները, որոնք կկարողանաք հեշտությամբ վերաբացել"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Այս ծանուցումները չեն կարող փոփոխվել:"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ծանուցումների տվյալ խումբը հնարավոր չէ կարգավորել այստեղ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Ծանուցումն ուղարկվել է պրոքսի սերվերի միջոցով"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Սարքի ծառայություններ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Անանուն"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Հպեք՝ հավելվածը վերագործարկելու և լիաէկրան ռեժիմին անցնելու համար։"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ի ամպիկների կարգավորումներ"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Լրացուցիչ ընտրացանկ"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Նորից ավելացնել զտիչներում"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Կառավարել"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>՝ <xliff:g id="APP_NAME">%2$s</xliff:g>-ից"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>` <xliff:g id="APP_NAME">%2$s</xliff:g>-ից ու ևս <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ամպիկ"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Տեղափոխել"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Տեղափոխել վերև՝ ձախ"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Տեղափոխել վերև՝ աջ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Տեղափոխել ներքև՝ ձախ"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Տեղափոխել ներքև՝ աջ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Փակել ամպիկը"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Զրույցը չցուցադրել ամպիկի տեսքով"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Զրույցի ամպիկներ"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Նոր զրույցները կհայտնվեն լողացող պատկերակների կամ ամպիկների տեսքով։ Հպեք՝ ամպիկը բացելու համար։ Քաշեք՝ այն տեղափոխելու համար։"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ամպիկների կարգավորումներ"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Հպեք «Կառավարել» կոճակին՝ այս հավելվածի ամպիկներն անջատելու համար։"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Եղավ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – կարգավորումներ"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Սպասման ռեժիմ"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Մարտկոցի ցուցիչը կարդալու հետ կապված խնդիր կա"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Հպեք՝ ավելին իմանալու համար"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings_tv.xml b/packages/SystemUI/res/values-hy/strings_tv.xml
index 4009335e..3ed3ecf 100644
--- a/packages/SystemUI/res/values-hy/strings_tv.xml
+++ b/packages/SystemUI/res/values-hy/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Խոսափողն ակտիվացված է"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s հավելվածն օգտագործել է ձեր խոսափողը"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 9aaf270..2a294c4 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Coba ambil screenshot lagi"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Tidak dapat menyimpan screenshot karena ruang penyimpanan terbatas"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Mengambil screenshot tidak diizinkan oleh aplikasi atau organisasi"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edit screenshot"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Menutup screenshot"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pratinjau screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Perekam Layar"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses perekaman layar"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Baterai dua batang."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Baterai tiga batang."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Baterai penuh."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Persentase baterai tidak diketahui."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Tidak dapat melakukan panggilan."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Ponsel satu batang."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Ponsel dua batang."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notifikasi disingkirkan."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Balon ditutup."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bayangan pemberitahuan."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Setelan cepat."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Layar kunci."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil dapat dipantau"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Jaringan mungkin dipantau"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Jaringan mungkin dipantau"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Perangkat ini dikelola oleh orang tua"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi Anda memiliki perangkat ini dan mungkin memantau traffic jaringan"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> memiliki perangkat ini dan mungkin memantau traffic jaringan"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Perangkat ini milik organisasi Anda dan terhubung ke <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Nonaktifkan VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Putuskan sambungan VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Lihat Kebijakan"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Lihat kontrol"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Perangkat ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdmin IT Anda dapat memantau dan mengelola setelan, akses perusahaan, aplikasi, data yang terkait dengan perangkat, dan informasi lokasi perangkat.\n\nUntuk informasi selengkapnya, hubungi admin IT Anda."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Perangkat ini milik organisasi Anda.\n\nAdmin IT Anda dapat memantau dan mengelola setelan, akses perusahaan, aplikasi, data yang terkait dengan perangkat, dan informasi lokasi perangkat.\n\nUntuk informasi selengkapnya, hubungi admin IT Anda."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasi Anda menginstal otoritas sertifikat di perangkat ini. Traffic jaringan aman Anda mungkin dipantau atau diubah."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Admin telah mengaktifkan pencatatan log jaringan, yang memantau traffic di perangkat.\n\nUntuk informasi selengkapnya, hubungi admin."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Anda memberikan izin kepada aplikasi untuk menyiapkan sambungan VPN.\n\nAplikasi ini ini dapat memantau aktivitas perangkat dan jaringan, termasuk email, aplikasi, dan situs web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Profil kerja dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdmin dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs web.\n\nUntuk informasi selengkapnya, hubungi admin.\n\nAnda juga tersambung ke VPN, yang dapat memantau aktivitas jaringan."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Perangkat ini dikelola oleh orang tua. Orang tua Anda dapat melihat dan mengelola informasi, seperti aplikasi yang digunakan, lokasi, dan waktu pemakaian perangkat."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Anda tersambung ke <xliff:g id="APPLICATION">%1$s</xliff:g>, yang dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Anda tersambung ke <xliff:g id="APPLICATION">%1$s</xliff:g>, yang dapat memantau aktivitas jaringan pribadi, termasuk email, aplikasi, dan situs web."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Terus tampilkan notifikasi dari aplikasi ini?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Senyap"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Balon"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatis"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Tidak ada suara atau getaran"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Tidak ada suara atau getaran dan ditampilkan lebih rendah di bagian percakapan"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Setelan"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritas"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak mendukung fitur percakapan"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Tidak ada balon baru-baru ini"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Balon yang baru dipakai dan balon yang telah ditutup akan muncul di sini"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Notifikasi ini tidak dapat diubah."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Grup notifikasi ini tidak dapat dikonfigurasi di sini"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notifikasi proxy"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Layanan Perangkat"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Tanpa judul"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Setelan untuk balon <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Tambahan"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Tambahkan kembali ke stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Kelola"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> dari <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> dari <xliff:g id="APP_NAME">%2$s</xliff:g> dan <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> lainnya"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Pindahkan"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Pindahkan ke kiri atas"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Pindahkan ke kanan atas"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Pindahkan ke kiri bawah"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Pindahkan ke kanan bawah"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Tutup balon"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Jangan gunakan percakapan balon"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat dalam tampilan balon"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Percakapan baru muncul sebagai ikon mengambang, atau balon. Ketuk untuk membuka balon. Tarik untuk memindahkannya."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrol balon kapan saja"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ketuk Kelola untuk menonaktifkan balon dari aplikasi ini"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Oke"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Setelan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem diupdate. Untuk melakukan perubahan, buka Setelan."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Buka Setelan untuk mengupdate navigasi sistem"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Siaga"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sambungkan perangkat baru"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor versi"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Terjadi masalah saat membaca indikator baterai"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketuk untuk informasi selengkapnya"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml
index 670f812..315796e 100644
--- a/packages/SystemUI/res/values-in/strings_tv.xml
+++ b/packages/SystemUI/res/values-in/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon Aktif"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s mengakses mikrofon"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index bf49e97..7c7902f 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prófaðu að taka skjámynd aftur"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Ekki tókst að vista skjámynd vegna takmarkaðs geymslupláss"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Forritið eða fyrirtækið þitt leyfir ekki skjámyndatöku"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Breyta skjámynd"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Loka skjámynd"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Breyta"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Breyta skjámynd"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Fletta"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Flettiskjáskot"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Loka skjámynd"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forskoðun skjámyndar"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skjáupptaka"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Vinnur úr skjáupptöku"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Tvö strik á rafhlöðu."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Þrjú strik á rafhlöðu."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Rafhlaða fullhlaðin."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Staða rafhlöðu óþekkt."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Ekkert símasamband."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Styrkur símasambands er eitt strik."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Styrkur símasambands er tvö strik."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Tilkynningu lokað."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Blöðru lokað."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Tilkynningasvæði."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Flýtistillingar."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lásskjár."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Hugsanlega er fylgst með þessu sniði"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Hugsanlega er fylgst með netinu"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Hugsanlega er fylgst með netinu"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Foreldri þitt stjórnar þessu tæki"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Fyrirtækið þitt á þetta tæki og fylgist hugsanlega með netumferð"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> á þetta tæki og fylgist hugsanlega með netumferð"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Þetta tæki tilheyrir fyrirtækinu þínu og er tengt við <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Slökkva á VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Aftengja VPN-net"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Skoða stefnur"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Skoða stýringar"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Þetta tæki tilheyrir fyrirtækinu þínu.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Fyrirtækið þitt setti upp CA-vottorð á þessu tæki. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Kerfisstjóri hefur kveikt á eftirliti netkerfa, sem fylgist með netumferð á tækinu þínu.\n\nHafðu samband við kerfisstjóra til að fá frekari upplýsingar."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Þú veittir forriti heimild til að koma á VPN-tengingu.\n\nÞetta forrit getur fylgst með virkni þinni í tækinu og á netinu, þar á meðal tölvupósti, forritum og vefsvæðum."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> stýrir vinnusniðinu þínu.\n\nKerfisstjórinn getur fylgst með virkni þinni á netinu, þ.m.t. tölvupósti, forritum og vefsvæðum.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar.\n\nÞú ert einnig með VPN-tengingu, sem getur fylgst með virkni þinni á netinu."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Foreldri þitt stjórnar þessu tæki. Foreldri þitt getur séð og stjórnað upplýsingum eins og forritunum sem þú notar, staðsetningu þinni og skjátímanum."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Þú ert með tengingu við <xliff:g id="APPLICATION">%1$s</xliff:g>, sem getur fylgst með netnotkun þinni, þ. á m. tölvupósti, forritum og vefsvæðum."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Þú ert með tengingu við <xliff:g id="APPLICATION">%1$s</xliff:g>, sem getur fylgst með persónulegri netnotkun þinni, þ. á m. tölvupósti, forritum og vefsvæðum."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Sýna áfram tilkynningar frá þessu forriti?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Hljóðlaust"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Sjálfgefið"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Blaðra"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Sjálfvirk"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ekkert hljóð eða titringur"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ekkert hljóð eða titringur og birtist neðar í samtalshluta"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Áfram"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Forgangur"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> styður ekki samtalseiginleika"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Engar nýlegar blöðrur"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Nýlegar blöðrur og blöðrur sem þú hefur lokað birtast hér"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ekki er hægt að breyta þessum tilkynningum."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ekki er hægt að stilla þessar tilkynningar hér"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Staðgengilstilkynning"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Tækjaþjónusta"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Enginn titill"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Ýttu til að endurræsa forritið og sýna það á öllum skjánum."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Stillingar fyrir blöðrur frá <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Yfirflæði"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Bæta aftur í stafla"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Stjórna"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> frá <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ frá <xliff:g id="APP_NAME">%2$s</xliff:g> og <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> í viðbót"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Færa"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Færa efst til vinstri"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Færa efst til hægri"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Færa neðst til vinstri"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Færðu neðst til hægri"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Loka blöðru"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ekki setja samtal í blöðru"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Spjalla með blöðrum"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Ný samtöl birtast sem fljótandi tákn eða blöðrur. Ýttu til að opna blöðru. Dragðu hana til að færa."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Hægt er að stjórna blöðrum hvenær sem er"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ýttu á „Stjórna“ til að slökkva á blöðrum frá þessu forriti"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ég skil"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Stillingar <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Kerfisstjórnun uppfærð. Þú getur breytt þessu í stillingunum."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Farðu í stillingar til að uppfæra kerfisstjórnun"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Biðstaða"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Para nýtt tæki"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Vandamál við að lesa stöðu rafhlöðu"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ýttu til að fá frekari upplýsingar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings_tv.xml b/packages/SystemUI/res/values-is/strings_tv.xml
index 27334af..30456d4 100644
--- a/packages/SystemUI/res/values-is/strings_tv.xml
+++ b/packages/SystemUI/res/values-is/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Hljóðnemi virkur"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s fékk aðgang að hljóðnemanum þínum"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 8e665ec..ef2d6cf 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Riprova ad acquisire lo screenshot"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Impossibile salvare lo screenshot a causa dello spazio di archiviazione limitato"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'acquisizione di screenshot non è consentita dall\'app o dall\'organizzazione"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Modifica screenshot"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ignora screenshot"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Anteprima screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Registrazione dello schermo"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaboraz. registraz. schermo"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Batteria: due barre."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Batteria: tre barre."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batteria carica."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentuale della batteria sconosciuta."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nessun telefono."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefono: una barra."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefono: due barre."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notifica eliminata."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Fumetto ignorato."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Area notifiche."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Impostazioni rapide."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Schermata di blocco."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Il profilo potrebbe essere monitorato"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"La rete potrebbe essere monitorata"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"La rete potrebbe essere monitorata"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Questo dispositivo è gestito da uno dei tuoi genitori"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Questo dispositivo appartiene alla tua organizzazione, che potrebbe monitorare il traffico di rete"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, che potrebbe monitorare il traffico di rete"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Questo dispositivo appartiene alla tua organizzazione ed è collegato a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Disattiva VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Scollega VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Visualizza le norme"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Visualizza controlli"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIl tuo amministratore IT può monitorare e gestire impostazioni, accesso aziendale, app, dati associati al dispositivo e informazioni sulla posizione del dispositivo.\n\nPer ulteriori informazioni, contatta il tuo amministratore IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Questo dispositivo appartiene alla tua organizzazione.\n\nIl tuo amministratore IT può monitorare e gestire impostazioni, accesso aziendale, app, dati associati al dispositivo e informazioni sulla posizione del dispositivo.\n\nPer ulteriori informazioni, contatta il tuo amministratore IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"La tua organizzazione ha installato un\'autorità di certificazione sul dispositivo. Il tuo traffico di rete protetto potrebbe essere monitorato o modificato."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"L\'amministratore ha attivato i log di rete, che consentono di monitorare il traffico sul dispositivo.\n\nPer ulteriori informazioni, contatta l\'amministratore."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Hai autorizzato l\'app a configurare una connessione VPN.\n\nQuesta app può monitorare il tuo dispositivo e l\'attività di rete, inclusi email, app e siti web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Il tuo profilo di lavoro è gestito da <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nL\'amministratore può monitorare la tua attività di rete, inclusi siti web, email e app.\n\nPer ulteriori informazioni, contatta l\'amministratore.\n\nSei inoltre connesso a una VPN, da cui è possibile monitorare la tua attività di rete."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Questo dispositivo è gestito da uno dei tuoi genitori. Il genitore può visualizzare e gestire informazioni quali le app che usi, la tua posizione e il tuo tempo di utilizzo."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Sei collegato a <xliff:g id="APPLICATION">%1$s</xliff:g>, da cui è possibile monitorare la tua attività di rete, inclusi siti web, email e app."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Sei connesso a <xliff:g id="APPLICATION">%1$s</xliff:g>, da cui è possibile monitorare la tua attività di rete personale, inclusi email, app e siti web."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Continuare a ricevere notifiche da questa app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Modalità silenziosa"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Modalità predefinita"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Fumetto"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatico"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Nessun suono o vibrazione"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nessun suono o vibrazione e appare più in basso nella sezione delle conversazioni"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Impostazioni"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorità"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non supporta le funzionalità delle conversazioni"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nessuna bolla recente"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Le bolle recenti e ignorate appariranno qui"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossibile modificare queste notifiche."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Qui non è possibile configurare questo gruppo di notifiche"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notifica inviata al proxy"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Servizi del dispositivo"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Senza titolo"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tocca per riavviare l\'app e passare a schermo intero."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Impostazioni per bolle <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Altre"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Aggiungi di nuovo all\'elenco"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gestisci"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> da <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> da <xliff:g id="APP_NAME">%2$s</xliff:g> e altre <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Sposta"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Sposta in alto a sinistra"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Sposta in alto a destra"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Sposta in basso a sinistra"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Sposta in basso a destra"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Ignora bolla"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Non mettere la conversazione nella bolla"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatta utilizzando le bolle"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Le nuove conversazioni vengono visualizzate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlla le bolle quando vuoi"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tocca Gestisci per disattivare le bolle dall\'app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Impostazioni <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigazione del sistema aggiornata. Per apportare modifiche, usa le Impostazioni."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Usa le Impostazioni per aggiornare la navigazione del sistema"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Accoppia nuovo dispositivo"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema durante la lettura dell\'indicatore di livello della batteria"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tocca per ulteriori informazioni"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml
index e0fce87..6c45e35 100644
--- a/packages/SystemUI/res/values-it/strings_tv.xml
+++ b/packages/SystemUI/res/values-it/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microfono attivo"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ha avuto accesso al tuo microfono"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 052b721..708032a 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"יש לנסות שוב לבצע צילום מסך"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"לא היה מספיק מקום לשמור את צילום המסך"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"האפליקציה או הארגון שלך אינם מתירים ליצור צילומי מסך"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"עריכת צילום מסך"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"סגירת צילום מסך"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"תצוגה מקדימה של צילום מסך"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"מקליט המסך"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"שני פסים של סוללה."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"שלושה פסים של סוללה."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"סוללה מלאה."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"אחוז טעינת הסוללה לא ידוע."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"אין טלפון."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"פס אחד של טלפון."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"שני פסים של טלפון."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"התראה נדחתה."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"הבועה נסגרה."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"לוח התראות."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"הגדרות מהירות."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"מסך נעילה."</string>
@@ -526,6 +534,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ייתכן שהפרופיל נתון למעקב"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ייתכן שהרשת נמצאת במעקב"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ייתכן שהרשת מנוטרת"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"מכשיר זה מנוהל על ידי ההורה שלך"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"הארגון שלך הוא הבעלים של מכשיר זה והוא עשוי לנטר את התנועה ברשת"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"הארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> הוא הבעלים של מכשיר זה והוא עשוי לנטר את התנועה ברשת"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"המכשיר הזה שייך לארגון שלך, והוא מחובר ל-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -550,6 +559,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"‏השבת VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"‏נתק את ה-VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"הצג מדיניות"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"לצפייה באמצעי בקרת ההורים"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"‏המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nמנהל ה-IT יכול לנטר ולנהל הגדרות, גישה ארגונית, אפליקציות, נתונים המשויכים למכשיר ומידע על מיקום המכשיר.\n\nלמידע נוסף, יש לפנות למנהל ה-IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"‏המכשיר הזה שייך לארגון שלך.\n\nמנהל ה-IT יכול לנטר ולנהל הגדרות, גישה ארגונית, אפליקציות, נתונים המשויכים למכשיר ומידע על מיקום המכשיר.\n\nלמידע נוסף, יש לפנות למנהל ה-IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"הארגון שלך התקין רשות אישורים במכשיר. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string>
@@ -573,6 +583,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"מנהל המערכת הפעיל את תכונת רישום התנועה ברשת, שמנטרת את תנועת הנתונים במכשיר.\n\nלמידע נוסף, צור קשר עם מנהל המערכת."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"‏נתת לאפליקציה כלשהי הרשאה להגדיר חיבור ‏VPN‏.\n\nהאפליקציה הזו יכולה לעקוב אחר הפעילות שלך ברשת ובמכשיר, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"‏פרופיל העבודה שלך מנוהל על-ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\n מנהל המערכת שלך יכול לעקוב אחרי הפעילות שלך ברשת, כולל פעילות באימייל, באפליקציות ובאתרים.\n\n למידע נוסף, צור קשר עם מנהל המערכת.\n\nבנוסף, אתה מחובר ל-VPN, שגם באמצעותו ניתן לעקוב אחרי הפעילות שלך ברשת."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"מכשיר זה מנוהל על ידי ההורה שלך. להורה שלך יש אפשרות לצפות בפרטים כמו האפליקציות שבשימוש, המיקום וזמן המסך שלך, ולנהל אותם."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת הפרטית, כולל הודעות אימייל, אפליקציות ואתרים."</string>
@@ -715,7 +726,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"שנמשיך להציג לך התראות מהאפליקציה הזאת?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"שקט"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ברירת מחדל"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"בועה"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"באופן אוטומטי"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ללא צליל או רטט"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ללא צליל או רטט ומופיעה למטה בקטע התראות השיחה"</string>
@@ -727,8 +737,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"הגדרות"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"עדיפות"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא תומכת בתכונות השיחה"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"אין בועות מהזמן האחרון"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"בועות אחרונות ובועות שנסגרו יופיעו כאן"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"לא ניתן לשנות את ההתראות האלה."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"‏התראה דרך שרת proxy"</string>
@@ -991,25 +999,7 @@
     <string name="device_services" msgid="1549944177856658705">"שירותים למכשיר"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ללא שם"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"צריך להקיש כדי להפעיל מחדש את האפליקציה הזו ולעבור למסך מלא."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"הגדרות בשביל בועות של <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"גלישה"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"הוספה בחזרה לערימה"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"ניהול"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> מהאפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> מ-<xliff:g id="APP_NAME">%2$s</xliff:g> ועוד <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"העברה"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"העברה לפינה השמאלית העליונה"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"העברה לפינה הימנית העליונה"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"העברה לפינה השמאלית התחתונה"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"העברה לפינה הימנית התחתונה"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"סגירת בועה"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"אין להציג בועות לשיחה"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"לדבר בבועות"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"שיחות חדשות מופיעות כסמלים צפים, או בועות. יש להקיש כדי לפתוח בועה. יש לגרור כדי להזיז אותה."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"שליטה בבועות, בכל זמן"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"יש להקיש על \'ניהול\' כדי להשבית את הבועות מהאפליקציה הזו"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"הבנתי"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"הגדרות <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"המתנה"</string>
@@ -1101,4 +1091,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"התאמה של מכשיר חדש"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‏מספר Build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‏מספר ה-Build הועתק ללוח."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"בעיה בקריאת מדדי הסוללה"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש להקיש כדי להציג מידע נוסף"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml
index 2bd86ef..f2d51f5a 100644
--- a/packages/SystemUI/res/values-iw/strings_tv.xml
+++ b/packages/SystemUI/res/values-iw/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"המיקרופון פעיל"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"‏%1$s קיבלה גישה למיקרופון שלך"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 7e64155f..be6f491 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"スクリーンショットを撮り直してください"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"空き容量が足りないため、スクリーンショットを保存できません"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"スクリーンショットの作成はアプリまたは組織で許可されていません"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"スクリーンショットの編集"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"スクリーンショットを閉じます"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"編集"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"スクリーンショットを編集します"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"スクロール"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"スクリーンショットをスクロールします"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"スクリーンショットを閉じます"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"スクリーンショットのプレビュー"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"スクリーン レコーダー"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"電池残量:レベル2"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"電池残量:レベル3"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"電池残量:満"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"電池残量は不明です。"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"電波状態:なし"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"電波状態:レベル1"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"電波状態:レベル2"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"通知が削除されました。"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ふきだしが非表示になっています。"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"通知シェード"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"クイック設定"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ロック画面"</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"プロファイルが監視されている可能性があります"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ネットワークが監視されている可能性があります"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ネットワークが監視されている可能性があります"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"このデバイスは保護者によって管理されています"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"これは組織が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"これは組織が所有するデバイスで、<xliff:g id="VPN_APP">%1$s</xliff:g> に接続しています"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPNを無効にする"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPNを切断"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ポリシーを見る"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"使用制限を表示"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスです。\n\nIT 管理者が、このデバイスに関連付けられている設定、コーポレート アクセス、アプリ、データのほか、デバイスの位置情報を監視、管理できます。\n\n詳しくは、IT 管理者にお問い合わせください。"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"これは組織が所有するデバイスです。\n\nIT 管理者が、このデバイスに関連付けられている設定、コーポレート アクセス、アプリ、データのほか、デバイスの位置情報を監視、管理できます。\n\n詳しくは、IT 管理者にお問い合わせください。"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"組織によってこのデバイスに認証局がインストールされました。保護されたネットワーク トラフィックが監視、変更される場合があります。"</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"管理者がネットワーク ログを有効にしているため、このデバイスのトラフィックは監視されています。\n\n詳しくは管理者にお問い合わせください。"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"アプリにVPN接続の設定を許可しました。\n\nこのアプリはあなたのデバイスやネットワークアクティビティ(メール、アプリ、ウェブサイトなど)を監視できます。"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"この仕事用プロファイルは、<xliff:g id="ORGANIZATION">%1$s</xliff:g> により管理されています。\n\n管理者は、このプロファイルでのネットワーク アクティビティ(メール、アプリ、ウェブサイトなど)を監視できます。\n\n詳しくは管理者にお問い合わせください。\n\nまた、VPN に接続しているため、このネットワークでのあなたのネットワーク アクティビティも監視されます。"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"このデバイスは保護者によって管理されています。使用しているアプリ、現在地、利用時間などの情報を保護者が確認、管理できます。"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"<xliff:g id="APPLICATION">%1$s</xliff:g> に接続しています。このアプリはあなたのネットワーク アクティビティ(メール、アプリ、ウェブサイトなど)を監視できます。"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"<xliff:g id="APPLICATION">%1$s</xliff:g>に接続しています。このアプリはあなたの個人のネットワークアクティビティ(メール、アプリ、ウェブサイトなど)を監視できます。"</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"このアプリからの通知を今後も表示しますか?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"サイレント"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"デフォルト"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"バブル"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"着信音もバイブレーションも無効です"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"着信音もバイブレーションも無効になり会話セクションの下に表示されます"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"設定"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> は会話機能に対応していません"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"最近閉じたバブルはありません"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"最近表示されたバブルや閉じたバブルが、ここに表示されます"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"これらの通知は変更できません。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"このグループの通知はここでは設定できません"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"代理通知"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"デバイス サービス"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"タイトルなし"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"タップしてこのアプリを再起動すると、全画面表示になります。"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> のバブルの設定"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"オーバーフロー"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"スタックに戻す"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"管理"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>(<xliff:g id="APP_NAME">%2$s</xliff:g>)"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>(<xliff:g id="APP_NAME">%2$s</xliff:g>)、他 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> 件"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"移動"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"左上に移動"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"右上に移動"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"左下に移動"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"右下に移動"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"バブルを閉じる"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"会話をバブルで表示しない"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"チャットでバブルを使う"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"新しい会話はフローティング アイコン(バブル)として表示されます。タップするとバブルが開きます。ドラッグしてバブルを移動できます。"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"いつでもバブルを管理"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"このアプリからのバブルを OFF にするには、[管理] をタップしてください"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> の設定"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"システム ナビゲーションを更新しました。変更するには [設定] に移動してください。"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"システム ナビゲーションを更新するには [設定] に移動してください"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"スタンバイ"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"電池残量の読み込み中に問題が発生しました"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"タップすると詳細が表示されます"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml
index 1e7d05b..c501865 100644
--- a/packages/SystemUI/res/values-ja/strings_tv.xml
+++ b/packages/SystemUI/res/values-ja/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"マイク: 有効"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s がマイクにアクセスしました"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 97aea29..272c3b4 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ხელახლა ცადეთ ეკრანის ანაბეჭდის გაკეთება"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"ეკრანის ანაბეჭდის შენახვა ვერ მოხერხდა შეზღუდული მეხსიერების გამო"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ეკრანის ანაბეჭდების შექმნა არ არის ნებადართული აპის ან თქვენი ორგანიზაციის მიერ"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ეკრანის ანაბეჭდის რედაქტირება"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ეკრანის ანაბეჭდის დახურვა"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ეკრანის ანაბეჭდის გადახედვა"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ეკრანის ჩამწერი"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ეკრანის ჩანაწერი მუშავდება"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ბატარეა ორ ზოლზე."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ბატარეა სამ ზოლზე."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ბატარეა სავსეა."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ბატარეის პროცენტული მაჩვენებელი უცნობია."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ტელეფონი არ არის."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ტელეფონის სიგნალი ერთ ზოლზეა."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ტელეფონის სიგნალი ორ ზოლზეა."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"შეტყობინება წაიშალა."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ბუშტი დაიხურა."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"შეტყობინებების ფარდა"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"სწრაფი პარამეტრები"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ეკრანის დაბლოკვა."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"შესაძლოა პროფილზე ხორციელდებოდეს მონიტორინგი"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"შესაძლოა ქსელზე ხორციელდება მონიტორინგი"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ქსელზე შესაძლოა მონიტორინგი ხორციელდებოდეს"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ამ მოწყობილობას თქვენი მშობელი მართავს"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და ის დაკავშირებულია <xliff:g id="VPN_APP">%1$s</xliff:g>-თან"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN-ის გაუქმება"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN-ის გათიშვა"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"წესების ნახვა"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"მართვის საშუალებების ნახვა"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ეს მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nთქვენს IT ადმინისტრატორს შეუძლია მოწყობილობასთან დაკავშირებული პარამეტრების, კორპორაციული წვდომის, აპებისა და მონაცემების (მათ შორის, თქვენი მოწყობილობის მდებარეობის ინფორმაციის) მონიტორინგი და მართვა.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს IT ადმინისტრატორს."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია.\n\nთქვენს IT ადმინისტრატორს შეუძლია მოწყობილობასთან დაკავშირებული პარამეტრების, კორპორაციული წვდომის, აპებისა და მონაცემების (მათ შორის, თქვენი მოწყობილობის მდებარეობის ინფორმაციის) მონიტორინგი და მართვა.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს IT ადმინისტრატორს."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"თქვენმა ორგანიზაციამ ამ მოწყობილობაზე სერტიფიცირების ორგანო დააინსტალირა. თქვენი ქსელის დაცული ტრაფიკი შეიძლება შეიცვალოს, ან მასზე მონიტორინგი განხორციელდეს."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"თქვენმა ადმინისტრატორმა ქსელის ჟურნალირება ჩართო, რომელიც თქვენი მოწყობილობის ტრაფიკის მონიტორინგს ახორციელებს.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"თქვენ მიეცით ნებართვა აპს, დააყენოს VPN კავშირი.\n\nამ აპს შეუძლია თქვენი მოწყობილობის და ქსელის აქტივობის, მათ შორის, ელფოსტის, აპებისა და ვებსაიტების მონიტორინგი."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"თქვენს სამსახურის პროფილს მართავს <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი ქსელის აქტივობის (მათ შორის, ელფოსტის, აპებისა და ვებსაიტების) მონიტორინგი.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს.\n\nგარდა ამისა, თქვენ დაკავშირებული ხართ VPN-თან, რომელსაც ასევე შეუძლია თქვენი ქსელის აქტივობის მონიტორინგი."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ამ მოწყობილობას თქვენი მშობელი მართავს. თქვენი მშობელი ხედავს და მართავს ისეთ ინფორმაციას, როგორიც არის თქვენ მიერ გამოყენებული აპები, თქვენი მდებარეობა და თქვენ მიერ ეკრანთან გატარებული დრო."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"თქვენ დაკავშირებული ხართ <xliff:g id="APPLICATION">%1$s</xliff:g>-თან, რომელსაც შეუძლია თქვენი ქსელის აქტივობის (მათ შორის, ელფოსტის, აპებისა და ვებსაიტების) მონიტორინგი."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"თქვენ დაუკავშირდით <xliff:g id="APPLICATION">%1$s</xliff:g>-ს, რომელსაც შეუძლია თქვენი პირადი ქსელის აქტივობის, მათ შორის, ელფოსტის, აპებისა და ვებსაიტების მონიტორინგი."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"გაგრძელდეს შეტყობინებათა ჩვენება ამ აპიდან?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ჩუმი"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ნაგულისხმევი"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"ბუშტი"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ავტომატური"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ხმისა და ვიბრაციის გარეშე"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ხმისა და ვიბრაციის გარეშე, ჩნდება მიმოწერების სექციის ქვედა ნაწილში"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"პარამეტრები"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"პრიორიტეტი"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს მიმოწერის ფუნქციების მხარდაჭერა"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ბოლო დროს გამოყენებული ბუშტები არ არის"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"აქ გამოჩნდება ბოლოდროინდელი ბუშტები და უარყოფილი ბუშტები"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ამ შეტყობინებების შეცვლა შეუძლებელია."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"შეტყობინებების ამ ჯგუფის კონფიგურირება აქ შეუძლებელია"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"პროქსირებული შეტყობინება"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"მოწყობილობის სერვისები"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"უსათაურო"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"შეეხეთ ამ აპის გადასატვირთად და გადადით სრულ ეკრანზე."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"პარამეტრები <xliff:g id="APP_NAME">%1$s</xliff:g> ბუშტებისთვის"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"გადავსება"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ისევ დამატება დასტაზე"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"მართვა"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g>-ისგან"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g>-დან და კიდევ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"გადატანა"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ზევით და მარცხნივ გადატანა"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"გადაანაცვლეთ ზევით და მარჯვნივ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ქვევით და მარცხნივ გადატანა"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"გადაანაცვ. ქვემოთ და მარჯვნივ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ბუშტის დახურვა"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"აიკრძალოს საუბრის ბუშტები"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"ჩეთი ბუშტების გამოყენებით"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"ახალი საუბრები გამოჩნდება როგორც მოტივტივე ხატულები ან ბუშტები. შეეხეთ ბუშტის გასახსნელად. გადაიტანეთ ჩავლებით."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ბუშტების ნებისმიერ დროს გაკონტროლება"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ამ აპის ბუშტების გამოსართავად შეეხეთ „მართვას“"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"გასაგებია"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-ის პარამეტრები"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"სისტემური ნავიგაცია განახლდა. ცვლილებების შესატანად გადადით პარამეტრებზე."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"სისტემური ნავიგაციის გასაახლებლად გადადით პარამეტრებზე"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"მოლოდინის რეჟიმი"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ახალი მოწყობილობის დაწყვილება"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"თქვენი ბატარეის მზომის წაკითხვასთან დაკავშირებით პრობლემა დაფიქსირდა"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"შეეხეთ მეტი ინფორმაციისთვის"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings_tv.xml b/packages/SystemUI/res/values-ka/strings_tv.xml
index 476658d..607f6ce 100644
--- a/packages/SystemUI/res/values-ka/strings_tv.xml
+++ b/packages/SystemUI/res/values-ka/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"მიკროფონი აქტიურია"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s-მა გამოიყენა თქვენი მიკროფონი"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index a6376e3..93af68c 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Қайта скриншот жасап көріңіз"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Жадтағы шектеулі бос орынға байланысты скриншот сақталмайды"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Қолданба немесе ұйым скриншоттар түсіруге рұқсат етпейді"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Скриншотты өзгерту"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Скриншотты жабу"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотты алдын ала қарау"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Экран жазғыш"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экран жазғыш бейнесін өңдеу"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Батарея екі баған."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Батарея үш баған."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Батарея толы."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарея зарядының мөлшері белгісіз."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Телефон жоқ."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Телефон бір баған."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Телефон екі баған."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Хабар алынып тасталды."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Қалқымалы анықтама өшірілді."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Хабарландыру тақтасы"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Жылдам параметрлер."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Бекіту экраны."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Профиль бақылануы мүмкін"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Желі бақылауда болуы мүмкін"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Желі бақылауда болуы мүмкін"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бұл құрылғыны ата-анаңыз басқарады."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Бұл құрылғы ұйымыңызға тиесілі және <xliff:g id="VPN_APP">%1$s</xliff:g> қолданбасына қосылған."</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN функциясын өшіру"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN желісін ажырату"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Саясаттарды көру"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Басқару элементтерін көру"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Бұл құрылғы <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ұйымына тиесілі.\n\nӘкімші параметрлерді, корпоративтік кіру құқығын, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасқан жері туралы ақпаратты бақылай және басқара алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Бұл құрылғы ұйымыңызға тиесілі.\n\nӘкімші параметрлерді, корпоративтік кіру құқығын, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасқан жері туралы ақпаратты бақылай және басқара алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ұйымыңыз осы құрылғыда сертификат орнатқан. Қорғалған желі трафигіңіз бақылануы немесе өзгертілуі мүмкін."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Әкімші құрылғыдағы трафикті қадағалау үшін желі журналын жүргізуді қосып қойған.\n\nТолығырақ ақпарат алу үшін әкімшімен хабарласыңыз."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Қолданбаға VPN байланысын орнату рұқсатын бердіңіз.\n\nБұл қолданба құрылғыңызды және желідегі белсенділігіңізді, соның ішінде электрондық пошталарды, қолданбаларды және веб-сайттарды бақылай алады."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Жұмыс профиліңізді <xliff:g id="ORGANIZATION">%1$s</xliff:g> басқарады.\n\nӘкімші желідегі белсенділігіңізді, соның ішінде электрондық пошталарды, қолданбаларды және вебсайттарды бақылай алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз.\n\nСондай-ақ сіз желідегі белсенділігіңізді бақылай алатын VPN желісіне қосылғансыз."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Бұл құрылғыны ата-анаңыз басқарады. Ата-анаңыз сіз пайдаланатын қолданбалар, геодерегіңіз және пайдалану уақытыңыз сияқты ақпаратты көре және басқара алады."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Сіз желідегі белсенділігіңізді, соның ішінде электрондық хабарларды, қолданбаларды және веб-сайттарды бақылай алатын <xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына қосылғансыз."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Сіз жеке желідегі белсенділігіңізді, соның ішінде электрондық пошталарды, қолданбаларды және веб-сайттарды бақылай алатын <xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына қосылғансыз."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Осы қолданбаның хабарландырулары көрсетілсін бе?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Дыбыссыз"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Әдепкі"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Көпіршік"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматты"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Дыбыс не діріл қолданылмайды"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дыбыс не діріл қолданылмайды, әңгімелер бөлімінің төмен жағында шығады"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Параметрлер"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Маңызды"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> әңгімелесу функцияларын қолдамайды."</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Жақындағы қалқыма хабарлар жоқ"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Соңғы және жабылған қалқыма хабарлар осы жерде көрсетіледі."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Мұндай хабарландырулар бұл жерде конфигурацияланбайды."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Прокси-сервер арқылы жіберілген хабарландыру"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Құрылғы қызметтері"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Атауы жоқ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Бұл қолданбаны қайта қосып, толық экранға өту үшін түртіңіз."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> қалқыма хабарларының параметрлері"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Қосымша мәзір"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Стекке қайта енгізу"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Басқару"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> жіберген хабарландыру: <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасы жіберген <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> және тағы <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Жылжыту"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Жоғарғы сол жаққа жылжыту"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Жоғары оң жаққа жылжыту"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Төменгі сол жаққа жылжыту"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Төменгі оң жаққа жылжыту"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Қалқымалы хабарды жабу"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Әңгіменің қалқыма хабары көрсетілмесін"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Қалқыма хабарлар арқылы сөйлесу"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Жаңа әңгімелер қалқыма белгішелер немесе хабарлар түрінде көрсетіледі. Қалқыма хабарды ашу үшін түртіңіз. Жылжыту үшін сүйреңіз."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Қалқыма хабарларды реттеу"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бұл қолданбадан қалқыма хабарларды өшіру үшін \"Басқару\" түймесін түртіңіз."</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түсінікті"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> параметрлері"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Күту режимі"</string>
@@ -1086,7 +1076,9 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> құрылғы таңдалды."</string>
     <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ажыратылған)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Қосылмады. Қайта қосылып көріңіз."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғыны жұптау"</string>
+    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғымен жұптау"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батарея зарядының дерегі алынбай жатыр"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Толығырақ ақпарат алу үшін түртіңіз."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings_tv.xml b/packages/SystemUI/res/values-kk/strings_tv.xml
index d4b3c73..2c72710 100644
--- a/packages/SystemUI/res/values-kk/strings_tv.xml
+++ b/packages/SystemUI/res/values-kk/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Микрофон қосулы"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s микрофоныңызды пайдаланды."</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index b8d2fa8..e6c5106c 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -28,15 +28,15 @@
     <string name="battery_low_percent_format" msgid="4276661262843170964">"នៅ​សល់ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"នៅសល់ <xliff:g id="PERCENTAGE">%1$s</xliff:g> អាច​ប្រើ​បាន​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀត​ផ្អែកលើ​ការប្រើប្រាស់​របស់អ្នក"</string>
     <string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"នៅសល់ <xliff:g id="PERCENTAGE">%1$s</xliff:g> អាច​ប្រើ​បាន​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀត"</string>
-    <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"នៅ​សល់ <xliff:g id="PERCENTAGE">%s</xliff:g> ។ កម្មវិធី​សន្សំ​ថ្ម​បានបើក។"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"នៅ​សល់ <xliff:g id="PERCENTAGE">%s</xliff:g>។ មុខងារ​សន្សំ​ថ្មត្រូវបានបើក។"</string>
     <string name="invalid_charger" msgid="4370074072117767416">"មិន​អាច​សាក​តាម USB បានទេ។ សូម​ប្រើ​ឆ្នាំង​សាក​ដែល​ភ្ជាប់​មក​ជាមួយ​ឧបករណ៍​របស់អ្នក។"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"មិន​អាច​សាក​តាម USB បានទេ"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"សូមប្រើ​ឆ្នាំង​សាក​ដែល​ភ្ជាប់​មក​ជាមួយ​ឧបករណ៍​របស់អ្នក"</string>
     <string name="battery_low_why" msgid="2056750982959359863">"ការកំណត់"</string>
-    <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"បើក​កម្មវិធី​សន្សំ​ថ្ម?"</string>
-    <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"អំពី​កម្មវិធីសន្សំថ្ម"</string>
+    <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"បើក​មុខងារ​សន្សំ​ថ្ម?"</string>
+    <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"អំពី​មុខងារ​សន្សំ​ថ្ម"</string>
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"បើក"</string>
-    <string name="battery_saver_start_action" msgid="4553256017945469937">"បើក​កម្មវិធី​សន្សំ​ថ្ម​"</string>
+    <string name="battery_saver_start_action" msgid="4553256017945469937">"បើក​មុខងារ​សន្សំ​ថ្ម"</string>
     <string name="status_bar_settings_settings_button" msgid="534331565185171556">"ការ​កំណត់"</string>
     <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"វ៉ាយហ្វាយ"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"បង្វិល​អេក្រង់​ស្វ័យ​ប្រវត្តិ"</string>
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"សាកល្បង​ថតរូបថត​អេក្រង់​ម្តងទៀត"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"មិនអាច​រក្សាទុក​រូបថតអេក្រង់​បានទេ ​ដោយសារ​ទំហំផ្ទុក​មានកម្រិតទាប"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ការថត​រូបអេក្រង់​មិនត្រូវ​បាន​អនុញ្ញាត​ដោយ​កម្មវិធី​នេះ ឬ​ស្ថាប័ន​របស់អ្នក"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"កែ​រូបថត​អេក្រង់"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ច្រានចោល​រូបថត​អេក្រង់"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ការមើល​រូបថត​អេក្រង់​សាកល្បង"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"មុខងារថត​អេក្រង់"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"កំពុង​ដំណើរការ​ការថតអេក្រង់"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ថ្ម​ពីរ​កាំ។"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ថ្ម​ទាំង​បី​​កាំ​។"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ថ្ម​ពេញ​ហើយ។"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"មិនដឹងអំពី​ភាគរយថ្មទេ។"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"គ្មាន​ទូរស័ព្ទ។"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"សេវា​ទូរស័ព្ទ​មួយ​កាំ។"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"សេវា​ទូរស័ព្ទ​ពីរ​កាំ។"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"បាន​បដិសេធ​ការ​ជូនដំណឹង"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"បានច្រានចោល​សារលេចឡើង។"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ពណ៌​ការ​ជូន​ដំណឹង"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ការ​កំណត់​រហ័ស។"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ចាក់​សោ​អេក្រង់។"</string>
@@ -498,9 +506,9 @@
     <string name="user_remove_user_title" msgid="9124124694835811874">"យកអ្នកប្រើចេញ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"កម្មវិធី និងទិន្នន័យទាំងអស់របស់អ្នកប្រើនេះនឹងត្រូវបានលុប។"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"យកចេញ"</string>
-    <string name="battery_saver_notification_title" msgid="8419266546034372562">"កម្មវិធីសន្សំថ្មបានបើក"</string>
+    <string name="battery_saver_notification_title" msgid="8419266546034372562">"មុខងារ​សន្សំ​ថ្មបានបើក"</string>
     <string name="battery_saver_notification_text" msgid="2617841636449016951">"ការ​បន្ថយ​ការ​ប្រតិបត្តិ និង​ទិន្នន័យ​ផ្ទៃ​ខាងក្រោយ"</string>
-    <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"បិទ​កម្មវិធី​សន្សំ​ថ្ម"</string>
+    <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"បិទ​មុខងារ​សន្សំ​ថ្ម"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹងមានសិទ្ធិ​ចូលប្រើ​ព័ត៌មាន​ទាំងអស់​ដែលអាច​មើលឃើញ​នៅលើ​អេក្រង់​របស់អ្នក ឬដែលចាក់​ពីឧបករណ៍​របស់អ្នក នៅពេល​កំពុង​ថត ឬភ្ជាប់។ ព័ត៌មាន​នេះមាន​ដូចជា ពាក្យសម្ងាត់ ព័ត៌មាន​លម្អិត​អំពីការទូទាត់​ប្រាក់ រូបថត សារ និង​សំឡេង​ដែល​អ្នកចាក់​ជាដើម។"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"សេវាកម្មដែល​ផ្ដល់​មុខងារ​នេះ​នឹងមាន​សិទ្ធិ​ចូលប្រើ​ព័ត៌មាន​ទាំងអស់​ដែល​អាច​មើលឃើញ​នៅលើ​អេក្រង់​របស់អ្នក ឬ​ដែលចាក់​ពីឧបករណ៍​របស់អ្នក នៅពេល​កំពុង​ថត ឬភ្ជាប់។ ព័ត៌មាន​នេះមាន​ដូចជា ពាក្យសម្ងាត់ ព័ត៌មាន​លម្អិត​អំពីការទូទាត់​ប្រាក់ រូបថត សារ និង​សំឡេង​ដែល​អ្នកចាក់​ជាដើម។"</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ចាប់ផ្ដើម​ថត ឬបញ្ជូន​មែនទេ?"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ប្រវត្តិរូបអាចត្រូវបានតាមដាន"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"បណ្ដាញ​អាច​ត្រូវ​បាន​ត្រួតពិនិត្យ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"បណ្ដាញអាចត្រូវបានត្រួតពិនិត្យ"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់មាតាបិតាអ្នក"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ស្ថាប័ន​របស់អ្នក​ជាម្ចាស់​ឧបករណ៍​នេះ ហើយ​អាចនឹង​តាមដាន​ចរាចរណ៍បណ្តាញ"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ជាម្ចាស់​ឧបករណ៍​នេះ ហើយ​អាចនឹង​តាមដាន​ចរាចរណ៍​បណ្តាញ"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់​ស្ថាប័នអ្នក និងត្រូវបានភ្ជាប់ទៅ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"បិទ VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"ផ្ដាច់ VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"មើល​គោលការណ៍"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"មើលការគ្រប់គ្រង"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ឧបករណ៍នេះ​ជាគឺកម្មសិទ្ធិ​របស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>។\n\nអ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក​អាចតាមដាន និងគ្រប់គ្រង​ការកំណត់ ការចូលប្រើជាលក្ខណៈក្រុមហ៊ុន កម្មវិធី ទិន្នន័យដែលពាក់ព័ន្ធ​នឹង​ឧបករណ៍​របស់អ្នក និងព័ត៌មាន​ទីតាំង​របស់​ឧបករណ៍​អ្នក។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម សូម​ទាក់ទង​អ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក។"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ឧបករណ៍នេះ​គឺជាកម្មសិទ្ធិ​របស់ស្ថាប័នអ្នក។\n\nអ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក​អាចតាមដាន និងគ្រប់គ្រង​ការកំណត់ ការចូលប្រើជាលក្ខណៈក្រុមហ៊ុន កម្មវិធី ទិន្នន័យដែលពាក់ព័ន្ធ​នឹង​ឧបករណ៍​របស់អ្នក និងព័ត៌មាន​ទីតាំង​របស់ឧបករណ៍​អ្នក។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម សូម​ទាក់ទង​អ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក។"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ស្ថាប័ន​របស់អ្នក​បានដំឡើង​អាជ្ញាធរវិញ្ញាបនបត្រនៅលើ​ឧបករណ៍​នេះ។ ចរាចរណ៍​បណ្តាញដែលមាន​សុវត្ថិភាព​របស់អ្នក​អាច​ត្រូវបាន​តាមដាន ឬ​កែសម្រួល។"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"អ្នក​គ្រប់គ្រង​របស់អ្នក​បាន​បើក​ការ​ធ្វើ​កំណត់ហេតុ​បណ្តាញ​ ដែល​នឹង​តាមដាន​ចរាចរណ៍​នៅលើ​ឧបករណ៍​របស់អ្នក។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម​ សូម​ទាក់ទង​អ្នក​គ្រប់គ្រង​របស់អ្នក។"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"អ្នកបានអនុញ្ញាតឲ្យកម្មវិធីដំឡើងការតភ្ជាប់ VPN។\n\nកម្មវិធីនេះអាចឃ្លាំមើលឧបករណ៍ និងសកម្មភាពបណ្តាញរបស់អ្នក រាប់បញ្ចូលទាំងអ៊ីមែល កម្មវិធី និងគេហទំព័រ។"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"កម្រង​ព័ត៌មាន​ការងារ​របស់អ្នក​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ។\n\nអ្នក​គ្រប់គ្រង​របស់អ្នក​មាន​លទ្ធភាព​តាមដាន​សកម្មភាព​នៅលើ​បណ្តាញ​របស់អ្នក រួមទាំងអ៊ីមែល កម្មវិធី និងគេហទំព័រ។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម​ សូម​ទាក់ទង​អ្នក​គ្រប់គ្រង​របស់អ្នក។\n\nអ្នក​ក៏​ត្រូវ​បាន​ភ្ជាប់​ទៅ VPN ដែល​អាច​តាមដាន​សកម្មភាព​នៅលើ​បណ្តាញ​របស់អ្នក​ផងដែរ។"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់មាតាបិតាអ្នក។ មាតាបិតារបស់អ្នកអាចមើល និងគ្រប់គ្រងព័ត៌មាន​ដូចជា កម្មវិធីដែលអ្នកប្រើ ទីតាំងរបស់អ្នក និងរយៈពេលប្រើប្រាស់ឧបករណ៍របស់អ្នកជាដើម។"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"អ្នកត្រូវ​បាន​តភ្ជាប់ទៅ <xliff:g id="APPLICATION">%1$s</xliff:g> ដែល​អាច​តាមដាន​សកម្មភាព​បណ្តាញ​របស់អ្នក រួមទាំង​អ៊ីមែល កម្មវិធី និង​គេហទំព័រ​ផងដែរ។"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"អ្នកត្រូវបានតភ្ជាប់ទៅ <xliff:g id="APPLICATION">%1$s</xliff:g> ដែលអាចឃ្លាំមើលសកម្មភាពបណ្តាញរបស់អ្នក រាប់បញ្ចូលទាំងអ៊ីមែល កម្មវិធី និងគេហទំព័រ។"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"បន្ត​បង្ហាញ​ការជូនដំណឹង​ពីកម្មវិធីនេះ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ស្ងាត់"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"លំនាំដើម"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"ពពុះ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ស្វ័យប្រវត្តិ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"គ្មាន​សំឡេង ឬការញ័រទេ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"គ្មានសំឡេង ឬការញ័រ និងការបង្ហាញ​កម្រិតទាបជាង​នេះនៅក្នុង​ផ្នែកសន្ទនាទេ"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ការកំណត់"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"អាទិភាព"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនអាចប្រើ​មុខងារ​សន្ទនា​បានទេ"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"មិនមាន​ពពុះ​ថ្មីៗ​ទេ"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"ពពុះថ្មីៗ​ និង​ពពុះដែលបានបិទ​​នឹង​បង្ហាញ​នៅទីនេះ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"មិនអាច​កំណត់​រចនាសម្ព័ន្ធ​ក្រុមការជូនដំណឹងនេះ​នៅទីនេះ​បានទេ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ការជូនដំណឹង​ជា​ប្រូកស៊ី"</string>
@@ -774,7 +782,7 @@
       <item quantity="one">%d នាទី</item>
     </plurals>
     <string name="battery_panel_title" msgid="5931157246673665963">"ការប្រើប្រាស់ថ្ម"</string>
-    <string name="battery_detail_charging_summary" msgid="8821202155297559706">"កម្មវិធីសន្សំថ្មមិនអាចប្រើបានអំឡុងពេលសាកថ្មទេ"</string>
+    <string name="battery_detail_charging_summary" msgid="8821202155297559706">"មិនអាចប្រើមុខងារ​សន្សំ​ថ្មបានទេក្នុងអំឡុងពេលសាកថ្ម"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"មុខងារ​សន្សំ​ថ្ម"</string>
     <string name="battery_detail_switch_summary" msgid="3668748557848025990">"កាត់បន្ថយប្រតិបត្តិការ និងទិន្នន័យផ្ទៃខាងក្រោយ"</string>
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ប៊ូតុង <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -962,11 +970,11 @@
     <string name="slice_permission_checkbox" msgid="4242888137592298523">"អនុញ្ញាត​ឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្ហាញ​ស្ថិតិ​ប្រើប្រាស់​ពី​កម្មវិធី​នានា"</string>
     <string name="slice_permission_allow" msgid="6340449521277951123">"អនុញ្ញាត"</string>
     <string name="slice_permission_deny" msgid="6870256451658176895">"បដិសេធ"</string>
-    <string name="auto_saver_title" msgid="6873691178754086596">"ចុច​ដើម្បី​កំណត់​កាលវិភាគ​កម្មវិធី​សន្សំ​ថ្ម"</string>
+    <string name="auto_saver_title" msgid="6873691178754086596">"ចុច​ដើម្បី​កំណត់​កាលវិភាគ​មុខងារ​សន្សំ​ថ្ម"</string>
     <string name="auto_saver_text" msgid="3214960308353838764">"បើក​នៅពេល​ថ្ម​ទំនងជា​អស់"</string>
     <string name="no_auto_saver_action" msgid="7467924389609773835">"ទេ អរគុណ"</string>
-    <string name="auto_saver_enabled_title" msgid="4294726198280286333">"កាលវិភាគ​កម្មវិធី​សន្សំ​ថ្ម​បាន​បើក​ហើយ"</string>
-    <string name="auto_saver_enabled_text" msgid="7889491183116752719">"កម្មវិធី​សន្សំ​ថ្ម​នឹង​បើក​ដោយ​ស្វ័យ​ប្រវត្តិ​ នៅពេល​ថ្ម​នៅ​សល់​តិច​ជាង <xliff:g id="PERCENTAGE">%d</xliff:g>%% ។"</string>
+    <string name="auto_saver_enabled_title" msgid="4294726198280286333">"កាលវិភាគ​មុខងារ​សន្សំ​ថ្មបាន​បើក​ហើយ"</string>
+    <string name="auto_saver_enabled_text" msgid="7889491183116752719">"មុខងារ​សន្សំ​ថ្មនឹង​បើក​ដោយ​ស្វ័យ​ប្រវត្តិ​ នៅពេល​ថ្ម​នៅ​សល់​តិច​ជាង <xliff:g id="PERCENTAGE">%d</xliff:g>%%។"</string>
     <string name="open_saver_setting_action" msgid="2111461909782935190">"ការកំណត់"</string>
     <string name="auto_saver_okay_action" msgid="7815925750741935386">"យល់ហើយ"</string>
     <string name="heap_dump_tile_name" msgid="2464189856478823046">"ចម្លង SysUI Heap"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"សេវាកម្មឧបករណ៍"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"គ្មាន​ចំណងជើង"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ចុចដើម្បី​ចាប់ផ្ដើម​កម្មវិធី​នេះឡើងវិញ រួចចូលប្រើ​ពេញអេក្រង់។"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"ការកំណត់​សម្រាប់​ពពុះ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ម៉ឺនុយបន្ថែម"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"បញ្ចូល​ទៅក្នុង​គំនរវិញ"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"គ្រប់គ្រង"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ពី <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ពី <xliff:g id="APP_NAME">%2$s</xliff:g> និង <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ទៀត"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ផ្លាស់ទី"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ផ្លាស់ទីទៅផ្នែកខាងលើខាងឆ្វេង"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ផ្លាស់ទីទៅផ្នែកខាងលើខាងស្ដាំ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ផ្លាស់ទីទៅផ្នែកខាងក្រោមខាងឆ្វេង​"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ផ្លាស់ទីទៅផ្នែកខាងក្រោម​ខាងស្ដាំ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ច្រានចោល​ពពុះ"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"កុំបង្ហាញ​ការសន្ទនា​ជាពពុះ"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"ជជែក​ដោយប្រើ​ពពុះ"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"ការសន្ទនាថ្មីៗ​បង្ហាញជា​​ពពុះ ឬរូបអណ្ដែត។ ចុច ដើម្បីបើក​ពពុះ។ អូស ដើម្បី​ផ្លាស់ទី​ពពុះនេះ។"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"គ្រប់គ្រង​​ពពុះ​បានគ្រប់ពេល"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ចុច \"គ្រប់គ្រង\" ដើម្បីបិទ​ពពុះពីកម្មវិធីនេះ"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"យល់ហើយ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"ការកំណត់ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"បានធ្វើ​បច្ចុប្បន្នភាព​ការរុករកក្នុង​ប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅ​កាន់ការកំណត់។"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ចូល​ទៅកាន់​ការកំណត់ ដើម្បី​ធ្វើបច្ចុប្បន្នភាព​ការរុករក​ក្នុង​ប្រព័ន្ធ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ផ្អាក​ដំណើរការ"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ផ្គូផ្គង​ឧបករណ៍ថ្មី"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខ​កំណែបង្កើត"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខ​កំណែបង្កើតទៅឃ្លីបបត។"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"មានបញ្ហាក្នុង​ការអាន​ឧបករណ៍រង្វាស់កម្រិតថ្មរបស់អ្នក"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ចុចដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings_tv.xml b/packages/SystemUI/res/values-km/strings_tv.xml
index 685a5e4..db3487e 100644
--- a/packages/SystemUI/res/values-km/strings_tv.xml
+++ b/packages/SystemUI/res/values-km/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"មីក្រូហ្វូន​កំពុង​ដំណើរការ"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s បានចូលប្រើ​មីក្រូហ្វូន​របស់អ្នក"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 5c502ac..70dac4c 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ಪುನಃ ತೆಗೆದುಕೊಳ್ಳಲು ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"ಪರಿಮಿತ ಸಂಗ್ರಹಣೆ ಸ್ಥಳದ ಕಾರಣದಿಂದಾಗಿ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ಅಪ್ಲಿಕೇಶನ್ ಅಥವಾ ಸಂಸ್ಥೆಯು ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ತೆಗೆಯುವುದನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ಸ್ಕ್ರೀನ್‍ಶಾಟ್‍ನ ಪೂರ್ವವೀಕ್ಷಣೆ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ಬ್ಯಾಟರಿ ಎರಡು ಪಟ್ಟಿಗಳು."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ಬ್ಯಾಟರಿ ಮೂರು ಪಟ್ಟಿಗಳು."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ಬ್ಯಾಟರಿ ಭರ್ತಿಯಾಗಿದೆ."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ಬ್ಯಾಟರಿ ಶೇಕಡಾವಾರು ತಿಳಿದಿಲ್ಲ."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ಯಾವುದೇ ಫೋನ್ ಇಲ್ಲ."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ಪೋನ್ ಒಂದು ಪಟ್ಟಿ."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ಫೋನ್ ಎರಡು ಪಟ್ಟಿಗಳು."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ಅಧಿಸೂಚನೆ ವಜಾಗೊಂಡಿದೆ."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ಬಬಲ್ ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ಅಧಿಸೂಚನೆಯ ಛಾಯೆ."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ಲಾಕ್‌ ಪರದೆ."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ಪ್ರೊಫೈಲ್ ಅನ್ನು ಪರಿವೀಕ್ಷಿಸಬಹುದಾಗಿದೆ"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ವೀಕ್ಷಿಸಬಹುದಾಗಿ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ವೀಕ್ಷಿಸಬಹುದಾಗಿರುತ್ತದೆ"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ ಮತ್ತು <xliff:g id="VPN_APP">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN ಸಂಪರ್ಕಕಡಿತಗೊಳಿಸಿ"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ಕಾರ್ಯನೀತಿಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ನಿಯಂತ್ರಣಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಗೆ ಸೇರಿದೆ.\n\nಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಕಾರ್ಪೊರೇಟ್ ಪ್ರವೇಶ, ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳದ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ.\n\nಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಕಾರ್ಪೊರೇಟ್ ಪ್ರವೇಶ, ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳದ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದಲ್ಲಿ ಪ್ರಮಾಣಪತ್ರ ಅಂಗೀಕಾರವನ್ನು ಸ್ಥಾಪಿಸಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷಿತ ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಅಥವಾ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ನೆಟ್‌ವರ್ಕ್ ಲಾಗಿಂಗ್ ಆನ್ ಮಾಡಿದ್ದಾರೆ. ಇದು ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಟ್ರಾಫಿಕ್ ಮೇಲೆ ನಿಗಾ ಇರಿಸುತ್ತದೆ.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗೆ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"ನೀವು VPN ಸಂಪರ್ಕ ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡಿರುವಿರಿ.\n\nಈ ಅಪ್ಲಿಕೇಶನ್ ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ವೆಬ್‌ಸೈಟ್‌ಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"ನಿಮ್ಮ ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು <xliff:g id="ORGANIZATION">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ.\n\nಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ವೆಬ್‌ಸೈಟ್‌ಗಳೂ ಸೇರಿದಂತೆ ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕ್‌ ಚಟುವಟಿಕೆಯ ಮೇಲೆ ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಗಾ ಇರಿಸಬಲ್ಲರು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ, ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ.\n\nಅಲ್ಲದೇ, ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕ್‌ ಚಟುವಟಿಕೆಯ ನಿಗಾ ವಹಿಸುವ VPN ಗೂ ಸಹ ನೀವು ಸಂಪರ್ಕಗೊಂಡಿರುವಿರಿ."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ. ನೀವು ಬಳಸುವ ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಸ್ಥಳ ಮತ್ತು ನಿಮ್ಮ ವೀಕ್ಷಣಾ ಅವಧಿಯಂತಹ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನೋಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"ನೀವು <xliff:g id="APPLICATION">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಿರಿ. ಇದು ನಿಮ್ಮ ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ವೆಬ್‌ಸೈಟ್‌ಗಳೂ ಸೇರಿದಂತೆ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"ನೀವು ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ವೆಬ್‌ಸೈಟ್‌ಗಳು ಸೇರಿದಂತೆ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದಾದ <xliff:g id="APPLICATION">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಿರಿ."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ನಿಶ್ಶಬ್ದ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ಡೀಫಾಲ್ಟ್"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"ಬಬಲ್"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ಸ್ವಯಂಚಾಲಿತ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ಯಾವುದೇ ಧ್ವನಿ ಅಥವಾ ವೈಬ್ರೇಷನ್‌ ಆಗುವುದಿಲ್ಲ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ಯಾವುದೇ ಧ್ವನಿ ಅಥವಾ ವೈಬ್ರೇಷನ್‌ ಆಗುವುದಿಲ್ಲ, ಸಂಭಾಷಣೆ ವಿಭಾಗದ ಕೆಳಭಾಗದಲ್ಲಿ ಗೋಚರಿಸುತ್ತದೆ"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ಆದ್ಯತೆ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"ಸಂವಾದ ಫೀಚರ್‌ಗಳನ್ನು <xliff:g id="APP_NAME">%1$s</xliff:g> ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ಯಾವುದೇ ಇತ್ತೀಚಿನ ಬಬಲ್ಸ್ ಇಲ್ಲ"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"ಇತ್ತೀಚಿನ ಬಬಲ್ಸ್ ಮತ್ತು ವಜಾಗೊಳಿಸಿದ ಬಬಲ್ಸ್ ಇಲ್ಲಿ ಗೋಚರಿಸುತ್ತವೆ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ಈ ಗುಂಪಿನ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇಲ್ಲಿ ಕಾನ್ಫಿಗರ್‌ ಮಾಡಲಾಗಿರುವುದಿಲ್ಲ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ಪ್ರಾಕ್ಸಿ ಮಾಡಿದ ಅಧಿಸೂಚನೆಗಳು"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"ಸಾಧನ ಸೇವೆಗಳು"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಬಬಲ್ಸ್‌ಗಾಗಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ಓವರ್‌ಫ್ಲೋ"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ಸ್ಟ್ಯಾಕ್‌ಗೆ ಪುನಃ ಸೇರಿಸಿ"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"ನಿರ್ವಹಿಸಿ"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> ಆ್ಯಪ್‌ನ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> ಮತ್ತು <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ಹೆಚ್ಚಿನವುಗಳ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ಸರಿಸಿ"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ಎಡ ಮೇಲ್ಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ಬಲ ಮೇಲ್ಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ಸ್ಕ್ರೀನ್‌ನ ಎಡ ಕೆಳಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ಕೆಳಗಿನ ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ಬಬಲ್ ವಜಾಗೊಳಿಸಿ"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"ಸಂಭಾಷಣೆಯನ್ನು ಬಬಲ್ ಮಾಡಬೇಡಿ"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"ಬಬಲ್ಸ್ ಬಳಸಿ ಚಾಟ್ ಮಾಡಿ"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"ಹೊಸ ಸಂಭಾಷಣೆಗಳು ತೇಲುವ ಐಕಾನ್‌ಗಳು ಅಥವಾ ಬಬಲ್ಸ್ ಆಗಿ ಗೋಚರಿಸುತ್ತವೆ. ಬಬಲ್ ತೆರೆಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಅದನ್ನು ಡ್ರ್ಯಾಗ್ ಮಾಡಲು ಎಳೆಯಿರಿ."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಬಬಲ್ಸ್ ಅನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ಈ ಆ್ಯಪ್‌ನಿಂದ ಬಬಲ್ಸ್ ಅನ್ನು ಆಫ್ ಮಾಡಲು ನಿರ್ವಹಿಸಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ಅರ್ಥವಾಯಿತು"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ್ ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ಸ್ಟ್ಯಾಂಡ್‌ಬೈ"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ನಿಮ್ಮ ಬ್ಯಾಟರಿ ಮೀಟರ್ ಓದುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings_tv.xml b/packages/SystemUI/res/values-kn/strings_tv.xml
index 7db0c70..6f7c31d 100644
--- a/packages/SystemUI/res/values-kn/strings_tv.xml
+++ b/packages/SystemUI/res/values-kn/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"ಮೈಕ್ರೋಫೋನ್‌ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿದೆ"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index cef5158..6db40c1 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"스크린샷을 다시 찍어 보세요."</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"저장용량이 부족하여 스크린샷을 저장할 수 없습니다"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"앱이나 조직에서 스크린샷 촬영을 허용하지 않습니다."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"스크린샷 수정"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"스크린샷 닫기"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"수정"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"스크린샷 수정"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"스크롤"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"스크롤 스크린샷"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"스크린샷 닫기"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"스크린샷 미리보기"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"화면 녹화"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"화면 녹화 처리 중"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"배터리 막대가 두 개입니다."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"배터리 막대가 세 개입니다."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"배터리 충전이 완료되었습니다."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"배터리 잔량을 알 수 없습니다."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"휴대전화의 신호가 없습니다."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"휴대전화 신호 막대가 하나입니다."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"휴대전화 신호 막대가 두 개입니다."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"알림이 제거되었습니다."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"대화창을 닫았습니다."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"알림 세부정보"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"빠른 설정"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"화면을 잠급니다."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"프로필이 모니터링될 수 있음"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"네트워크가 모니터링될 수 있음"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"네트워크가 모니터링될 수 있음"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"부모님이 관리하는 기기입니다."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"내 조직에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"내 조직에 속한 기기이며 <xliff:g id="VPN_APP">%1$s</xliff:g>에 연결되었습니다."</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN 사용 중지"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN 연결 해제"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"정책 보기"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"제어 기능 보기"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에 속한 기기입니다.\n\nIT 관리자가 설정, 기업 액세스, 앱, 기기와 연결된 데이터, 기기 위치 정보를 모니터링 및 관리할 수 있습니다.\n\n자세한 정보를 확인하려면 IT 관리자에게 문의하세요."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"내 조직에 속한 기기입니다.\n\nIT 관리자가 설정, 기업 액세스, 앱, 기기와 연결된 데이터, 기기 위치 정보를 모니터링 및 관리할 수 있습니다.\n\n자세한 정보를 확인하려면 IT 관리자에게 문의하세요."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"조직에서 이 기기에 인증기관을 설치했습니다. 보안 네트워크 트래픽을 모니터링 또는 수정할 수 있습니다."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"관리자가 기기에서 발생하는 트래픽을 모니터링하는 네트워크 로깅을 사용 설정했습니다.\n\n자세한 정보는 관리자에게 문의하세요."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"VPN 연결을 설정할 수 있는 권한을 앱에 부여했습니다.\n\n이 앱에서 이메일, 앱, 웹사이트와 같은 내 네트워크 활동 및 기기를 모니터링할 수 있습니다."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g>에서 직장 프로필을 관리합니다.\n\n관리자가 이메일, 앱, 웹사이트를 비롯한 네트워크 활동을 모니터링할 수 있습니다.\n\n자세한 정보는 관리자에게 문의하세요.\n\n또한 VPN에 연결되어 있으며, VPN에서 네트워크 활동을 모니터링할 수 있습니다."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"부모님이 관리하는 기기입니다. 부모님이 내가 사용하는 앱, 위치, 기기 사용 시간과 같은 정보를 보고 관리할 수 있습니다."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"<xliff:g id="APPLICATION">%1$s</xliff:g>에 연결되었습니다. 이 앱은 이메일, 앱, 웹사이트와 같은 내 네트워크 활동을 모니터링할 수 있습니다."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"<xliff:g id="APPLICATION">%1$s</xliff:g>에 연결되었습니다. 이 앱은 이메일, 앱, 웹사이트와 같은 내 네트워크 활동을 모니터링할 수 있습니다."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"이 앱의 알림을 계속 표시하시겠습니까?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"무음"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"기본값"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"버블"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"자동"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"소리 또는 진동 없음"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"소리나 진동이 울리지 않으며 대화 섹션 하단에 표시됨"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"설정"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"우선순위"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱은 대화 기능을 지원하지 않습니다."</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"최근 대화창 없음"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"최근 대화창과 내가 닫은 대화창이 여기에 표시됩니다."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"이 알림은 수정할 수 없습니다."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"이 알림 그룹은 여기에서 설정할 수 없습니다."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"프록시를 통한 알림"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"기기 서비스"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"제목 없음"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"탭하여 이 앱을 다시 시작하고 전체 화면으로 이동합니다."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> 대화창 설정"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"더보기"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"스택에 다시 추가"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"관리"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>의 <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> 외 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>개의 <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"이동"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"왼쪽 상단으로 이동"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"오른쪽 상단으로 이동"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"왼쪽 하단으로 이동"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"오른쪽 하단으로 이동"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"대화창 닫기"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"대화를 대화창으로 표시하지 않기"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"대화창으로 채팅하기"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"새로운 대화가 플로팅 아이콘인 대화창으로 표시됩니다. 대화창을 열려면 탭하세요. 드래그하여 이동할 수 있습니다."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"언제든지 대화창을 제어하세요"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"이 앱에서 대화창을 사용 중지하려면 관리를 탭하세요."</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"확인"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> 설정"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"대기"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"배터리 수준을 읽는 중에 문제가 발생함"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"탭하여 자세한 정보를 확인하세요."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml
index 1088970..5424a84 100644
--- a/packages/SystemUI/res/values-ko/strings_tv.xml
+++ b/packages/SystemUI/res/values-ko/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"마이크 사용 중"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s에서 내 마이크에 액세스했습니다."</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 572c3e7..8a06ed6 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Скриншотту кайра тартып көрүңүз"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Сактагычта бош орун аз болгондуктан, скриншот сакталбай жатат"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Скриншот тартууга колдонмо же ишканаңыз тыюу салган."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Скриншотту түзөтүү"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Скриншотту четке кагуу"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Түзөтүү"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Скриншотту түзөтүү"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Сыдыруу"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Скриншотту сыдырып кароо"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Скриншотту четке кагуу"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотту алдын ала көрүү"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string>
@@ -182,6 +185,9 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Эки таякча батарея."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Үч таякча батарея."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Батарея толук."</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Телефон сигналы жок."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Телефон сигналы бир таякча."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Телефон сигналы эки таякча."</string>
@@ -255,7 +261,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Эскертме өчүрүлдү."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Калкып чыкма билдирме жабылды."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Билдирмелер тактасы."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Тез тууралоолор."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Кулпуланган экран."</string>
@@ -520,6 +525,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Профилди көзөмөлдөсө болот"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Тармак көзөмөлдөнүшү мүмкүн"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Тармак көзөмөлдөнүшү мүмкүн"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бул түзмөктү ата-энең башкарат"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Бул түзмөк уюмуңузга таандык. Уюмуңуз тармактын трафигин көзөмөлдөй алат"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык. Уюм тармактын трафигин көзөмөлдөй алат"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Бул түзмөк уюмуңузга таандык жана <xliff:g id="VPN_APP">%1$s</xliff:g> колдонмосуна туташтырылган"</string>
@@ -544,6 +550,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN\'ди өчүрүү"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN\'ди ажыратуу"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Саясаттарды карап көрүү"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Башкаруу элементтерин көрүү"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык.\n\nIT администраторуңуз жөндөөлөрдү, корпоративдик мүмкүнчүлүктү, колдонмолорду, түзмөгүңүзгө байланыштуу дайын-даректерди жана түзмөгүңүздүн жайгашкан жери тууралуу маалыматты көзөмөлдөп жана башкара алат.\n\nТолугураак маалымат алуу үчүн, IT администраторуңузга кайрылыңыз."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Бул түзмөк уюмуңузга таандык.\n\nIT администраторуңуз жөндөөлөрдү, корпоративдик мүмкүнчүлүктү, колдонмолорду, түзмөгүңүзгө байланыштуу дайын-даректерди жана түзмөгүңүздүн жайгашкан жери тууралуу маалыматты көзөмөлдөп жана башкара алат.\n\nТолугураак маалымат алуу үчүн, IT администраторуңузга кайрылыңыз."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ишканаңыз бул түзмөккө тастыктоочу борборду орнотту. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
@@ -567,6 +574,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Администраторуңуз тармактын таржымалын алууну иштетти, андыктан түзмөгүңүздөгү трафик көзөмөлгө алынды.\n\nКеңири маалымат алуу үчүн администраторуңузга кайрылыңыз."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Колдонмого VPN туташуусун орнотууга уруксат бердиңиз.\n\nБул колдонмо түзмөгүңүздү жана электрондук почталар, колдонмолор жана вебсайттар сыяктуу тармактагы аракеттериңизди көзөмөлдөй алат."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Жумуш профилиңизди <xliff:g id="ORGANIZATION">%1$s</xliff:g> башкарат.\n\nАдминистраторуңуздун тармактагы аракетиңизди, анын ичинде электрондук почталар, колдонмолор жана вебсайттарды көзөмөлдөө мүмкүнчүлүгү бар.\n\nКөбүрөөк маалымат үчүн, администраторуңузга кайрылыңыз.\n\nСиз тармактагы жеке аракетиңизди көзөмөлдөй турган VPN\'ге да туташкансыз."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Бул түзмөктү ата-энең башкарат. Ата-энең сен иштеткен колдонмолорду, кайда жүргөнүңдү жана түзмөктү канча убакыт колдонгонуңду көрүп, башкарып турат."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Электрондук почта, колдонмолор жана вебсайттар сыяктуу тармактык аракеттерди көзөмөлдөй турган <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосуна туташып турасыз."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Электрондук почта, колдонмолор жана вебсайттар сыяктуу тармактагы жеке аракеттериңизди көзөмөлдөй турган <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосуна туташып турасыз."</string>
@@ -709,7 +717,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Бул колдонмонун билдирмелери көрсөтүлө берсинби?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Үнсүз"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Демейки"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Көбүк"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматтык"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Үнү чыкпайт жана дирилдебейт"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Үнү чыгып же дирилдебейт жана жазышуу бөлүмүнүн ылдый жагында көрүнөт"</string>
@@ -721,8 +728,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Жөндөөлөр"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Маанилүүлүгү"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> жазышуу функцияларын колдоого албайт"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Азырынча эч нерсе жок"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Акыркы жана жабылган калкып чыкма билдирмелер ушул жерде көрүнөт"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Бул билдирмелерди өзгөртүүгө болбойт."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Бул билдирмелердин тобун бул жерде конфигурациялоого болбойт"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Прокси билдирмеси"</string>
@@ -981,25 +986,7 @@
     <string name="device_services" msgid="1549944177856658705">"Түзмөк кызматтары"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Аталышы жок"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Бул колдонмону өчүрүп күйгүзүп, толук экранга өтүү үчүн, таптап коюңуз."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> калкып чыкма билдирмелер жөндөөлөрү"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Кошумча меню"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Кайра топтомго кошуу"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Башкаруу"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> колдонмосунан <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> жана дагы <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> колдонмодон <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Жылдыруу"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Жогорку сол жакка жылдыруу"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Жогорку оң жакка жылдырыңыз"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Төмөнкү сол жакка жылдыруу"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Төмөнкү оң жакка жылдырыңыз"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Калкып чыкма билдирмени жабуу"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Жазышууда калкып чыкма билдирмелер көрүнбөсүн"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Калкып чыкма билдирмелер аркылуу маектешүү"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Жаңы жазышуулар калкыма сүрөтчөлөр же калкып чыкма билдирмелер түрүндө көрүнөт. Калкып чыкма билдирмелерди ачуу үчүн таптап коюңуз. Жылдыруу үчүн сүйрөңүз."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн, \"Башкарууну\" басыңыз"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түшүндүм"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> жөндөөлөрү"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string>
@@ -1089,4 +1076,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңы түзмөктү жупташтыруу"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батареяңыздын кубаты аныкталбай жатат"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings_tv.xml b/packages/SystemUI/res/values-ky/strings_tv.xml
index b69b1c6..8d8cdda 100644
--- a/packages/SystemUI/res/values-ky/strings_tv.xml
+++ b/packages/SystemUI/res/values-ky/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Микрофон күйүк"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s микрофонуңузду колдонууда"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index b584dfe..e45f4eb 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -36,10 +36,6 @@
     <dimen name="volume_tool_tip_right_margin">136dp</dimen>
     <dimen name="volume_tool_tip_top_margin">12dp</dimen>
 
-    <!-- Padding between status bar and bubbles when displayed in expanded state, smaller
-         value in landscape since we have limited vertical space-->
-    <dimen name="bubble_padding_top">4dp</dimen>
-
     <dimen name="controls_activity_view_top_offset">25dp</dimen>
 
     <dimen name="biometric_dialog_button_negative_max_width">140dp</dimen>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 1cc1b4e..b92c2c1 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ກະລຸນາລອງຖ່າຍຮູບໜ້າຈໍອີກຄັ້ງ"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"ບໍ່ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້ເນື່ອງຈາກພື້ນທີ່ຈັດເກັບຂໍ້ມູນມີຈຳກັດ"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ແອັບ ຫຼື ອົງກອນຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ຖ່າຍຮູບໜ້າຈໍ"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ແກ້ໄຂຮູບໜ້າຈໍ"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ປິດຮູບໜ້າຈໍ"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"ແກ້ໄຂ"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"ແກ້ໄຂຮູບໜ້າຈໍ"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"ເລື່ອນ"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"ເລື່ອນຮູບໜ້າຈໍ"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ປິດຮູບໜ້າຈໍ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ຕົວຢ່າງຮູບໜ້າຈໍ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ໂປຣແກຣມບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ກຳລັງປະມວນຜົນການບັນທຶກໜ້າຈໍ"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ແບັດເຕີຣີສອງຂີດ."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ແບັດເຕີຣີສາມຂີດ."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ແບັດເຕີຣີເຕັມ."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ບໍ່ຮູ້ເປີເຊັນແບັດເຕີຣີ."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ບໍ່ມີໂທລະສັບ."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ສັນຍານນຶ່ງຂີດ."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ສັນຍານສອງຂີດ."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ປິດການແຈ້ງເຕືອນແລ້ວ."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ປິດ Bubble ໄສ້ແລ້ວ."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ໜ້າຈໍແຈ້ງເຕືອນ."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ການຕັ້ງຄ່າດ່ວນ."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ລັອກ​ໜ້າ​ຈໍ."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ໂປຣ​ໄຟລ໌​ອາດ​ຖືກ​ເຝົ້າ​ຕິດ​ຕາມ​ຢູ່"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"​ເຄືອ​ຂ່າຍ​ອາດ​ມີ​ການ​ເຝົ້າ​ຕິດ​ຕາມ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ການນຳໃຊ້ເຄືອຂ່າຍອາດມີການກວດສອບຕິດຕາມ"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍພໍ່ແມ່ຂອງທ່ານ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ອົງການຂອງທ່ານເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ ແລະ ເຊື່ອມຕໍ່ຫາ <xliff:g id="VPN_APP">%1$s</xliff:g> ແລ້ວ"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"ປິດ​ການ​ໃຊ້ VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"ຕັດ​ການ​ເຊື່ອມ​ຕໍ່ VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ເບິ່ງນະໂຍບາຍ"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ເບິ່ງການຄວບຄຸມ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານສາມາດເຝົ້າຕິດຕາມ ແລະ ຈັດການການຕັ້ງຄ່າ, ສິດເຂົ້າເຖິງອົງກອນ, ແອັບ, ຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນຂອງທ່ານໄດ້.\n\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ກະລຸນາຕິດຕໍ່ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານ."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ.\n\nຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານສາມາດເຝົ້າຕິດຕາມ ແລະ ຈັດການການຕັ້ງຄ່າ, ສິດເຂົ້າເຖິງອົງກອນ, ແອັບ, ຂໍ້ມູນທີ່ເຊື່ອມໂຍງກັບອຸປະກອນຂອງທ່ານໄດ້.\n\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ກະລຸນາຕິດຕໍ່ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານ."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ອົງກອນຂອງທ່ານຕິດຕັ້ງອຳນາດໃບຮັບຮອງໄວ້ໃນອຸປະກອນນີ້. ທຣາບຟິກເຄືອຂ່າຍທີ່ເຂົ້າລະຫັດໄວ້ຂອງທ່ານອາດຖືກຕິດຕາມ ຫຼື ແກ້ໄຂໄດ້."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Your admin has turned on network logging, which monitors traffic on your device.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"ທ່ານໄດ້ອະນຸຍາດໃຫ້ແອັບຕັ້ງການເຊື່ອມຕໍ່ VPN.\n\nແອັບນີ້ສາມາດຕິດຕາມການເຄື່ອນໄຫວຂອງອຸປະກອນ ແລະເຄືອຂ່າຍຂອງທ່ານ ເຊິ່ງລວມທັງອີເມວ, ແອັບ ແລະເວັບໄຊທ໌."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nYour admin is capable of monitoring your network activity including emails, apps, and websites.\n\nFor more information, contact your admin.\n\nYou\'re also connected to a VPN, which can monitor your network activity."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍພໍ່ແມ່ຂອງທ່ານ. ພໍ່ແມ່ຂອງທ່ານສາມາດເບິ່ງ ແລະ ຈັດການຂໍ້ມູນໄດ້ ເຊັ່ນ: ແອັບທີ່ທ່ານໃຊ້, ສະຖານທີ່ ແລະ ເວລາໜ້າຈໍຂອງທ່ານ."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"ທ່ານເຊື່ອມຕໍ່ຫາ <xliff:g id="APPLICATION">%1$s</xliff:g> ແລ້ວ, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານ ຮວມທັງອີເມວ, ແອັບ ແລະ ເວັບໄຊ."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"ທ່ານເຊື່ອມຕໍ່ກັບ <xliff:g id="APPLICATION">%1$s</xliff:g>, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍສ່ວນຕົວຂອງທ່ານ ລວມທັງອີເມວ, ​ແອັບ ແລະເວັບໄຊທ໌."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ສະແດງການແຈ້ງເຕືອນຈາກແອັບນີ້ຕໍ່ໄປບໍ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ປິດສຽງ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ຄ່າເລີ່ມຕົ້ນ"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"ຟອງ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ອັດຕະໂນມັດ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ບໍ່ມີສຽງ ຫຼື ການສັ່ນເຕືອນ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ບໍ່ມີສຽງ ຫຼື ການສັ່ນເຕືອນ ແລະ ປາກົດຢູ່ທາງລຸ່ມຂອງພາກສ່ວນການສົນທະນາ"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ຕັ້ງຄ່າ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ສຳຄັນ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ຮອງຮັບຄຸນສົມບັດການສົນທະນາ"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ບໍ່ມີຟອງຫຼ້າສຸດ"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"ຟອງຫຼ້າສຸດ ແລະ ຟອງທີ່ປິດໄປຈະປາກົດຢູ່ບ່ອນນີ້"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ບໍ່ສາມາດຕັ້ງຄ່າກຸ່ມການແຈ້ງເຕືອນນີ້ຢູ່ບ່ອນນີ້ໄດ້"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ການແຈ້ງເຕືອນແບບພຣັອກຊີ"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"ບໍລິການອຸປະກອນ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ບໍ່ມີຊື່"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ ແລະ ໃຊ້ແບບເຕັມຈໍ."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"ການຕັ້ງຄ່າສຳລັບຟອງ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ລົ້ນ"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ເພີ່ມກັບໄປຫາການວາງຊ້ອນກັນ"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"ຈັດການ"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ຈາກ <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ຈາກ <xliff:g id="APP_NAME">%2$s</xliff:g> ແລະ ອີກ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ຍ້າຍ"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ຍ້າຍຊ້າຍເທິງ"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ຍ້າຍຂວາເທິງ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ຍ້າຍຊ້າຍລຸ່ມ"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ຍ້າຍຂວາລຸ່ມ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ປິດຟອງໄວ້"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"ຢ່າໃຊ້ຟອງໃນການສົນທະນາ"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"ສົນທະນາໂດຍໃຊ້ຟອງ"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"ການສົນທະນາໃໝ່ຈະປາກົດເປັນໄອຄອນ ຫຼື ຟອງແບບລອຍ. ແຕະເພື່ອເປີດຟອງ. ລາກເພື່ອຍ້າຍມັນ."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ຄວບຄຸມຟອງຕອນໃດກໍໄດ້"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ແຕະຈັດການ ເພື່ອປິດຟອງຈາກແອັບນີ້"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ເຂົ້າໃຈແລ້ວ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"ການຕັ້ງຄ່າ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ອັບເດດການນຳທາງລະບົບແລ້ວ. ເພື່ອປ່ຽນແປງ, ກະລຸນາໄປທີ່ການຕັ້ງຄ່າ."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ໄປທີ່ການຕັ້ງຄ່າເພື່ອອັບເດດການນຳທາງລະບົບ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ສະແຕນບາຍ"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ຈັບຄູ່ອຸປະກອນໃໝ່"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ເກີດບັນຫາໃນການອ່ານຕົວວັດແທກແບັດເຕີຣີຂອງທ່ານ"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings_tv.xml b/packages/SystemUI/res/values-lo/strings_tv.xml
index 056612e..37025a7 100644
--- a/packages/SystemUI/res/values-lo/strings_tv.xml
+++ b/packages/SystemUI/res/values-lo/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"ໄມໂຄຣໂຟນເປີດໃຊ້ຢູ່"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ເຂົ້າເຖິງໄມໂຄຣໂຟນຂອງທ່ານແລ້ວ"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 152a532..cac9cf1 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pabandykite padaryti ekrano kopiją dar kartą"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Negalima išsaugoti ekrano kopijos dėl ribotos saugyklos vietos"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Jūsų organizacijoje arba naudojant šią programą neleidžiama daryti ekrano kopijų"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Redaguoti ekrano kopiją"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Praleisti ekrano kopiją"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Redaguoti"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Redaguoti ekrano kopiją"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Slinkti"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Viso puslapio ekrano kopija"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Praleisti ekrano kopiją"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekrano kopijos peržiūra"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrano vaizdo įrašytuvas"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Apdorojam. ekrano vaizdo įraš."</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Dvi akumuliatoriaus juostos."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Trys akumuliatoriaus juostos."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Akumuliatorius įkrautas."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akumuliatoriaus energija procentais nežinoma."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nėra telefono."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Viena telefono juosta."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Dvi telefono juostos."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Pranešimo atsisakyta."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Debesėlio atsisakyta."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Pranešimų gaubtas."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Spartieji nustatymai."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Užrakinimo ekranas."</string>
@@ -526,6 +529,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profilis gali būti stebimas"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Tinklas gali būti stebimas"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Tinklas gali būti stebimas"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šį įrenginį tvarko vienas iš tavo tėvų"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šis įrenginys priklauso jūsų organizacijai ir ji gali stebėti tinklo srautą"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir ji gali stebėti tinklo srautą"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Šis įrenginys priklauso jūsų organizacijai ir yra susietas su „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
@@ -550,6 +554,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Išjungti VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Atjungti VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Žr. politiką"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Rodinio valdikliai"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“.\n\nIT administratorius gali stebėti ir tvarkyti nustatymus, įmonės prieigą, programas, su įrenginiu susietus duomenis ir įrenginio vietovės informaciją.\n\nDaugiau informacijos galite gauti susisiekę su IT administratoriumi."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Šis įrenginys priklauso jūsų organizacijai.\n\nIT administratorius gali stebėti ir tvarkyti nustatymus, įmonės prieigą, programas, su įrenginiu susietus duomenis ir įrenginio vietovės informaciją.\n\nDaugiau informacijos galite gauti susisiekę su IT administratoriumi."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jūsų organizacija įdiegė šiame įrenginyje sertifikato įgaliojimą. Jūsų saugaus tinklo srautas gali būti stebimas arba keičiamas."</string>
@@ -573,6 +578,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administratorius įjungė tinklo duomenų įrašymą į žurnalą. Įjungus šią funkciją stebimas srautas jūsų įrenginyje.\n\nJei reikia daugiau informacijos, susisiekite su administratoriumi."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Suteikėte programai leidimą nustatyti VPN ryšį.\n\nŠi programa gali stebėti įrenginio ir tinklo veiklą, įskaitant el. laiškus, programas ir svetaines."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Jūsų darbo profilį tvarko „<xliff:g id="ORGANIZATION">%1$s</xliff:g>“.\n\nJūsų administratorius gali stebėti jūsų tinklo veiklą, įskaitant el. laiškus, programas ir svetaines.\n\nJei reikia daugiau informacijos, susisiekite su administratoriumi.\n\nTaip pat esate prisijungę prie VPN, kuris gali stebėti jūsų tinklo veiklą."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Šį įrenginį tvarko vienas iš tavo tėvų. Jis gali peržiūrėti ir tvarkyti informaciją, pvz., tavo naudojamas programas, vietovę ir įrenginio naudojimo laiką."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Esate prisijungę prie „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kuri gali stebėti tinklo veiklą, įskaitant el. laiškus, programas ir svetaines."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Esate prisijungę prie programos „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kuri gali stebėti asmeninio profilio tinklo veiklą, įskaitant el. laiškus, programas ir svetaines."</string>
@@ -715,7 +721,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Toliau rodyti iš šios programos gautus pranešimus?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Tylūs"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Numatytasis"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Debesėlis"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatinis"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Neskamba ir nevibruoja"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Neskamba, nevibruoja ir rodoma apatinėje pokalbių skilties dalyje"</string>
@@ -727,8 +732,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Nustatymai"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetiniai"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ nepalaiko pokalbių funkcijų"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nėra naujausių burbulų"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Naujausi ir atsisakyti burbulai bus rodomi čia"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Šių pranešimų keisti negalima."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Šios grupės pranešimai čia nekonfigūruojami"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Per tarpinį serverį gautas pranešimas"</string>
@@ -991,25 +994,7 @@
     <string name="device_services" msgid="1549944177856658705">"Įrenginio paslaugos"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nėra pavadinimo"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Palieskite, kad paleistumėte iš naujo šią programą arba įjungtumėte viso ekrano režimą."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ burbulų nustatymai"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Perpildymas"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Pridėti atgal į krūvą"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Tvarkyti"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ iš „<xliff:g id="APP_NAME">%2$s</xliff:g>“"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ iš „<xliff:g id="APP_NAME">%2$s</xliff:g>“ ir dar <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Perkelti"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Perkelti į viršų kairėje"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Perkelti į viršų dešinėje"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Perkelti į apačią kairėje"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Perkelti į apačią dešinėje"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Atsisakyti burbulo"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nerodyti pokalbio burbule"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Pokalbis naudojant burbulus"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nauji pokalbiai rodomi kaip slankiosios piktogramos arba burbulai. Palieskite, kad atidarytumėte burbulą. Vilkite, kad perkeltumėte."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bet kada valdyti burbulus"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Palieskite „Tvarkyti“, kad išjungtumėte burbulus šioje programoje"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Supratau"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ nustatymai"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemos naršymo funkcijos atnaujintos. Jei norite pakeisti, eikite į skiltį „Nustatymai“."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Eikite į skiltį „Nustatymai“, kad atnaujintumėte sistemos naršymo funkcijas"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Budėjimo laikas"</string>
@@ -1101,4 +1086,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Naujo įrenginio susiejimas"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nuskaitant akumuliatoriaus skaitiklį iškilo problema"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml
index 7739680..670d8ba5 100644
--- a/packages/SystemUI/res/values-lt/strings_tv.xml
+++ b/packages/SystemUI/res/values-lt/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofonas aktyvus"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"„%1$s“ pasiekė jūsų mikrofoną"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index ae67d0f..8c6676e 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Mēģiniet izveidot jaunu ekrānuzņēmumu."</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Nevar saglabāt ekrānuzņēmumu, jo krātuvē nepietiek vietas."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Lietotne vai jūsu organizācija neatļauj veikt ekrānuzņēmumus."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Rediģēt ekrānuzņēmumu"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Nerādīt ekrānuzņēmumu"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekrānuzņēmuma priekšskatījums"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrāna ierakstītājs"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekrāna ieraksta apstrāde"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Akumulators: divas joslas."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Akumulators: trīs joslas."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Akumulators ir pilnīgi uzlādēts."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akumulatora uzlādes līmenis procentos nav zināms."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nav tālruņa."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Tālrunis: viena josla."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Tālrunis: divas joslas."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Paziņojums netiek rādīts."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Burbulis ir noraidīts."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Paziņojumu panelis"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Ātrie iestatījumi"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Bloķēšanas ekrāns."</string>
@@ -523,6 +531,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profilu var pārraudzīt"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Iespējams, tīklā veiktās darbības tiek pārraudzītas."</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Var tikt pārraudzītas tīklā veiktās darbības."</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šo ierīci pārvalda viens no jūsu vecākiem."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šī ierīce pieder jūsu organizācijai, un jūsu organizācija var uzraudzīt tīkla datplūsmu."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Šī ierīce pieder organizācijai<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, un šī organizācija var uzraudzīt tīkla datplūsmu."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Šī ierīce pieder jūsu organizācijai un ir saistīta ar: <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
@@ -547,6 +556,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Atspējot VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Atvienot VPN tīklu"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Skatīt politikas"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Skatīt vadīklas"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Šī ierīce pieder organizācijai <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJūsu IT administrators var pārraudzīt un pārvaldīt iestatījumus, korporatīvo piekļuvi, lietotnes, ar ierīci saistītos datus un ierīces atrašanās vietas informāciju.\n\nLai iegūtu plašāku informāciju, sazinieties ar IT administratoru."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Šī ierīce pieder jūsu organizācijai.\n\nJūsu IT administrators var pārraudzīt un pārvaldīt iestatījumus, korporatīvo piekļuvi, lietotnes, ar ierīci saistītos datus un ierīces atrašanās vietas informāciju.\n\nLai iegūtu plašāku informāciju, sazinieties ar IT administratoru."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Jūsu organizācija instalēja sertifikātu šajā ierīcē. Jūsu drošā tīkla datplūsma var tikt uzraudzīta."</string>
@@ -570,6 +580,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administrators ir ieslēdzis tīkla reģistrēšanu, kuru izmanto, lai pārraudzītu datplūsmu jūsu ierīcē.\n\nLai iegūtu plašāku informāciju, sazinieties ar administratoru."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Jūs piešķīrāt lietotnei atļauju izveidot savienojumu ar VPN tīklu.\n\nŠī lietotne var pārraudzīt jūsu ierīcē un tīklā veiktās darbības, tostarp e-pasta ziņojumus, lietotnes un vietnes."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Jūsu darba profilu pārvalda <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrators var pārraudzīt jūsu darbības darba tīklā, tostarp e-pastu, lietotnes un vietnes.\n\nLai iegūtu plašāku informāciju, sazinieties ar administratoru.\n\nIr izveidots savienojums arī ar VPN, kurā var pārraudzīt jūsu darbības tīklā."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Šo ierīci pārvalda viens no jūsu vecākiem. Vecāki var skatīt un pārvaldīt tādu informāciju kā jūsu izmantotās lietotnes, atrašanās vieta un izmantošanas ilgums."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Ir izveidots savienojums ar lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, kura var pārraudzīt jūsu tīklā veiktās darbības, tostarp e-pasta ziņojumus, lietotnes un vietnes."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Ir izveidots savienojums ar lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, kura var pārraudzīt jūsu tīklā veiktās privātās darbības, tostarp e-pasta ziņojumus, lietotnes un vietnes."</string>
@@ -712,7 +723,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Vai turpināt rādīt paziņojumus no šīs lietotnes?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Klusums"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Noklusējums"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Burbulis"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automātiski"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Nav skaņas signāla vai vibrācijas"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nav skaņas signāla vai vibrācijas, kā arī atrodas tālāk sarunu sadaļā"</string>
@@ -724,8 +734,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Iestatījumi"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritārs"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> netiek atbalstītas sarunu funkcijas."</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nav nesen aizvērtu burbuļu"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Šeit būs redzami nesen rādītie burbuļi un aizvērtie burbuļi"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Šos paziņojumus nevar modificēt."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Šeit nevar konfigurēt šo paziņojumu grupu."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Starpniekservera paziņojums"</string>
@@ -986,25 +994,7 @@
     <string name="device_services" msgid="1549944177856658705">"Ierīces pakalpojumi"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nav nosaukuma"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Pieskarieties, lai restartētu šo lietotni un pārietu pilnekrāna režīmā."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> burbuļu iestatījumi"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Pārpilde"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Pievienot atpakaļ kopai"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Pārvaldīt"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> no: <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> no lietotnes “<xliff:g id="APP_NAME">%2$s</xliff:g>” un vēl <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Pārvietot"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Pārvietot augšpusē pa kreisi"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Pārvietot augšpusē pa labi"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Pārvietot apakšpusē pa kreisi"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Pārvietot apakšpusē pa labi"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Nerādīt burbuli"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nerādīt sarunu burbuļos"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Tērzēšana, izmantojot burbuļus"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Jaunas sarunas tiek rādītas kā peldošas ikonas vai burbuļi. Pieskarieties, lai atvērtu burbuli. Velciet, lai to pārvietotu."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Allaž pārvaldīt burbuļus"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Pieskarieties pogai “Pārvaldīt”, lai izslēgtu burbuļus no šīs lietotnes."</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Labi"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Lietotnes <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iestatījumi"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistēmas navigācija ir atjaunināta. Lai veiktu izmaiņas, atveriet iestatījumus."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Atveriet iestatījumus, lai atjauninātu sistēmas navigāciju"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gaidstāve"</string>
@@ -1095,4 +1085,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Savienošana pārī ar jaunu ierīci"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nevar iegūt informāciju par akumulatora uzlādes līmeni."</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Pieskarieties, lai iegūtu plašāku informāciju."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml
index 6b841d2..82a1a0a 100644
--- a/packages/SystemUI/res/values-lv/strings_tv.xml
+++ b/packages/SystemUI/res/values-lv/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofons ir aktīvs"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Lietotne %1$s piekļuva jūsu mikrofonam"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index fca688d..c2803b4 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Повторно обидете се да направите слика од екранот"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Сликата од екранот не може да се зачува поради ограничена меморија"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Апликацијата или вашата организација не дозволува снимање слики од екранот"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Изменете ја сликата од екранот"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Отфрлете ја сликата од екранот"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Измени"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Изменете ја сликата од екранот"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Континуирана слика"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Континуирана слика од екранот"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Отфрлете ја сликата од екранот"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Преглед на слика од екранот"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Снимач на екран"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Се обработува снимка од екран"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Батерија две цртички."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Батерија три цртички."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Батеријата е полна."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Процентот на батеријата е непознат."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Нема сигнал."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Телефон една цртичка.."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Телефон две цртички."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Известувањето е отфрлено."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Балончето е отфрлено."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Панел за известување"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брзи поставки."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Заклучи екран."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Профилот можеби се следи"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Мрежата може да се следи"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Мрежата може да се следи"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Родителот управува со уредов"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацијата е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Уредов е во сопственост на организацијата и е поврзан со <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Оневозможи ВПН"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Исклучи ВПН"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Прикажи „Политики“"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Прикажи ги контролите"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-администраторот може да ги следи и да управува со поставките, корпоративниот пристап, апликациите, податоците поврзани со уредот и податоците за локацијата на уредот.\n\nЗа повеќе информации, контактирајте со IT-администраторот."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Уредов е во сопственост на организацијата.\n\nIT-администраторот може да ги следи и да управува со поставките, корпоративниот пристап, апликациите, податоците поврзани со уредот и податоците за локацијата на уредот.\n\nЗа повеќе информации, контактирајте со IT-администраторот."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Вашата организација инсталираше авторитет за сертификат на уредов. Сообраќајот на вашата безбедна мрежа можно е да се следи или изменува."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Вашиот администратор вклучил евиденција на мрежата, што подразбира следење на сообраќајот на вашиот уред.\n\nЗа повеќе информации, контактирајте со администраторот."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Дозволивте апликацијата да постави поврзување преку ВПН.\n\nАпликацијата може да го следи уредот и активноста на мрежата, вклучувајќи ги е-пораките, апликациите и веб-локациите."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> управува со вашиот работен профил.\n\nАдминистратор е во можност да ја следи вашата активност на мрежата, вклучувајќи ги е-пораките, апликациите и веб-локациите.\n\nЗа повеќе информации, контактирајте со администраторот.\n\nYИсто така, поврзани сте на VPN којашто може да ја следи вашата активност на мрежата."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Родителот управува со уредов. Родителот може да прегледува и управува со податоците, како што се апликациите што ги користите, вашата локација и време поминато на уредот."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"ВПН"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Поврзани сте на <xliff:g id="APPLICATION">%1$s</xliff:g>, што може да ја следи вашата активност на мрежата, заедно со е-пораките, апликациите и веб-сајтовите."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Поврзани сте на <xliff:g id="APPLICATION">%1$s</xliff:g>, којашто може да ја следи вашата лична активност на мрежата, вклучувајќи ги е-пораките, апликациите и веб-локациите."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Дали да продолжат да се прикажуваат известувања од апликацијава?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Безгласно"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Стандардно"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Балонче"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматски"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звук или вибрации"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звук или вибрации и се појавува подолу во делот со разговори"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Поставки"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддржува функции за разговор"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Нема неодамнешни балончиња"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Неодамнешните и отфрлените балончиња ќе се појавуваат тука"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Овие известувања не може да се изменат"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Оваа група известувања не може да се конфигурира тука"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Известување преку прокси"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Услуги за уредот"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслов"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Допрете за да ја рестартирате апликацијава и да ја отворите на цел екран."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Поставки за балончињата за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Прелевање"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Додајте назад во stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Управувајте"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> од <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> од <xliff:g id="APP_NAME">%2$s</xliff:g> и уште <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Премести"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Премести горе лево"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Премести горе десно"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Премести долу лево"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Премести долу десно"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Отфрли балонче"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не прикажувај го разговорот во балончиња"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Разговор во балончиња"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Новите разговори ќе се појавуваат како лебдечки икони или балончиња. Допрете за отворање на балончето. Повлечете за да го преместите."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контролирајте ги балончињата во секое време"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Допрете „Управувајте“ за да ги исклучите балончињата од апликацијава"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Сфатив"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Поставки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Подготвеност"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спарете нов уред"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем при читањето на мерачот на батеријата"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Допрете за повеќе информации"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings_tv.xml b/packages/SystemUI/res/values-mk/strings_tv.xml
index a935cc4..17e7255 100644
--- a/packages/SystemUI/res/values-mk/strings_tv.xml
+++ b/packages/SystemUI/res/values-mk/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Микрофонот е активен"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s пристапи до вашиот микрофон"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index cd75761..5de8830 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"സ്‌ക്രീൻഷോട്ട് എടുക്കാൻ വീണ്ടും ശ്രമിക്കുക"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"സ്‌റ്റോറേജ് ഇടം പരിമിതമായതിനാൽ സ്‌ക്രീൻഷോട്ട് സംരക്ഷിക്കാനാകുന്നില്ല"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"സ്ക്രീൻഷോട്ടുകൾ എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"സ്ക്രീൻഷോട്ട് എഡിറ്റ് ചെയ്യുക"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"സ്ക്രീൻഷോട്ട് ഡിസ്‌മിസ് ചെയ്യുക"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"സ്‌ക്രീൻഷോട്ട് പ്രിവ്യു"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"സ്ക്രീൻ റെക്കോർഡർ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ബാറ്ററി രണ്ട് ബാർ."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ബാറ്ററി മൂന്ന് ബാർ."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ബാറ്ററി നിറഞ്ഞു."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ബാറ്ററി ശതമാനം അജ്ഞാതമാണ്."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ഫോൺ സിഗ്‌നൽ ഒന്നുമില്ല."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ഫോണിൽ ഒരു ബാർ."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ഫോണിൽ രണ്ട് ബാർ."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"അറിയിപ്പ് നിരസിച്ചു."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ബബ്ൾ ഡിസ്മിസ് ചെയ്തു."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"അറിയിപ്പ് ഷെയ്‌ഡ്."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ദ്രുത ക്രമീകരണങ്ങൾ."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ലോക്ക് സ്‌ക്രീൻ."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"പ്രൊഫൈൽ നിരീക്ഷിക്കപ്പെടാം"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"നെറ്റ്‌വർക്ക് നിരീക്ഷിക്കപ്പെടാം"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"നെറ്റ്‌വർക്ക് നിരീക്ഷിക്കപ്പെടാം"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ ഉടമസ്ഥതയിലായതിനാൽ നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിച്ചേക്കാം"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> എന്ന സ്ഥാപനത്തിന്റെ ഉടമസ്ഥതയിലായതിനാൽ നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിച്ചേക്കാം"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്, കൂടാതെ <xliff:g id="VPN_APP">%1$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റ് ചെയ്‌തിരിക്കുന്നു"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN പ്രവർത്തനരഹിതമാക്കുക"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN വിച്‌ഛേദിക്കുക"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"നയങ്ങൾ കാണുക"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"നിയന്ത്രണങ്ങൾ കാണുക"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>എന്ന സ്ഥാപനത്തിന്റേതാണ്.\n\nക്രമീകരണം, കോർപ്പറേറ്റ് ആക്‌സസ്, ആപ്പുകൾ, നിങ്ങളുടെ ഉപകരണവുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ‌വിവരങ്ങൾ എന്നിവ നിരീക്ഷിക്കാനും മാനേജ് ചെയ്യാനും നിങ്ങളുടെ ഐടി അഡ്‌മിന് കഴിയും.\n\nകൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ ഐടി അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്.\n\nക്രമീകരണം, കോർപ്പറേറ്റ് ആക്‌സസ്, ആപ്പുകൾ, നിങ്ങളുടെ ഉപകരണവുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ‌വിവരങ്ങൾ എന്നിവ നിരീക്ഷിക്കാനും മാനേജ് ചെയ്യാനും നിങ്ങളുടെ ഐടി അഡ്‌മിന് കഴിയും.\n\nകൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ ഐടി അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ഈ ഉപകരണത്തിൽ നിങ്ങളുടെ സ്ഥാപനമൊരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"നിങ്ങളുടെ ഉപകരണത്തിലെ ട്രാഫിക്ക് നിരീക്ഷിക്കുന്ന നെറ്റ്‌വർക്ക് ലോഗിംഗ് അഡ്‌മിൻ ഓണാക്കിയിട്ടുണ്ട്.\n\nകൂടുതൽ ‌വിവരങ്ങൾക്ക് അഡ്‌മിനുമായി‌ ബന്ധപ്പെടുക."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"VPN കണക്ഷൻ സജ്ജീകരിക്കാൻ നിങ്ങൾ ഒരു ആപ്പിന് അനുമതി നൽകി.\n\nഈ ആപ്പിന് നിങ്ങളുടെ ഇമെയിലുകളും ആപ്സും വെബ്‌സൈറ്റുകളും ഉൾപ്പെടെ, ഉപകരണവും നെറ്റ്‌വർക്ക് പ്രവർത്തനവും നിരീക്ഷിക്കാൻ കഴിയും."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ നിയന്ത്രിക്കുന്നത് <xliff:g id="ORGANIZATION">%1$s</xliff:g> ആണ്.\n\nഇമെയിലുകൾ, ആപ്‌സ്, വെബ്‌സൈറ്റുകൾ എന്നിവയടങ്ങുന്ന നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാൻ അഡ്‌മിന് കഴിയും.\n\nകൂടുതൽ ‌വിവരങ്ങൾക്ക് അഡ്‌മിനുമായി‌ ബന്ധപ്പെടുക.\n\nനെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി ‌നിരീക്ഷിക്കാൻ സാധിക്കുന്ന ഒരു VPN-ലേക്ക് കൂടി നിങ്ങൾ കണക്റ്റ് ‌ചെയ്യപ്പെട്ടിരിക്കുന്നു."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്. നിങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ, സ്‌ക്രീൻ സമയം, ലൊക്കേഷൻ എന്നിവ പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ രക്ഷിതാവിന് കാണാം, നിയന്ത്രിക്കാം."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"നിങ്ങൾ <xliff:g id="APPLICATION">%1$s</xliff:g> ആപ്പിലേക്ക് കണക്റ്റുചെയ്‌തിരിക്കുന്നു, അതിന് ഇമെയിലുകൾ, ആപ്പുകൾ, വെബ്‌സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാനാകും."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"നിങ്ങൾ <xliff:g id="APPLICATION">%1$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്‌തിരിക്കുന്നു, അതിന് ഇമെയിലുകൾ, ആപ്സ്, വെബ്‌സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ സ്വകാര്യ നെറ്റ്‌വർക്ക് പ്രവർത്തനം നിരീക്ഷിക്കാനാകും."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ഈ ആപ്പിൽ നിന്നുള്ള അറിയിപ്പുകൾ തുടർന്നും കാണിക്കണോ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"നിശബ്‌ദം"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ഡിഫോൾട്ട്"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"ബബ്ൾ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"സ്വയമേവ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ശബ്ദമോ വൈബ്രേഷനോ ഇല്ല"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ശബ്‌ദമോ വൈബ്രേഷനോ ഇല്ല, സംഭാഷണ വിഭാഗത്തിന് താഴെയായി ദൃശ്യമാകും"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ക്രമീകരണം"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"മുൻഗണന"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> സംഭാഷണ സവിശേഷതകളെ പിന്തുണയ്‌ക്കുന്നില്ല"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"അടുത്തിടെയുള്ള ബബിളുകൾ ഒന്നുമില്ല"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"അടുത്തിടെയുള്ള ബബിളുകൾ, ഡിസ്മിസ് ചെയ്ത ബബിളുകൾ എന്നിവ ഇവിടെ ദൃശ്യമാവും"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ഈ അറിയിപ്പുകൾ പരിഷ്ക്കരിക്കാനാവില്ല."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"അറിയിപ്പുകളുടെ ഈ ഗ്രൂപ്പ് ഇവിടെ കോണ്‍ഫിഗര്‍ ചെയ്യാൻ കഴിയില്ല"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"പ്രോക്‌സി അറിയിപ്പ്"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"ഉപകരണ സേവനങ്ങള്‍"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"പേരില്ല"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ഈ ആപ്പ് റീസ്‌റ്റാർട്ട് ചെയ്യാനും പൂർണ്ണ സ്‌ക്രീനാവാനും ടാപ്പ് ചെയ്യുക."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബബിളുകളുടെ ക്രമീകരണം"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ഓവർഫ്ലോ"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"അടുക്കുകളിലേക്ക് തിരിച്ച് ചേർക്കുക"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"മാനേജ് ചെയ്യുക"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>-ൽ നിന്നുള്ള <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> എന്നതിൽ നിന്നുള്ള <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> കൂടുതലും"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"നീക്കുക"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"മുകളിൽ ഇടതുഭാഗത്തേക്ക് നീക്കുക"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"മുകളിൽ വലതുഭാഗത്തേക്ക് നീക്കുക"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ചുവടെ ഇടതുഭാഗത്തേക്ക് നീക്കുക"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ചുവടെ വലതുഭാഗത്തേക്ക് നീക്കുക"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ബബിൾ ഡിസ്മിസ് ചെയ്യൂ"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"സംഭാഷണം ബബിൾ ചെയ്യരുത്"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"ബബിളുകൾ ഉപയോഗിച്ച് ചാറ്റ് ചെയ്യുക"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"പുതിയ സംഭാഷണങ്ങൾ ഫ്ലോട്ടിംഗ് ഐക്കണുകളോ ബബിളുകളോ ആയി ദൃശ്യമാവുന്നു. ബബിൾ തുറക്കാൻ ടാപ്പ് ചെയ്യൂ. ഇത് നീക്കാൻ വലിച്ചിടുക."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ബബിളുകൾ ഏതുസമയത്തും നിയന്ത്രിക്കുക"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ഈ ആപ്പിൽ നിന്നുള്ള ബബിളുകൾ ഓഫാക്കാൻ മാനേജ് ചെയ്യുക ടാപ്പ് ചെയ്യുക"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"മനസ്സിലായി"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ക്രമീകരണം"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്‌തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"സ്‌റ്റാൻഡ്‌ബൈ"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"പുതിയ ഉപകരണവുമായി ജോടിയാക്കുക"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"നിങ്ങളുടെ ബാറ്ററി മീറ്റർ വായിക്കുന്നതിൽ പ്രശ്‌നമുണ്ട്"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"കൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings_tv.xml b/packages/SystemUI/res/values-ml/strings_tv.xml
index 9784337..b9a6dbe 100644
--- a/packages/SystemUI/res/values-ml/strings_tv.xml
+++ b/packages/SystemUI/res/values-ml/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"മൈക്രോഫോൺ സജീവമാണ്"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s, നിങ്ങളുടെ മൈക്രോഫോൺ ആക്‌സസ് ചെയ്‌തു"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 4eb2fb1..b841fa95 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -86,14 +86,17 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Дэлгэцийн зургийг дахин дарж үзнэ үү"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Сангийн багтаамж бага байгаа тул дэлгэцээс дарсан зургийг хадгалах боломжгүй байна"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Таны апп, байгууллагад дэлгэцийн зураг авахыг зөвшөөрдөггүй"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Дэлгэцийн агшныг засах"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Дэлгэцийн агшныг хаах"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Засах"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Дэлгэцийн агшныг засах"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Гүйлгэх"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Бүхэлд нь багтаасан дэлгэцийн агшин"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Дэлгэцийн агшныг хаах"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Дэлгэцийн агшныг урьдчилан үзэх"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Дэлгэцийн үйлдэл бичигч"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Дэлгэц бичлэг боловсруулж байна"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Бичлэгийг эхлүүлэх үү?"</string>
-    <string name="screenrecord_description" msgid="1123231719680353736">"Бичих үед Андройд систем нь таны дэлгэц дээр харагдах эсвэл төхөөрөмж дээрээ тоглуулсан аливаа эмзэг мэдээллийг авах боломжтой. Үүнд нууц үг, төлбөрийн мэдээлэл, зураг, зурвас болон аудио багтана."</string>
+    <string name="screenrecord_description" msgid="1123231719680353736">"Бичих үед Андройд систем нь таны дэлгэц дээр харагдах эсвэл төхөөрөмж дээрээ тоглуулсан аливаа эмзэг мэдээллийг авах боломжтой. Үүнд нууц үг, төлбөрийн мэдээлэл, зураг, мессеж болон аудио багтана."</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио бичих"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Төхөөрөмжийн аудио"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Хөгжим, дуудлага болон хонхны ая зэрэг таны төхөөрөмжийн дуу"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Батерей хоёр баганатай."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Батерей гурван баганатай."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Батерей дүүрэн."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарейн хувь тодорхойгүй байна."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Утас байхгүй."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Утас нэг баганатай."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Утас хоёр баганатай."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Мэдэгдэл хаагдсан."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Бөмбөлгийг үл хэрэгссэн."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Мэдэгдлийн хураангуй самбар"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Шуурхай тохиргоо."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Дэлгэц түгжих."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Профайлыг хянаж байж болзошгүй"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Сүлжээ хянагдаж байж болзошгүй"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Сүлжээг хянаж байж болзошгүй"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Энэ төхөөрөмжийг таны эцэг эх удирддаг"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Танай байгууллага энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг бөгөөд <xliff:g id="VPN_APP">%1$s</xliff:g>-д холбогдсон байна"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN идэвхгүйжүүлэх"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN таслах"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Удирдамж харах"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Хяналтыг харах"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Энэ төхөөрөмж <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-д харьяалагддаг.\n\nТанай IT админ тохиргоо, байгууллагын хандалт, аппууд, таны төхөөрөмжтэй холбоотой өгөгдөл, таны төхөөрөмжийн байршлын мэдээллийг хянах, удирдах боломжтой.\n\nНэмэлт мэдээлэл авахын тулд IT админтайгаа холбогдоно уу."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг.\n\nТанай IT админ тохиргоо, байгууллагын хандалт, аппууд, таны төхөөрөмжтэй холбоотой өгөгдөл, таны төхөөрөмжийн байршлын мэдээллийг хянах, удирдах боломжтой.\n\nНэмэлт мэдээлэл авахын тулд IT админтайгаа холбогдоно уу."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Таны байгууллага энэ төхөөрөмжид сертификатын зөвшөөрлийг суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Таны админ төхөөрөмжийн ачааллыг хянадаг сүлжээний логийг асаасан байна.\n\nДэлгэрэнгүй мэдээлэл авах бол админтайгаа холбогдоно уу."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Та апп-д VPN холболт хийхийг зөвшөөрсөн байна.\n\nЭнэхүү апп нь таны имэйл, апп, вебсайт зэрэг төхөөрөмж болон сүлжээний үйл ажиллагааг хянах боломжтой."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> таны ажлын профайлыг удирддаг.\n\nТаны админ имэйл, апп болон веб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой.\n\nДэлгэрэнгүй мэдээлэл авах бол админтайгаа холбогдоно уу.\n\nТа сүлжээний үйл ажиллагааг хянах боломжтой VPN-д холбогдсон байна."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Энэ төхөөрөмжийг таны эцэг эх удирддаг. Таны эцэг эх таны хэрэглэдэг апп, байршил, дэлгэцийн цаг зэрэг мэдээллийг харж, удирдах боломжтой."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вебсайт зэрэг сүлжээний үйл ажиллагааг хянах боломжтой."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вебсайт зэрэг сүлжээний хувийн үйл ажиллагааг хянах боломжтой."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Энэ аппаас мэдэгдэл харуулсан хэвээр байх уу?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Чимээгүй"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Өгөгдмөл"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Бөмбөлөг"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автомат"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Дуу эсвэл чичиргээ байхгүй"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Дуу эсвэл чичиргээ байхгүй бөгөөд харилцан ярианы хэсгийн доод талд харагдана"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Тохиргоо"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Ач холбогдол"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь харилцан ярианы онцлогуудыг дэмждэггүй"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Саяхны бөмбөлөг алга байна"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Саяхны бөмбөлгүүд болон үл хэрэгссэн бөмбөлгүүд энд харагдана"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Эдгээр мэдэгдлийг өөрчлөх боломжгүй."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Энэ бүлэг мэдэгдлийг энд тохируулах боломжгүй байна"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Прокси хийсэн мэдэгдэл"</string>
@@ -929,7 +932,7 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Сэрэмжлүүлэг"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Батарей"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Дэлгэцийн зураг дарах"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Энгийн зурвас"</string>
+    <string name="notification_channel_general" msgid="4384774889645929705">"Энгийн мессеж"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Хадгалах сан"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Заавар"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Шуурхай апп"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Төхөөрөмжийн үйлчилгээ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Гарчиггүй"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Энэ аппыг дахин эхлүүлж, бүтэн дэлгэцэд орохын тулд товшино уу."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н бөмбөлгүүдийн тохиргоо"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Халих"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Өрөлтөд буцааж нэмэх"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Удирдах"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>-н <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g>-н <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> болон бусад <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Зөөх"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Зүүн дээш зөөх"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Баруун дээш зөөх"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Зүүн доош зөөх"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Баруун доош зөөх"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Бөмбөлгийг хаах"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Харилцан яриаг бүү бөмбөлөг болго"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Бөмбөлөг ашиглан чатлаарай"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Шинэ харилцан яриа нь хөвөгч дүрс тэмдэг эсвэл бөмбөлөг хэлбэрээр харагддаг. Бөмбөлгийг нээхийн тулд товшино уу. Түүнийг зөөхийн тулд чирнэ үү."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Дурын үед бөмбөлгийг хянаарай"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Энэ аппын бөмбөлгүүдийг унтраахын тулд Удирдах дээр товшино уу"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ойлголоо"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-н тохиргоо"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Зогсолтын горим"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Шинэ төхөөрөмж хослуулах"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийгдсэн дугаар"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Хийгдсэн дугаарыг түр санах ойд хуулсан."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Таны батарей хэмжигчийг уншихад асуудал гарлаа"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нэмэлт мэдээлэл авахын тулд товшино уу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings_tv.xml b/packages/SystemUI/res/values-mn/strings_tv.xml
index 3a5ff74..3aef055 100644
--- a/packages/SystemUI/res/values-mn/strings_tv.xml
+++ b/packages/SystemUI/res/values-mn/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Микрофон идэвхтэй байна"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s нь таны микрофонд хандcан байна"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 57c1e07..ff67a40 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रीनशॉट पुन्हा घेण्याचा प्रयत्न करा"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"मर्यादित स्टोरेज जागेमुळे स्क्रीनशॉट सेव्ह करू शकत नाही"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"अ‍ॅप किंवा आपल्या संस्थेद्वारे स्क्रीनशॉट घेण्याची अनुमती नाही"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"स्क्रीनशॉट संपादित करा"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"स्क्रीनशॉट डिसमिस करा"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रीनशॉटचे पूर्वावलोकन"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रेकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"बॅटरी दोन बार."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"बॅटरी तीन बार."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"बॅटरी पूर्ण भरली."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"बॅटरीच्या चार्जिंगची टक्केवारी माहित नाही."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"कोणताही फोन नाही."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"फोन एक बार."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"फोन दोन बार."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"सूचना डिसमिस केल्या."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"बबल डिसमिस केला."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"सूचना शेड."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"द्रुत सेटिंग्ज."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"लॉक स्क्रीन."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफाईलचे परीक्षण केले जाऊ शकते"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"हे डिव्हाइस तुमच्या पालकाने व्यवस्थापित केले आहे"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"तुमच्‍या संस्‍थेकडे या डिव्हाइसची मालकी आहे आणि ती नेटवर्क ट्रॅफिकचे परीक्षण करू शकते"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> च्या मालकीचे आहे आणि ती नेटवर्क ट्रॅफिकचे परीक्षण करू शकते"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"हे डिव्हाइस तुमच्या संस्थेचे आहे आणि ते <xliff:g id="VPN_APP">%1$s</xliff:g> ला कनेक्ट केले आहे"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN अक्षम करा"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN डिस्कनेक्ट करा"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"धोरणे पहा"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"नियंत्रणे पाहा"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> चे आहे.\n\nतुमचा आयटी ॲडमिन सेटिंग्ज, कॉर्पोरेट अ‍ॅक्सेस, ॲप्‍स, तुमच्‍या डिव्‍हाइसशी संबंधित डेटा आणि तुमच्‍या डिव्‍हाइसच्‍या स्‍थानाची माहिती यांचे परीक्षण व व्‍यवस्‍थापन करू शकतो.\n\nअधिक माहितीसाठी तुमच्‍या आयटी ॲडमिनशी संपर्क साधा."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"हे डिव्हाइस तुमच्या संस्थेचे आहे.\n\nतुमचा आयटी ॲडमिन सेटिंग्ज, कॉर्पोरेट अ‍ॅक्सेस, ॲप्‍स, तुमच्‍या डिव्‍हाइसशी संबंधित डेटा आणि तुमच्‍या डिव्‍हाइसच्‍या स्‍थानाची माहिती यांचे परीक्षण व व्‍यवस्‍थापन करू शकतो.\n\nअधिक माहितीसाठी तुमच्‍या आयटी ॲडमिनशी संपर्क साधा."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"आपल्या संस्थेने या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"आपल्या प्रशासकाने नेटवर्क लॉगिंग सुरू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे निरीक्षण करते.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"तुम्ही VPN कनेक्शन सेट करण्यासाठी अ‍ॅपला परवानगी दिली.\n\nहा अ‍ॅप ईमेल, अ‍ॅप्स आणि वेबसाइटसह, तुमच्या डिव्हाइस आणि नेटवर्क ॲक्टिव्हिटीचे परीक्षण करू शकतो."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"तुमचे कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते.\n\nतुमचा प्रशासक ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्या नेटवर्क ॲक्टिव्हिटीचे निरीक्षण करण्यास सक्षम आहे.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा.\n\nतुम्ही VPN शी देखील कनेक्ट आहात, जे आपल्या नेटवर्क ॲक्टिव्हिटीचे निरीक्षण करू शकते."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"हे डिव्हाइस तुमच्या पालकाने व्यवस्थापित केले आहे. तुम्ही वापरत असलेली ॲप्स, तुमचे स्थान आणि तुमचा स्क्रीन वेळ यांसारखी माहिती तुमचे पालक पाहू आणि व्यवस्‍थापित करू शकतात."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"तुम्ही <xliff:g id="APPLICATION">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"तुम्ही <xliff:g id="APPLICATION">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जो ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या वैयक्तिक नेटवर्क क्रियाकलापाचे परीक्षण करू शकतो."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"या अ‍ॅपकडील सूचना दाखवणे सुरू ठेवायचे?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"सायलंट"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"डीफॉल्ट"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"बबल"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ऑटोमॅटिक"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"आवाज किंवा व्हायब्रेशन नाही"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"आवाज किंवा व्हायब्रेशन नाही आणि संभाषण विभागात सर्वात तळाशी दिसते"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिंग्ज"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राधान्य"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे संभाषण वैशिष्ट्यांना सपोर्ट करत नाही"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"अलीकडील कोणतेही बबल नाहीत"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"अलीकडील बबल आणि डिसमिस केलेले बबल येथे दिसतील"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"या सूचनांचा संच येथे कॉंफिगर केला जाऊ शकत नाही"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"प्रॉक्सी केलेल्या सूचना"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"डिव्हाइस सेवा"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक नाही"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"हे अ‍ॅप रीस्टार्ट करण्यासाठी आणि फुल स्क्रीन करण्यासाठी टॅप करा."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> बबलसाठी सेटिंग्ज"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ओव्हरफ्लो"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"स्टॅकमध्ये परत जोडा"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"व्यवस्थापित करा"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> कडून <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> आणि आणखी <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> कडून <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"हलवा"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"वर डावीकडे हलवा"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"वर उजवीकडे हलवा"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"तळाशी डावीकडे हलवा"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"तळाशी उजवीकडे हलवा"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"बबल डिसमिस करा"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"संभाषणाला बबल करू नका"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"बबल वापरून चॅट करा"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"नवीन संभाषणे फ्लोटिंग आयकन किंवा बबल म्हणून दिसतात. बबल उघडण्यासाठी टॅप करा. हे हलवण्यासाठी ड्रॅग करा."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"बबल कधीही नियंत्रित करा"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"या अ‍ॅपमधून बबल बंद करण्यासाठी व्यवस्थापित करा वर टॅप करा"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"समजले"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> सेटिंग्ज"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टँडबाय"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नवीन डिव्हाइससोबत पेअर करा"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"तुमचे बॅटरी मीटर वाचताना समस्या आली"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"अधिक माहितीसाठी टॅप करा"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings_tv.xml b/packages/SystemUI/res/values-mr/strings_tv.xml
index 7f58fe7..0d0d8e1 100644
--- a/packages/SystemUI/res/values-mr/strings_tv.xml
+++ b/packages/SystemUI/res/values-mr/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"मायक्रोफोन ॲक्टिव्ह आहे"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s यांनी तुमचा मायक्रोफोन अ‍ॅक्सेस केला आहे"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 058055f..8f426ed 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Cuba ambil tangkapan skrin sekali lagi"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Tidak dapat menyimpan tangkapan skrin kerana ruang storan terhad"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Pengambilan tangkapan skrin tidak dibenarkan oleh apl atau organisasi anda"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edit tangkapan skrin"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ketepikan tangkapan skrin"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit tangkapan skrin"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Tatal"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Penatalan tangkapan skrin"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ketepikan tangkapan skrin"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pratonton tangkapan skrin"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Perakam Skrin"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Bateri dua bar."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Bateri tiga bar."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Bateri penuh."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Peratusan kuasa bateri tidak diketahui."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Tiada telefon."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon satu bar."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon dua bar."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Pemberitahuan diketepikan."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Gelembung diketepikan."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bidai pemberitahuan."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Tetapan pantas."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Kunci skrin."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil mungkin dipantau"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Rangkaian mungkin dipantau"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Rangkaian mungkin dipantau"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Peranti ini diurus oleh ibu bapa anda"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi anda memiliki peranti ini dan mungkin memantau trafik rangkaian"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> memiliki peranti ini dan mungkin memantau trafik rangkaian"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Peranti ini milik organisasi anda dan dihubungkan dengan <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Lumpuhkan VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Putuskan sambungan VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Lihat Dasar"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Lihat kawalan"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Peranti ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nPentadbir IT anda boleh memantau dan mengurus tetapan, akses korporat, apl, data yang dikaitkan dengan peranti anda dan maklumat lokasi peranti anda.\n\nUntuk maklumat lanjut, hubungi pentadbir IT anda."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Peranti ini milik organisasi anda.\n\nPentadbir IT anda boleh memantau dan mengurus tetapan, akses korporat, apl, data yang dikaitkan dengan peranti anda dan maklumat lokasi peranti anda.\n\nUntuk maklumat lanjut, hubungi pentadbir IT anda."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasi anda memasang sijil kuasa pada peranti ini. Trafik rangkaian selamat anda mungkin dipantau atau diubah suai."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Pentadbir anda telah menghidupkan pengelogan rangkaian yang memantau trafik pada peranti anda.\n\nUntuk mendapatkan maklumat lanjut, hubungi pentadbir anda."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Anda memberikan kebenaran kepada apl untuk menyediakan sambungan VPN.\n\nApl ini boleh memantau aktiviti peranti dan rangkaian anda, termasuk e-mel, apl dan tapak web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Profil kerja anda diurus oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nPentadbir anda boleh memantau aktiviti rangkaian, termasuk e-mel, apl dan tapak web.\n\nUntuk mendapatkan maklumat lanjut, hubungi pentadbir anda.\n\nAnda juga disambungkan ke VPN, yang boleh memantau aktiviti rangkaian."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Peranti ini diurus oleh ibu bapa anda. Ibu bapa anda dapat melihat dan mengurus maklumat seperti apl yang anda gunakan, lokasi dan masa skrin anda."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Anda dihubungkan ke <xliff:g id="APPLICATION">%1$s</xliff:g>, yang boleh memantau aktiviti rangkaian anda, termasuk e-mel, apl dan tapak web."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Anda disambungkan ke <xliff:g id="APPLICATION">%1$s</xliff:g>, yang boleh memantau aktiviti rangkaian peribadi anda, termasuk e-mel, apl dan tapak web."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Terus tunjukkan pemberitahuan daripada apl ini?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Senyap"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Lalai"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Gelembung"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatik"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Tiada bunyi atau getaran"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Tiada bunyi atau getaran dan muncul di sebelah bawah dalam bahagian perbualan"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Tetapan"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Keutamaan"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak menyokong ciri perbualan"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Tiada gelembung terbaharu"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Gelembung baharu dan gelembung yang diketepikan akan dipaparkan di sini"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Pemberitahuan ini tidak boleh diubah suai."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Kumpulan pemberitahuan ini tidak boleh dikonfigurasikan di sini"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Pemberitahuan berproksi"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Perkhidmatan Peranti"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Tiada tajuk"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Ketik untuk memulakan semula apl ini dan menggunakan skrin penuh."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Tetapan untuk gelembung <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Limpahan"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Tambah kembali pada tindanan"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Urus"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> daripada <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> daripada <xliff:g id="APP_NAME">%2$s</xliff:g> dan <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> lagi"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Alih"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Alihkan ke atas sebelah kiri"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Alihkan ke atas sebelah kanan"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Alihkan ke bawah sebelah kiri"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Alihkan ke bawah sebelah kanan"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Ketepikan gelembung"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Jangan jadikan perbualan dalam bentuk gelembung"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Bersembang menggunakan gelembung"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Perbualan baharu muncul sebagai ikon terapung atau gelembung. Ketik untuk membuka gelembung. Seret untuk mengalihkan gelembung tersebut."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kawal gelembung pada bila-bila masa"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ketik Urus untuk mematikan gelembung daripada apl ini"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Tetapan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem dikemas kini. Untuk membuat perubahan, pergi ke Tetapan."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pergi ke Tetapan untuk mengemas kini navigasi sistem"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tunggu sedia"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Gandingkan peranti baharu"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Masalah membaca meter bateri anda"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketik untuk mendapatkan maklumat lanjut"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings_tv.xml b/packages/SystemUI/res/values-ms/strings_tv.xml
index 3c62891..91c8c47 100644
--- a/packages/SystemUI/res/values-ms/strings_tv.xml
+++ b/packages/SystemUI/res/values-ms/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon Aktif"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s telah mengakses mikrofon anda"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 5249efa..9d8ffc9 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"မျက်နှာပြင်ပုံကို ထပ်ရိုက်ကြည့်ပါ"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"သိုလှောင်ခန်းနေရာ အကန့်အသတ်ရှိသောကြောင့် ဖန်သားပြင်ဓာတ်ပုံကို သိမ်းဆည်း၍မရပါ"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ဖန်သားပြင်ဓာတ်ပုံရိုက်ကူးခြင်းကို ဤအက်ပ် သို့မဟုတ် သင်၏အဖွဲ့အစည်းက ခွင့်မပြုပါ"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ဖန်သားပြင်ဓာတ်ပုံကို တည်းဖြတ်သည်"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ဖန်သားပြင်ဓာတ်ပုံ ပယ်ရန်"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"တည်းဖြတ်ရန်"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"ဖန်သားပြင်ဓာတ်ပုံကို တည်းဖြတ်သည်"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"လှိမ့်ရန်"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"ဖန်သားပြင်ဓာတ်ပုံကို လှိမ့်ရန်"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ဖန်သားပြင်ဓာတ်ပုံကို ပယ်သည်"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ဖန်သားပြင်ဓာတ်ပုံ အစမ်းကြည့်ရှုခြင်း"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ဖန်သားပြင် ရိုက်ကူးမှု"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ဖန်သားပြင်ရိုက်ကူးနေသည်"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ဘတ္တရီနှစ်ဘား။"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ဘတ္တရီသုံးဘား။"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ဘတ္တရီအပြည့်။"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ဘက်ထရီရာခိုင်နှုန်းကို မသိပါ။"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ဖုန်းလိုင်းမရှိပါ။"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ဖုန်းလိုင်းတစ်ဘား။"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ဖုန်းလိုင်းနှစ်ဘား။"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"အကြောင်းကြားချက်ကိုဖယ်ရှားပြီး"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ပူဖောင်းကွက် ဖယ်လိုက်သည်။"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"အ​ကြောင်းကြားစာအကွက်"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"အမြန်လုပ် အပြင်အဆင်"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"မျက်နှာပြင် သော့ပိတ်ရန်"</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ပရိုဖိုင်ကို စောင့်ကြပ်နိုင်သည်"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ကွန်ရက်ကို ကို စောင့်ကြပ် နိုင်ပါသည်"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ကွန်ရက်ကို စောင့်ကြည့်စစ်ဆေးမှု ရှိနိုင်ပါသည်"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး <xliff:g id="VPN_APP">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN ကို ပိတ်ထားရန်"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN ကို အဆက်ဖြတ်ရန်"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"မူဝါဒများကို ကြည့်ရန်"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ထိန်းချုပ်မှုများကို ကြည့်ရန်"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပါသည်။\n\nဆက်တင်များ၊ ကော်ပိုရိတ် သုံးခွင့်၊ အက်ပ်များ၊ သင့်စက်နှင့် ဆက်စပ်နေသော ဒေတာများနှင့် သင့်စက်တည်နေရာတို့ကို သင်၏ IT စီမံခန့်ခွဲသူက စောင့်ကြည့် စီမံနိုင်သည်။\n\nနောက်ထပ်အချက်အလက်များအတွက် သင်၏ IT စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်။\n\nဆက်တင်များ၊ ကော်ပိုရိတ် သုံးခွင့်၊ အက်ပ်များ၊ သင့်စက်နှင့် ဆက်စပ်နေသော ဒေတာများနှင့် သင့်စက်တည်နေရာတို့ကို သင်၏ IT စီမံခန့်ခွဲသူက စောင့်ကြည့် စီမံနိုင်သည်။\n\nနောက်ထပ်အချက်အလက်များအတွက် သင်၏ IT စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"သင်၏ အဖွဲ့အစည်းက ဤစက်ပစ္စည်းတွင် စီမံခန့်ခွဲမှုဆိုင်ရာ အသိအမှတ်ပြုလက်မှတ်ကို ထည့်သွင်းထားပါသည်။ လုံခြုံမှုရှိသော ကွန်ရက်ဒေတာစီးဆင်းမှုကို စောင့်ကြည့်ခြင်း သို့မဟုတ် ပြုပြင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်။"</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"သင့်စီမံခန့်ခွဲသူသည် စက်ပစ္စည်းပေါ်ရှိ ဒေတာအသွားအလာကို စောင့်ကြည့်နိုင်သည့် ကွန်ရက်အတွက် မှတ်တမ်းတင်ခြင်းကို ဖွင့်ထားပါသည်။\n\nနောက်ထပ် အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"VPN ချိတ်ဆက်မှုပြုလုပ်ရန် အက်ပ်ကို သင်ခွင့်ပြုလိုက်သည်။ \n\n ဤအက်ပ်သည် အီးမေးလ်များ၊ အက်ပ်များနှင့် ဝဘ်ဆိုက်များအပါအဝင် သင့်ကွန်ရက်လုပ်ဆောင်ချက်များကို စောင့်ကြည့်နိုင်သည်။"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"သင့်အလုပ်ပရိုဖိုင်ကို <xliff:g id="ORGANIZATION">%1$s</xliff:g> က စီမံခန့်ခွဲထားပါသည်။\n\nသင့်စီမံခန့်ခွဲသူသည် အီးမေးလ်၊ အက်ပ်နှင့် ဝဘ်ဆိုက်များအပါအဝင် သင့်ကွန်ရက်လုပ်ဆောင်ချက်ကို စောင့်ကြည့်နိုင်ပါသည်။\n\nနောက်ထပ် အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။\n\nသင်သည် သင့်ကွန်ရက်လုပ်ဆောင်ချက်ကို စောင့်ကြည့်နိုင်သည့် VPN သို့လည်း ချိတ်ဆက်ထားပါသေးသည်။"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်။ သင့်မိဘက သင်သုံးသောအက်ပ်များ၊ သင်၏တည်နေရာနှင့် အသုံးပြုချိန် ကဲ့သို့သော အချက်အလက်များကို မြင်နိုင်ပြီး စီမံခန့်ခွဲနိုင်သည်။"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"သင်သည် အီးမေး၊ အက်ပ်နှင့် ဝဘ်ဆိုက်များအပါအဝင် သင်၏ကွန်ရက် လုပ်ဆောင်ချက်များကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်။"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"သင်သည် <xliff:g id="APPLICATION">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားသည်။ ၎င်းသည် အီးမေးလ်များ၊ အက်ပ်များနှင့် ဝဘ်ဆိုက်များအပါအဝင် သင့်ကွန်ရက်လုပ်ဆောင်ချက်ကို စောင့်ကြည့်နိုင်သည်။"</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ဤအက်ပ်ထံမှ အကြောင်းကြားချက်များကို ဆက်ပြလိုပါသလား။"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"အသံတိတ်ရန်"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"မူလ"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"ပူဖောင်းဖောက်သံ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"အလိုအလျောက်"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"အသံ သို့မဟုတ် တုန်ခါမှုမရှိပါ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"အသံ သို့မဟုတ် တုန်ခါမှုမရှိပါ၊ စကားဝိုင်းကဏ္ဍ၏ အောက်ပိုင်းတွင် မြင်ရသည်"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ဆက်တင်များ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ဦးစားပေး"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> က စကားဝိုင်းဝန်ဆောင်မှုများကို မပံ့ပိုးပါ"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"လတ်တလော ပူဖောင်းကွက်များ မရှိပါ"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"လတ်တလော ပူဖောင်းကွက်များနှင့် ပိတ်လိုက်သော ပူဖောင်းကွက်များကို ဤနေရာတွင် မြင်ရပါမည်"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ဤအကြောင်းကြားချက်များကို ပြုပြင်၍ မရပါ။"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ဤအကြောင်းကြားချက်အုပ်စုကို ဤနေရာတွင် စီစဉ်သတ်မှတ်၍ မရပါ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ပရောက်စီထည့်ထားသော အကြောင်းကြားချက်"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"စက်ပစ္စည်းဝန်ဆောင်မှုများ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ခေါင်းစဉ် မရှိပါ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ဤအက်ပ်ကို ပြန်စတင်ပြီး မျက်နှာပြင်အပြည့်လုပ်ရန် တို့ပါ။"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ပူဖောင်းကွက်အတွက် ဆက်တင်များ"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"အပိုများပြရန်"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ပူဖေါင်းတန်းသို့ ပြန်ထည့်ရန်"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"စီမံရန်"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> မှ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> နှင့် နောက်ထပ် <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ခုမှ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ရွှေ့ရန်"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ဘယ်ဘက်ထိပ်သို့ ရွှေ့ရန်"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ညာဘက်ထိပ်သို့ ရွှေ့ပါ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ဘယ်အောက်ခြေသို့ ရွှေ့ရန်"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ညာအောက်ခြေသို့ ရွှေ့ပါ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ပူဖောင်းကွက် ပယ်ရန်"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"စကားဝိုင်းကို ပူဖောင်းကွက် မပြုလုပ်ပါနှင့်"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"ပူဖောင်းကွက် သုံး၍ ချတ်လုပ်ခြင်း"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"စကားဝိုင်းအသစ်များကို မျောနေသည့် သင်္ကေတများ သို့မဟုတ် ပူဖောင်းကွက်များအဖြစ် မြင်ရပါမည်။ ပူဖောင်းကွက်ကိုဖွင့်ရန် တို့ပါ။ ရွှေ့ရန် ၎င်းကို ဖိဆွဲပါ။"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ပူဖောင်းကွက်ကို အချိန်မရွေး ထိန်းချုပ်ရန်"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ဤအက်ပ်မှနေ၍ ပူဖောင်းများကို ပိတ်ရန်အတွက် \'စီမံရန်\' ကို တို့ပါ"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ရပါပြီ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ဆက်တင်များ"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ပြီးပါပြီ။ အပြောင်းအလဲများ ပြုလုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ။"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"အသင့်အနေအထား"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"စက်အသစ် တွဲချိတ်ရန်"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"သင်၏ ဘက်ထရီမီတာကို ဖတ်ရာတွင် ပြဿနာရှိနေသည်"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"နောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings_tv.xml b/packages/SystemUI/res/values-my/strings_tv.xml
index 88d7d53..05387e1 100644
--- a/packages/SystemUI/res/values-my/strings_tv.xml
+++ b/packages/SystemUI/res/values-my/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"မိုက်ခရိုဖုန်း ဖွင့်ထားသည်"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s က သင့်မိုက်ခရိုဖုန်းကို သုံးထားသည်"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index b676e91..cd0ec71 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv å ta skjermdump på nytt"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Kan ikke lagre skjermdumpen på grunn av begrenset lagringsplass"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Rediger skjermdumpen"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Avvis skjermdumpen"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning av skjermdump"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skjermopptaker"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skjermopptaket"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Batteri – to stolper."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Batteri – tre stolper."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batteriet er fullt."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriprosenten er ukjent."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Ingen telefon."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon – én stolpe."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon – to stolper."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Varselet ble skjult."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Boblen er avvist."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Varselskygge."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Hurtiginnstillinger."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Låseskjerm."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profilen kan overvåkes"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Nettverket kan være overvåket"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Nettverket kan bli overvåket"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enheten administreres av forelderen din"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasjonen din eier denne enheten og kan overvåke nettverkstrafikken"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> eier denne enheten og kan overvåke nettverkstrafikken"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Denne enheten tilhører organisasjonen din og er koblet til <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Deaktiver VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Koble fra VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Se retningslinjer"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Visningskontroller"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-administratoren din kan overvåke og administrere innstillinger, bedriftstilgang, apper, data som er tilknyttet denne enheten, og enhetens posisjonsinformasjon.\n\nKontakt IT-administratoren for å få mer informasjon."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Denne enheten tilhører organisasjonen din.\n\nIT-administratoren din kan overvåke og administrere innstillinger, bedriftstilgang, apper, data som er tilknyttet denne enheten, og enhetens posisjonsinformasjon.\n\nKontakt IT-administratoren for å få mer informasjon."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisasjonen din installerte en sertifiseringsinstans på denne enheten. Den sikre nettverkstrafikken din kan overvåkes eller endres."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administratoren din har slått på loggføring av nettverk, som overvåker trafikken på enheten din.\n\nKontakt administratoren for mer informasjon."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Du ga en app tillatelse til å konfigurere en VPN-tilkobling.\n\nDenne appen kan overvåke enheten og nettverksaktiviteten din, inkludert e-post, apper og nettsteder."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Jobbprofilen din administreres av <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratoren din kan overvåke nettverksaktiviteten din, inkludert e-post, apper og nettsteder.\n\nKontakt administratoren for mer informasjon.\n\nDu er også tilkoblet en VPN som kan overvåke nettverksaktiviteten din."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Denne enheten administreres av forelderen din. Forelderen din kan se og administrere informasjon, for eksempel appene du bruker, posisjonen din og skjermtiden din."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Enheten er koblet til <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan overvåke nettverksaktiviteten din, inkludert e-post, apper og nettsteder."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Enheten er koblet til <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan overvåke den personlige nettverksaktiviteten din, inkludert e-post, apper og nettsteder."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Vil du fortsette å vise varsler fra denne appen?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Lydløs"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Boble"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Ingen lyd eller vibrering"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Ingen lyd eller vibrering, og vises lavere i samtaledelen"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Innstillinger"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> støtter ikke samtalefunksjoner"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Ingen nylige bobler"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Nylige bobler og avviste bobler vises her"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse varslene kan ikke endres."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Denne varselgruppen kan ikke konfigureres her"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Omdirigert varsel"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Enhetstjenester"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen tittel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Trykk for å starte denne appen på nytt og vise den i fullskjerm."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Innstillinger for <xliff:g id="APP_NAME">%1$s</xliff:g>-bobler"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overflyt"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Legg tilbake i stabelen"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Administrer"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> fra <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> fra <xliff:g id="APP_NAME">%2$s</xliff:g> og <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> flere"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Flytt"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Flytt til øverst til venstre"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Flytt til øverst til høyre"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Flytt til nederst til venstre"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Flytt til nederst til høyre"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Lukk boblen"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ikke vis samtaler i bobler"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat med bobler"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nye samtaler vises som flytende ikoner eller bobler. Trykk for å åpne bobler. Dra for å flytte dem."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrollér bobler når som helst"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Trykk på Administrer for å slå av bobler for denne appen"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Greit"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-innstillinger"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ventemodus"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Koble til en ny enhet"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kunne ikke lese batterimåleren"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trykk for å få mer informasjon"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings_tv.xml b/packages/SystemUI/res/values-nb/strings_tv.xml
index cd55873..2f69a6c 100644
--- a/packages/SystemUI/res/values-nb/strings_tv.xml
+++ b/packages/SystemUI/res/values-nb/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofonen er aktiv"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s fikk tilgang til mikrofonen din"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index c3c8903..560fd0b 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रिनसट फेरि लिएर हेर्नुहोस्"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"भण्डारण ठाउँ सीमित भएका कारण स्क्रिनसट सुरक्षित गर्न सकिएन"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"उक्त एप वा तपाईंको संगठनले स्क्रिनसटहरू लिन दिँदैन"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"स्क्रिनसट सम्पादन गर्नुहोस्"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"स्क्रिनसट हटाउनुहोस्"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रिनसटको पूर्वावलोकन"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रिन रेकर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ब्याट्रिका दुईवटा पट्टिहरू"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ब्याट्रिका तिनवटा पट्टिहरू"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ब्याट्री पूर्ण छ।"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ब्याट्रीमा कति प्रतिशत चार्ज छ भन्ने कुराको जानाकरी छैन।"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"फोन छैन्।"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"फोन एउटा पट्टि।"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"फोन दुई पट्टि।"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"सूचना खारेज।"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"बबल हटाइयो।"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"सूचना कक्ष।"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"द्रुत सेटिङहरू"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"स्क्रीन बन्द गर्नुहोस्।"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफाइल अनुगमन हुन सक्छ"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"सञ्जाल अनुगमित हुन सक्छ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्कको अनुगमन गरिने सम्भावना छ"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"यो यन्त्र तपाईंका अभिभावक व्यवस्थापन गर्नुहुन्छ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ र उक्त सङ्गठनले यसको नेटवर्क ट्राफिक अनुगमन गर्न सक्छ"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> को स्वामित्वमा छ र उक्त सङ्गठनले यसको नेटवर्क ट्राफिक अनुगमन गर्न सक्छ"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ र <xliff:g id="VPN_APP">%1$s</xliff:g> मा कनेक्ट गरिएको छ"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN असक्षम गर्नुहोस्"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"विच्छेद VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतिहरू हेर्नुहोस्"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"नियन्त्रणहरू हेर्नुहोस्"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> को स्वामित्वमा छ।\n\nतपाईंका IT एड्मिन सेटिङ, संस्थागत पहुँच, एप, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको निगरानी र व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्ना IT एड्मिनसँग सम्पर्क गर्नुहोस्।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ।\n\nतपाईंका IT एड्मिन सेटिङ, संस्थागत पहुँच, एप, तपाईंको यन्त्रसँग सम्बन्धित डेटा र तपाईंको यन्त्रको स्थानसम्बन्धी जानकारीको निगरानी र व्यवस्थापन गर्न सक्नुहुन्छ।\n\nथप जानकारीका लागि आफ्ना IT एड्मिनसँग सम्पर्क गर्नुहोस्।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापित गऱ्यो। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"तपाईँको प्रशासकले तपाईँको यन्त्रमा ट्राफिकको अनुगमन गर्ने नेटवर्कको लगिङलाई सक्रिय पार्नुभएको छ।\n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"तपाईँले VPN जडान गर्न एपलाई अनुमति दिनुभयो।\n\nयो एपले तपाईँका यन्त्र र  नेटवर्क गतिविधि लगायत इमेल, एप र वेबसाइटहरू अनुगमन गर्न सक्छ।"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"तपाईंको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> ले व्यवस्थापन गर्दछ।\n\nतपाईंको प्रशासकले तपाईंको इमेल, एप र वेबसाइट सहित नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्नुहुन्छ। \n\nथप जानकारीका लागि आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।\n\n तपाईं एउटा VPN मा जडित हुनुहुन्छ। यस VPN ले नेटवर्कमा तपाईंको गतिविधिको अनुगमन गर्न सक्छ।"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"यो यन्त्र तपाईंका अभिभावक व्यवस्थापन गर्नुहुन्छ। तपाईंका अभिभावक तपाईंले प्रयोग गर्ने एप, तपाईंको स्थान र तपाईंले यन्त्र चलाएर बिताउने समय जस्ता जानकारी हेर्न तथा व्यवस्थापन गर्न सक्नुहुन्छ।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"तपाईं आफ्ना इमेल, एप र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> सँग जडित हुनुहुन्छ जसले इ-मेल, एपहरू र वेबसाइट लगायतका तपाईंको निजी नेटवर्क गतिविधिका अनुगमन गर्न सक्छ।"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"यो अनुप्रयोगका सूचनाहरू देखाउने क्रम जारी राख्ने हो?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"मौन"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"पूर्वनिर्धारित"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"बबल"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"स्वचालित"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"न घन्टी बज्छ न त कम्पन नै हुन्छ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"न घन्टी बज्छ न त कम्पन नै हुन्छ र वार्तालाप खण्डको तलतिर देखा पर्छ"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिङ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"हालैका बबलहरू छैनन्"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"हालैका बबल र खारेज गरिएका बबलहरू यहाँ देखिने छन्"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"यहाँबाट सूचनाहरूको यो समूह कन्फिगर गर्न सकिँदैन"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"प्रोक्सीमार्फत आउने सूचना"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"यन्त्रका सेवाहरू"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक छैन"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"यो एप पुनः सुरु गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> का बबलसम्बन्धी सेटिङहरू"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ओभरफ्लो देखाउनुहोस्"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"स्ट्याकमा फेरि थप्नुहोस्"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"व्यवस्थापन गर्नुहोस्"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> को <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> का <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> र थप <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"सार्नुहोस्"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"शीर्ष भागको बायाँतिर सार्नुहोस्"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"सिरानमा दायाँतिर सार्नुहोस्"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"पुछारमा बायाँतिर सार्नुहोस्"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"पुछारमा दायाँतिर सार्नुहोस्"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"बबल खारेज गर्नुहोस्"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"वार्तालाप बबलको रूपमा नदेखाइयोस्"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"बबलहरू प्रयोग गरी कुराकानी गर्नुहोस्"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"नयाँ वार्तालापहरू तैरने आइकन वा बबलका रूपमा देखिन्छन्। बबल खोल्न ट्याप गर्नुहोस्। बबल सार्न सो बबललाई ड्र्याग गर्नुहोस्।"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"जुनसुकै बेला बबलहरू नियन्त्रण गर्नुहोस्"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"यो एपबाट आएका बबलहरू अफ गर्न \"व्यवस्थापन गर्नुहोस्\" बटनमा ट्याप गर्नुहोस्"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"बुझेँ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> का सेटिङहरू"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्ट्यान्डबाई"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नयाँ यन्त्रको जोडा बनाउनुहोस्"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"यन्त्रको ब्याट्रीको मिटर रिडिङ क्रममा समस्या भयो"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"थप जानकारी प्राप्त गर्न ट्याप गर्नुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings_tv.xml b/packages/SystemUI/res/values-ne/strings_tv.xml
index 22f7f71..6f3eb66 100644
--- a/packages/SystemUI/res/values-ne/strings_tv.xml
+++ b/packages/SystemUI/res/values-ne/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"माइक्रोफोन सक्रिय छ"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ले तपाईंको माइक्रोफोनमाथि पहुँच राख्यो"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 691bfcb..6bed66b 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probeer opnieuw een screenshot te maken"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Kan screenshot niet opslaan vanwege beperkte opslagruimte"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Het maken van screenshots wordt niet toegestaan door de app of je organisatie"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Screenshot bewerken"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Screenshot sluiten"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Bewerken"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Screenshot bewerken"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Scrollen"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Screenshot scrollen"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Screenshot sluiten"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Voorbeeld van screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Schermopname"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Schermopname verwerken"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Batterij: twee streepjes."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Batterij: drie streepjes."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batterij is vol."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batterijpercentage onbekend."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Geen telefoonsignaal."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefoon: één streepje."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefoon: twee streepjes."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Melding verwijderd."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bubbel gesloten."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Meldingenpaneel."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Snelle instellingen."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Vergrendelscherm."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profiel kan worden gecontroleerd"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Netwerk kan worden gecontroleerd"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Netwerk kan worden gecontroleerd"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dit apparaat wordt beheerd door je ouder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Je organisatie is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Dit apparaat is eigendom van je organisatie en is verbonden met <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN uitschakelen"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Verbinding met VPN verbreken"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Beleid bekijken"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Beheeropties bekijken"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nJe IT-beheerder kan instellingen, zakelijke toegang, apps, aan je apparaat gekoppelde gegevens en de locatiegegevens van je apparaat bekijken en beheren.\n\nNeem contact op met je IT-beheerder voor meer informatie."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Dit apparaat is eigendom van je organisatie.\n\nJe IT-beheerder kan instellingen, zakelijke toegang, apps, aan je apparaat gekoppelde gegevens en de locatiegegevens van je apparaat bekijken en beheren.\n\nNeem contact op met je IT-beheerder voor meer informatie."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Je organisatie heeft een certificeringsinstantie geïnstalleerd op dit apparaat. Je beveiligde netwerkverkeer kan worden bijgehouden of aangepast."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Je beheerder heeft netwerkregistratie ingeschakeld, waarmee verkeer op je apparaat wordt bijgehouden.\n\nNeem contact op met je beheerder voor meer informatie."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Je hebt een app rechten gegeven voor het instellen van een VPN-verbinding.\n\nMet deze app kan je apparaat- en netwerkactiviteit worden gecontroleerd, inclusief e-mails, apps en websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nJe beheerder kan je netwerkactiviteit controleren, inclusief e-mails, apps en websites.\n\nNeem contact op met je beheerder voor meer informatie.\n\nJe bent ook verbonden met een VPN, waarmee je netwerkactiviteit kan worden gecontroleerd."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Dit apparaat wordt beheerd door je ouder. Je ouder kan informatie bekijken en beheren, zoals de apps die je gebruikt, je locatie en je schermtijd."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Je bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee je netwerkactiviteit (waaronder e-mails, apps en websites) kan worden bijgehouden."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"U bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee je persoonlijke netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Meldingen van deze app blijven weergeven?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Stil"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standaard"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bubbel"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Geen geluid of trilling"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Geen geluid of trilling en wordt lager in het gedeelte met gesprekken weergegeven"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Instellingen"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ondersteunt geen gespreksfuncties"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Geen recente bubbels"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Recente bubbels en gesloten bubbels worden hier weergegeven"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Deze meldingen kunnen niet worden aangepast."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Deze groep meldingen kan hier niet worden geconfigureerd"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Melding via proxy"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Apparaatservices"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Geen titel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tik om deze app opnieuw te starten en te openen op het volledige scherm."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Instellingen voor <xliff:g id="APP_NAME">%1$s</xliff:g>-bubbels"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overloop"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Weer toevoegen aan stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Beheren"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> van <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> van <xliff:g id="APP_NAME">%2$s</xliff:g> en nog <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Verplaatsen"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Naar linksboven verplaatsen"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Naar rechtsboven verplaatsen"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Naar linksonder verplaatsen"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Naar rechtsonder verplaatsen"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Bubbel sluiten"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Gesprekken niet in bubbels weergeven"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatten met bubbels"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nieuwe gesprekken worden weergegeven als zwevende iconen of \'bubbels\'. Tik om een bubbel te openen. Sleep om de bubbel te verplaatsen."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Beheer bubbels wanneer je wilt"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tik op Beheren om bubbels van deze app uit te schakelen"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Instellingen voor <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systeemnavigatie geüpdatet. Als je wijzigingen wilt aanbrengen, ga je naar Instellingen."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ga naar Instellingen om de systeemnavigatie te updaten"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stand-by"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Nieuw apparaat koppelen"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-nummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build-nummer naar klembord gekopieerd."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem bij het lezen van je batterijmeter"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik hier voor meer informatie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings_tv.xml b/packages/SystemUI/res/values-nl/strings_tv.xml
index 3b8e320..55dea83 100644
--- a/packages/SystemUI/res/values-nl/strings_tv.xml
+++ b/packages/SystemUI/res/values-nl/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microfoon actief"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s heeft toegang tot je microfoon gehad"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index de48527..3483e8c 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ପୁଣିଥରେ ସ୍କ୍ରୀନ୍‌ଶଟ୍ ନେବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"ସୀମିତ ଷ୍ଟୋରେଜ୍‍ ସ୍ପେସ୍‍ ହେତୁ ସ୍କ୍ରୀନଶଟ୍‍ ସେଭ୍‍ ହୋଇପାରିବ ନାହିଁ"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ଆପ୍‍ କିମ୍ବା ସଂସ୍ଥା ଦ୍ୱାରା ସ୍କ୍ରୀନଶଟ୍‍ ନେବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ସ୍କ୍ରିନସଟକୁ ଏଡିଟ୍ କରନ୍ତୁ"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ସ୍କ୍ରିନସଟ୍ ଖାରଜ କରନ୍ତୁ"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ସ୍କ୍ରିନସଟର ପ୍ରିଭ୍ୟୁ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ସ୍କ୍ରିନ୍ ରେକର୍ଡର୍"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ସ୍କ୍ରିନ ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ବ୍ୟାଟେରୀର ଦୁଇଟି ବାର୍‍ ଅଛି।"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ବ୍ୟାଟେରୀର ତିନୋଟି ବାର୍‍ ଅଛି।"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ବ୍ୟାଟେରୀ ପୂର୍ଣ୍ଣ‍।"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ବ୍ୟାଟେରୀ ଶତକଡ଼ା ଅଜଣା ଅଟେ।"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"କୌଣସି ଫୋନ୍ ନାହିଁ।"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ଫୋନର ଗୋଟିଏ ବାର ଅଛି।"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ଫୋନର ଦୁଇଟି ବାର୍‌ ଅଛି।"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା।"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ବବଲ୍ ଖାରଜ କରାଯାଇଛି।"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ବିଜ୍ଞପ୍ତି ଶେଡ୍‍।"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ଦ୍ରୁତ ସେଟିଂସ୍।"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ଲକ୍‌ ସ୍କ୍ରୀନ୍‌।"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ପ୍ରୋଫାଇଲ୍ ନିରୀକ୍ଷଣ କରାଯାଇପାରେ।"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ନେଟ୍‌ୱର୍କ ନୀରିକ୍ଷଣ କରାଯାଇପାରେ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ନେଟ୍‌ୱର୍କକୁ ନିରୀକ୍ଷଣ କରାଯାଇପାରେ"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ବାପାମାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ଏହି ଡିଭାଇସର ମାଲିକାନା ଆପଣଙ୍କ ସଂସ୍ଥା ପାଖରେ ଅଛି ଏବଂ ଏହା ନେଟୱାର୍କ ଟ୍ରାଫିକର ନିରୀକ୍ଷଣ କରିପାରେ"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ ଏବଂ ଏହା ନେଟୱାର୍କ ଟ୍ରାଫିକକୁ ନିରୀକ୍ଷଣ କରିପାରେ"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ ଏବଂ ଏହା <xliff:g id="VPN_APP">%1$s</xliff:g> ସହ ସଂଯୁକ୍ତ ଅଛି"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN ଅକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN ବିଛିନ୍ନ କରନ୍ତୁ"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ପଲିସୀ ଦେଖନ୍ତୁ"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ।\n\nଆପଣଙ୍କ IT ଆଡମିନ୍ ସେଟିଂସ୍, କର୍ପୋରେଟ୍ ଆକ୍ସେସ୍, ଆପ୍ସ, ଆପଣଙ୍କ ଡିଭାଇସ୍ ସହ ସମ୍ବନ୍ଧିତ ଡାଟା ଏବଂ ଆପଣଙ୍କ ଡିଭାଇସର ଲୋକେସନ୍ ସୂଚନାକୁ ନିରୀକ୍ଷଣ ଏବଂ ପରିଚାଳନା କରିପାରିବେ।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ।\n\nଆପଣଙ୍କ IT ଆଡମିନ୍ ସେଟିଂସ୍, କର୍ପୋରେଟ୍ ଆକ୍ସେସ୍, ଆପ୍ସ, ଆପଣଙ୍କ ଡିଭାଇସ୍ ସହ ସମ୍ବନ୍ଧିତ ଡାଟା ଏବଂ ଆପଣଙ୍କ ଡିଭାଇସର ଲୋକେସନ୍ ସୂଚନାକୁ ନିରୀକ୍ଷଣ ଏବଂ ପରିଚାଳନା କରିପାରିବେ।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ଏହି ଡିଭାଇସରେ ଆପଣଙ୍କ ସଂସ୍ଥା ଏକ ସର୍ଟିଫିକେଟ୍‍ ଅଥରିଟି ଇନଷ୍ଟଲ୍‍ କରିଛନ୍ତି। ଆପଣଙ୍କ ସୁରକ୍ଷିତ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କିମ୍ବା ସଂଶୋଧନ କରାଯାଇ ପାରେ।"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"ଆପଣଙ୍କ ଆଡମିନ୍‍ ନେଟ୍‌ୱର୍କ ଲଗଇନ୍‍ କରିବା ଅନ୍‍ କରିଛନ୍ତି, ଯାହା ଆପଣଙ୍କ ଡିଭାଇସରେ ଟ୍ରାଫିକ୍‍ ନିରୀକ୍ଷଣ କରେ।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ନିଜ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"ଏକ VPN ସଂଯୋଗ ସେଟ୍‍ ଅପ୍‍ କରିବା ପାଇଁ ଆପଣ ଗୋଟିଏ ଆପକୁ ଅନୁମତି ଦେଲେ।\n\nଏହି ଆପ୍‍ ଇମେଲ୍‍, ଆପ୍‌ ଓ ୱେବସାଇଟ୍‍ ସମେତ ଆପଣଙ୍କ ଡିଭାଇସ୍‍ ଓ ନେଟ୍‌ୱର୍କ ଗତିବିଧିକୁ ନିରୀକ୍ଷଣ କରିପାରେ।"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"ଆପଣଙ୍କ ୱର୍କ ପ୍ରୋଫାଇଲ୍‍ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳନା କରାଯାଉଛି।\n\nଆପଣଙ୍କ ଆଡମିନ୍‍ ଇମେଲ୍‍, ଆପ୍‌ ଓ ୱେବସାଇଟ୍‍ ସମେତ ଆପଣଙ୍କ ନେଟୱର୍କ ଗତିବିଧିକୁ ନିରୀକ୍ଷଣ କରିପାରିବେ।\n\nଅଧିକ ସୂଚନା ପାଇଁ, ନିଜ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।.\n\nଆପଣ ଏକ VPNରେ ମଧ୍ୟ ସଂଯୁକ୍ତ, ଯାହା ଆପଣଙ୍କ ନେଟୱର୍କ ଗତିବିଧିକୁ ନିରୀକ୍ଷଣ କରିପାରେ।"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ବାପାମାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ। ଆପଣଙ୍କ ବାପାମା ଆପଣ ବ୍ୟବହାର କରୁଥିବା ଆପ୍ସ, ଆପଣଙ୍କ ଲୋକେସନ୍ ଓ ସ୍କ୍ରିନ୍ ସମୟ ପରି ସୂଚନା ଦେଖିପାରିବେ ଏବଂ ପରିଚାଳନା କରିପାରିବେ।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"ଆପଣ <xliff:g id="APPLICATION">%1$s</xliff:g>ରେ ସଂଯୁକ୍ତ, ଯାହା ଇମେଲ୍‍, ଆପ୍‌ ଓ ୱେବସାଇଟ୍‍ ସମେତ ଆପଣଙ୍କ ନେଟୱର୍କ ଗତିବିଧିକୁ ନିରୀକ୍ଷଣ କରିପାରେ।"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"ଆପଣ <xliff:g id="APPLICATION">%1$s</xliff:g>ରେ ସଂଯୁକ୍ତ, ଯାହା ଇମେଲ୍‍, ଆପ୍‌ ଓ ୱେବସାଇଟ୍‍ ସମେତ ଆପଣଙ୍କ ନେଟ୍‌ୱର୍କ ଗତିବିଧିକୁ ନିରୀକ୍ଷଣ କରିପାରେ।"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ଏହି ଆପ୍‌ରୁ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଦେଖାଇବା ଜାରି ରଖିବେ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ନୀରବ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ଡିଫଲ୍ଟ"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"ବବଲ୍"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ସ୍ୱଚାଳିତ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"କୌଣସି ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ନାହିଁ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"କୌଣସି ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ନାହିଁ ଏବଂ ବାର୍ତ୍ତାଳାପ ବିଭାଗର ନିମ୍ନରେ ଦେଖାଯାଏ"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ସେଟିଂସ୍"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ପ୍ରାଥମିକତା"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବାର୍ତ୍ତାଳାପ ଫିଚରଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ ନାହିଁ"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ବର୍ତ୍ତମାନ କୌଣସି ବବଲ୍ ନାହିଁ"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"ବର୍ତ୍ତମାନର ଏବଂ ଖାରଜ କରାଯାଇଥିବା ବବଲଗୁଡ଼ିକ ଏଠାରେ ଦେଖାଯିବ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ଏଠାରେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଗ୍ରୁପ୍ କନଫ୍ୟୁଗର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ବିଜ୍ଞପ୍ତି ପ୍ରକ୍ସୀ ହୋଇଛି"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"ଡିଭାଇସ୍‍ ସେବାଗୁଡିକ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"କୌଣସି ଶୀର୍ଷକ ନାହିଁ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ଏହି ଆପ୍‌କୁ ରିଷ୍ଟାର୍ଟ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ ଏବଂ ଫୁଲ୍‌ସ୍କ୍ରିନ୍‌କୁ ଯାଆନ୍ତୁ।"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବବଲ୍‌ଗୁଡ଼ିକ ପାଇଁ ସେଟିଂସ୍"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ଓଭରଫ୍ଲୋ"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ଷ୍ଟାକରେ ପୁଣି ଯୋଗ କରନ୍ତୁ"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"ପରିଚାଳନା କରନ୍ତୁ"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>ରୁ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> ଏବଂ ଅଧିକ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>ଟିରୁ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ନିଅନ୍ତୁ"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ଉପର ବାମକୁ ନିଅନ୍ତୁ"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ଉପର-ଡାହାଣକୁ ନିଅନ୍ତୁ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ତଳ ବାମକୁ ନିଅନ୍ତୁ"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ତଳ ଡାହାଣକୁ ନିଅନ୍ତୁ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ବବଲ୍ ଖାରଜ କରନ୍ତୁ"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"ବାର୍ତ୍ତାଳାପକୁ ବବଲ୍ କରନ୍ତୁ ନାହିଁ"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"ବବଲଗୁଡ଼ିକୁ ବ୍ୟବହାର କରି ଚାଟ୍ କରନ୍ତୁ"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"ନୂଆ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ଫ୍ଲୋଟିଂ ଆଇକନ୍ କିମ୍ବା ବବଲ୍ ଭାବେ ଦେଖାଯିବ। ବବଲ୍ ଖୋଲିବାକୁ ଟାପ୍ କରନ୍ତୁ। ଏହାକୁ ମୁଭ୍ କରିବାକୁ ଟାଣନ୍ତୁ।"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ଯେ କୌଣସି ସମୟରେ ବବଲଗୁଡ଼ିକ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ଏହି ଆପର ବବଲଗୁଡ଼ିକ ବନ୍ଦ କରିବା ପାଇଁ \'ପରିଚାଳନା କରନ୍ତୁ\' ବଟନରେ ଟାପ୍ କରନ୍ତୁ"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ବୁଝିଗଲି"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ସେଟିଂସ୍"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍‌କୁ ଯାଆନ୍ତୁ।"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍‍କୁ ଯାଆନ୍ତୁ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ଷ୍ଟାଣ୍ଡବାଏ"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ନୂଆ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ମିଟର୍ ପଢ଼ିବାରେ ସମସ୍ୟା ହେଉଛି"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings_tv.xml b/packages/SystemUI/res/values-or/strings_tv.xml
index b44dc3b..36623b8 100644
--- a/packages/SystemUI/res/values-or/strings_tv.xml
+++ b/packages/SystemUI/res/values-or/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"ମାଇକ୍ରୋଫୋନ୍ ସକ୍ରିୟ"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ଆପଣଙ୍କର ମାଇକ୍ରୋଫୋନ୍‌କୁ ଆକ୍ସେସ୍ କରିଛି"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 13f4506..9eac7df 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੁਬਾਰਾ ਲੈ ਕੇ ਦੇਖੋ"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"ਸੀਮਿਤ ਸਟੋਰੇਜ ਹੋਣ ਕਾਰਨ ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਖਾਰਜ ਕਰੋ"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਪੂਰਵ-ਝਲਕ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"ਬੈਟਰੀ ਦੋ ਬਾਰਸ।"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"ਬੈਟਰੀ ਤਿੰਨ ਬਾਰਸ।"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"ਬੈਟਰੀ ਪੂਰੀ।"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ਬੈਟਰੀ ਪ੍ਰਤੀਸ਼ਤ ਅਗਿਆਤ ਹੈ।"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ਕੋਈ ਫ਼ੋਨ ਨਹੀਂ।"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ਫ਼ੋਨ ਇੱਕ ਬਾਰ।"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ਫ਼ੋਨ ਦੋ ਬਾਰਸ।"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ਸੂਚਨਾ ਰੱਦ ਕੀਤੀ।"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ਸੂਚਨਾ ਸ਼ੇਡ।"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ।"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">" ਲਾਕ  ਸਕ੍ਰੀਨ।"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ਪ੍ਰੋਫਾਈਲ ਦਾ ਨਿਰੀਖਣ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ਨੈੱਟਵਰਕ ਦਾ ਨਿਰੀਖਣ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ਹੋ ਸਕਦਾ ਹੈ ਨੈੱਟਵਰਕ ਦੀ ਨਿਗਰਾਨੀ ਹੋ ਰਹੀ ਹੋਵੇ"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ ਅਤੇ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ਨੀਤੀਆਂ ਦੇਖੋ"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ਕੰਟਰੋਲ ਦੇਖੋ"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ।\n\nਤੁਹਾਡਾ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡਾਟੇ ਅਤੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ।\n\nਤੁਹਾਡਾ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਾਂ, ਡਾਟੇ ਅਤੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਦੀ ਨਿਗਰਾਨੀ ਅਤੇ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਸਥਾਪਤ ਕੀਤੀ ਗਈ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗਿੰਗ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਨੂੰ ਇੱਕ VPN ਕਨੈਕਸ਼ਨ ਸੈੱਟ ਅੱਪ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੱਤੀ ਹੈ।\n\nਇਹ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਅਤੇ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ, ਈਮੇਲਾਂ, ਐਪਾਂ ਅਤੇ ਸੁਰੱਖਿਅਤ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ।"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਈਮੇਲ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰਨ ਦੇ ਸਮਰੱਥ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।\n\nਤੁਸੀਂ ਇੱਕ VPN ਨਾਲ ਵੀ ਕਨੈਕਟ ਹੋਂ, ਜੋ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਤੁਹਾਡੀਆਂ ਐਪਾਂ ਦੀ ਵਰਤੋਂ, ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਅਤੇ ਤੁਹਾਡੇ ਸਕ੍ਰੀਨ ਸਮੇਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਦੇਖ ਅਤੇ ਉਸਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦੇ ਹਨ।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"ਤੁਸੀਂ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"ਤੁਸੀਂ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲ, ਐਪਸ ਅਤੇ ਵੈਬਸਫ਼ਿਆਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ।"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ਕੀ ਇਸ ਐਪ ਤੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ਸ਼ਾਂਤ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"ਬੁਲਬੁਲਾ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ਸਵੈਚਲਿਤ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਵਿੱਚ ਹੇਠਲੇ ਪਾਸੇ ਦਿਸਦੀਆਂ ਹਨ"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ਤਰਜੀਹ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਗੱਲਬਾਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ਕੋਈ ਹਾਲੀਆ ਬਬਲ ਨਹੀਂ"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"ਹਾਲੀਆ ਬਬਲ ਅਤੇ ਖਾਰਜ ਕੀਤੇ ਬਬਲ ਇੱਥੇ ਦਿਸਣਗੇ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ਇਹ ਸੂਚਨਾਵਾਂ ਦਾ ਗਰੁੱਪ ਇੱਥੇ ਸੰਰੂਪਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ਇੱਕ ਐਪ ਦੀ ਥਾਂ \'ਤੇ ਦੂਜੀ ਐਪ ਰਾਹੀਂ ਦਿੱਤੀ ਗਈ ਸੂਚਨਾ"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਪੂਰੀ-ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਓ।"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਬਬਲ ਲਈ ਸੈਟਿੰਗਾਂ"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ਓਵਰਫ਼ਲੋ"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ਸਟੈਕ ਵਿੱਚ ਵਾਪਸ ਸ਼ਾਮਲ ਕਰੋ"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> ਤੋਂ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> ਅਤੇ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ਹੋਰਾਂ ਤੋਂ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ਲਿਜਾਓ"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ਉੱਪਰ ਵੱਲ ਖੱਬੇ ਲਿਜਾਓ"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ਉੱਪਰ ਵੱਲ ਸੱਜੇ ਲਿਜਾਓ"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ਹੇਠਾਂ ਵੱਲ ਖੱਬੇ ਲਿਜਾਓ"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ਹੇਠਾਂ ਵੱਲ ਸੱਜੇ ਲਿਜਾਓ"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕਰੋ"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"ਗੱਲਬਾਤ \'ਤੇ ਬਬਲ ਨਾ ਲਾਓ"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"ਬਬਲ ਵਰਤਦੇ ਹੋਏ ਚੈਟ ਕਰੋ"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"ਨਵੀਆਂ ਗੱਲਾਂਬਾਤਾਂ ਫਲੋਟਿੰਗ ਪ੍ਰਤੀਕਾਂ ਜਾਂ ਬਬਲ ਦੇ ਰੂਪ ਵਿੱਚ ਦਿਸਦੀਆਂ ਹਨ। ਬਬਲ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ। ਇਸਨੂੰ ਲਿਜਾਣ ਲਈ ਘਸੀਟੋ।"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ਬਬਲ ਨੂੰ ਕਿਸੇ ਵੇਲੇ ਵੀ ਕੰਟਰੋਲ ਕਰੋ"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ਇਸ ਐਪ \'ਤੇ ਬਬਲ ਬੰਦ ਕਰਨ ਲਈ \'ਪ੍ਰਬੰਧਨ ਕਰੋ\' \'ਤੇ ਟੈਪ ਕਰੋ"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ਸਮਝ ਲਿਆ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ਸੈਟਿੰਗਾਂ"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ਤੁਹਾਡੇ ਬੈਟਰੀ ਮੀਟਰ ਨੂੰ ਪੜ੍ਹਨ ਵਿੱਚ ਸਮੱਸਿਆ ਹੋ ਰਹੀ ਹੈ"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings_tv.xml b/packages/SystemUI/res/values-pa/strings_tv.xml
index f5300b3..b623fea 100644
--- a/packages/SystemUI/res/values-pa/strings_tv.xml
+++ b/packages/SystemUI/res/values-pa/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਕਿਰਿਆਸ਼ੀਲ"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ਨੇ ਤੁਹਾਡੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 6da167d..1c6b6a1 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Spróbuj jeszcze raz wykonać zrzut ekranu"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Nie można zapisać zrzutu ekranu, bo brakuje miejsca w pamięci"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Nie możesz wykonać zrzutu ekranu, bo nie zezwala na to aplikacja lub Twoja organizacja."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Edytuj zrzut ekranu"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Zamknij zrzut ekranu"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Edytuj"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Edytuj zrzut ekranu"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Przewiń"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Przewiń zrzut ekranu"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Zamknij zrzut ekranu"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Podgląd zrzutu ekranu"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Nagrywanie ekranu"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Bateria: dwa paski."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Bateria: trzy paski."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Bateria naładowana."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Poziom naładowania baterii jest nieznany."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Brak sygnału telefonu."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon: jeden pasek."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon: dwa paski."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Zamknięto powiadomienie."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Zamknięto dymek"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Obszar powiadomień."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Szybkie ustawienia."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ekran blokady."</string>
@@ -526,6 +529,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil może być monitorowany"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Sieć może być monitorowana"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Sieć może być monitorowana"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tym urządzeniem zarządza Twój rodzic"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Twoja organizacja jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"To urządzenie należy do Twojej organizacji i jest połączone z siecią <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -550,6 +554,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Wyłącz VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Rozłącz z VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobacz zasady"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Wyświetl elementy sterujące"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"To urządzenie należy do organizacji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrator IT może monitorować ustawienia, firmowe uprawnienia dostępu, aplikacje, dane dotyczące urządzenia i lokalizacji oraz nimi zarządzać.\n\nAby dowiedzieć się więcej, skontaktuj się z administratorem IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"To urządzenie należy do Twojej organizacji.\n\nAdministrator IT może monitorować ustawienia, firmowe uprawnienia dostępu, aplikacje, dane dotyczące urządzenia i lokalizacji oraz nimi zarządzać.\n\nAby dowiedzieć się więcej, skontaktuj się z administratorem IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Twoja organizacja zainstalowała urząd certyfikacji na tym urządzeniu. Zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string>
@@ -573,6 +578,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administrator włączył rejestrowanie sieciowe, które pozwala monitorować ruch na Twoim urządzeniu.\n\nAby dowiedzieć się więcej, skontaktuj się z administratorem."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Aplikacja otrzymała od Ciebie uprawnienia do konfigurowania połączenia VPN.\n\nMoże ona monitorować Twoją aktywność na urządzeniu i w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Twoim profilem do pracy zarządza <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrator może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe.\n\nAby dowiedzieć się więcej, skontaktuj się z administratorem.\n\nŁączysz się też z siecią VPN, która może monitorować Twoją aktywność w sieci."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Tym urządzeniem zarządza Twój rodzic. Rodzic może zobaczyć różne informacje, np. o aplikacjach, których używasz, lokalizacji i czasie korzystania z urządzenia, a także zarządzać tymi danymi."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Łączysz się z aplikacją <xliff:g id="APPLICATION">%1$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Masz połączenie z aplikacją <xliff:g id="APPLICATION">%1$s</xliff:g>, która może monitorować Twoją prywatną aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
@@ -715,7 +721,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Nadal pokazywać powiadomienia z tej aplikacji?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Bez dźwięku"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Domyślne"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Dymek"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatycznie"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Brak dźwięku i wibracji"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Brak dźwięku i wibracji, wyświetla się niżej w sekcji rozmów"</string>
@@ -727,8 +732,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ustawienia"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorytet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje funkcji rozmów"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Brak ostatnich dymków"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Tutaj będą pojawiać się ostatnie i odrzucone dymki"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tych powiadomień nie można zmodyfikować."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Tej grupy powiadomień nie można tu skonfigurować"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Powiadomienie w zastępstwie"</string>
@@ -991,25 +994,7 @@
     <string name="device_services" msgid="1549944177856658705">"Usługi urządzenia"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez tytułu"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Kliknij, by uruchomić tę aplikację ponownie i przejść w tryb pełnoekranowy."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Ustawienia dymków aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Przepełnienie"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodaj ponownie do stosu"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Zarządzaj"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikacji <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikacji <xliff:g id="APP_NAME">%2$s</xliff:g> i jeszcze <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Przenieś"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Przenieś w lewy górny róg"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Przenieś w prawy górny róg"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Przenieś w lewy dolny róg"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Przenieś w prawy dolny róg"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Zamknij dymek"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nie wyświetlaj rozmowy jako dymka"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Czatuj, korzystając z dymków"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nowe rozmowy będą wyświetlane jako pływające ikony lub dymki. Kliknij, by otworzyć dymek. Przeciągnij, by go przenieść."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Zarządzaj dymkami w dowolnym momencie"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Kliknij Zarządzaj, aby wyłączyć dymki z tej aplikacji"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – ustawienia"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Nawigacja w systemie została zaktualizowana. Aby wprowadzić zmiany, otwórz Ustawienia."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Otwórz Ustawienia, by zaktualizować nawigację w systemie"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tryb gotowości"</string>
@@ -1101,4 +1086,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sparuj nowe urządzenie"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem z odczytaniem pomiaru wykorzystania baterii"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Kliknij, aby uzyskać więcej informacji"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml
index b060141..2c80194 100644
--- a/packages/SystemUI/res/values-pl/strings_tv.xml
+++ b/packages/SystemUI/res/values-pl/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon aktywny"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacja %1$s uzyskała dostęp do mikrofonu"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 0db05d8..d058eddb 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tente fazer a captura de tela novamente"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Não é possível salvar a captura de tela, porque não há espaço suficiente"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"O app ou a organização não permitem capturas de tela"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Editar captura de tela"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Dispensar captura de tela"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de tela"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Rolar"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Captura de tela da página inteira"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dispensar captura de tela"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Visualização de captura de tela"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de tela"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Duas barras de bateria."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Três barras de bateria."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Bateria cheia."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentagem da bateria desconhecida."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Sem telefone."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Uma barra de sinal do telefone."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Duas barras de sinal do telefone."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notificação dispensada."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Balão dispensado."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Aba de notificações."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configurações rápidas."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Tela de bloqueio."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"O perfil pode ser monitorado"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"A rede pode ser monitorada"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"A rede pode ser monitorada"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu pai/mãe"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua organização e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Desativar VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Controles de visualização"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua organização.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Sua organização instalou uma autoridade de certificação neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Seu administrador ativou o registro de rede, que monitora o tráfego no seu dispositivo.\n\nPara ver mais informações, entre em contato com o administrador."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Você deu permissão para um app configurar uma conexão VPN.\n\nEsse app pode monitorar seu dispositivo e a atividade na rede, incluindo e-mails, apps e websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSeu administrador pode monitorar sua atividade de rede, incluindo e-mails, apps e websites.\n\nPara ver mais informações, entre em contato com o administrador.\n\nVocê também está conectado a uma VPN, que pode monitorar sua atividade de rede."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerenciado pelo seu pai/mãe, que pode ver e gerenciar informações como os apps que você usa, sua localização e seu tempo de uso."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade de rede, incluindo e-mails, apps e websites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade pessoal na rede, incluindo e-mails, apps e websites."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Continuar mostrando notificações desse app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Padrão"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bolha"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Som e vibração desativados"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"O som e a vibração estão desativados, e o balão aparece na parte inferior da seção de conversa"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configurações"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nenhum balão recente"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Os balões recentes e dispensados aparecerão aqui"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar esse grupo de notificações aqui"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificação salva no proxy"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toque para reiniciar o app e usar tela cheia."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Configurações de balões do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menu flutuante"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Devolver à pilha"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gerenciar"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> mais <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Mover para canto superior esquerdo"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Mover para canto superior direito"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Mover para canto inferior esquerdo"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Mover para canto inferior direito"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Dispensar balão"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Não criar balões de conversa"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Converse usando balões"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Novas conversas aparecerão como ícones flutuantes, ou balões. Toque para abrir o balão. Arraste para movê-lo."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controle os balões a qualquer momento"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toque em \"Gerenciar\" para desativar os balões desse app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ok"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Configurações de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Acesse as configurações para atualizar a navegação no sistema"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
index 19cb4ea..2b76a8c 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microfone ativado"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s acessou seu microfone"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 147ed1d..4c97018 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Experimente voltar a efetuar a captura de ecrã."</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Não é possível guardar a captura de ecrã devido a espaço de armazenamento limitado."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"A app ou a sua entidade não permitem tirar capturas de ecrã"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Editar captura de ecrã"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ignorar captura de ecrã"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pré-visualização da captura de ecrã"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de ecrã"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"A processar a gravação de ecrã"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Duas barras de bateria."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Três barras de bateria."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Bateria carregada."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentagem da bateria desconhecida."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Sem telefone."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Uma barra de telefone."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Duas barras de telefone."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notificação ignorada."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Balão ignorado."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Painel de notificações."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Definições rápidas."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ecrã de bloqueio."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"O perfil pode ser monitorizado"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"A rede pode ser monitorizada"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"A rede pode ser monitorizada"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerido pelos teus pais"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede."</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é proprietária deste dispositivo e pode monitorizar o tráfego de rede."</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua entidade e está ligado a <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Desativar a VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Desligar VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver Políticas"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ver controlos"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorizar e gerir as definições, o acesso empresarial, as apps, os dados associados ao dispositivo e as informações de localização do mesmo.\n\nContacte o administrador de TI para obter mais informações."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua entidade.\n\nO administrador de TI pode monitorizar e gerir as definições, o acesso empresarial, as apps, os dados associados ao dispositivo e as informações de localização do mesmo.\n\nContacte o administrador de TI para obter mais informações."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"A sua entidade instalou uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"O seu gestor ativou os registos de rede, que monitorizam o tráfego no seu dispositivo.\n\nPara obter mais informações, contacte o gestor."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Concedeu autorização a uma app para configurar uma ligação VPN.\n\nEsta app pode monitorizar a atividade do dispositivo e da rede, incluindo emails, aplicações e Sites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"O seu perfil de trabalho é gerido por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nO seu gestor tem a capacidade de monitorizar a sua atividade da rede, incluindo emails, aplicações e Sites.\n\nPara obter mais informações, contacte o gestor.\n\nAlém disso, está ligado a uma VPN, que pode monitorizar a sua atividade da rede."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerido pelos teus pais. Estes podem ver e gerir informações como as apps que utilizas, a tua localização e o tempo de utilização."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Está associado à app <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Está ligado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Pretende continuar a ver notificações desta app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predefinição"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Balão"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sem som ou vibração"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sem som ou vibração e aparece na parte inferior na secção de conversas."</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Definições"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> não suporta funcionalidades de conversa."</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nenhum balão recente"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Os balões recentes e ignorados vão aparecer aqui."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar estas notificações."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar este grupo de notificações aqui."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificação de app proxy"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toque para reiniciar esta app e ficar em ecrã inteiro."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Definições dos balões da app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menu adicional"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Adicionar novamente à pilha"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gerir"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> do <xliff:g id="APP_NAME">%2$s</xliff:g> e mais<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>."</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Mover p/ parte sup. esquerda"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Mover parte superior direita"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Mover p/ parte infer. esquerda"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Mover parte inferior direita"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Ignorar balão"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Não apresentar a conversa em balões"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Converse no chat através de balões"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"As novas conversas aparecem como ícones flutuantes ou balões. Toque para abrir o balão. Arraste para o mover."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controle os balões em qualquer altura"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toque em Gerir para desativar os balões desta app."</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Definições de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A navegação no sistema foi atualizada. Para efetuar alterações, aceda às Definições."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Aceda às Definições para atualizar a navegação no sistema."</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sincronize o novo dispositivo"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ocorreu um problema ao ler o medidor da bateria"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para obter mais informações"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
index 2e60421..ea551d4 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microfone ativado"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s acedeu ao microfone"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 0db05d8..d058eddb 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tente fazer a captura de tela novamente"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Não é possível salvar a captura de tela, porque não há espaço suficiente"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"O app ou a organização não permitem capturas de tela"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Editar captura de tela"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Dispensar captura de tela"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de tela"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Rolar"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Captura de tela da página inteira"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dispensar captura de tela"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Visualização de captura de tela"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de tela"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Duas barras de bateria."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Três barras de bateria."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Bateria cheia."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentagem da bateria desconhecida."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Sem telefone."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Uma barra de sinal do telefone."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Duas barras de sinal do telefone."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notificação dispensada."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Balão dispensado."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Aba de notificações."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configurações rápidas."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Tela de bloqueio."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"O perfil pode ser monitorado"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"A rede pode ser monitorada"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"A rede pode ser monitorada"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu pai/mãe"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Este dispositivo pertence à sua organização e está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Desativar VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Desconectar VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Ver políticas"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Controles de visualização"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Este dispositivo pertence à sua organização.\n\nO administrador de TI pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações de local do dispositivo.\n\nPara saber mais, entre em contato com seu administrador de TI."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Sua organização instalou uma autoridade de certificação neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Seu administrador ativou o registro de rede, que monitora o tráfego no seu dispositivo.\n\nPara ver mais informações, entre em contato com o administrador."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Você deu permissão para um app configurar uma conexão VPN.\n\nEsse app pode monitorar seu dispositivo e a atividade na rede, incluindo e-mails, apps e websites."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSeu administrador pode monitorar sua atividade de rede, incluindo e-mails, apps e websites.\n\nPara ver mais informações, entre em contato com o administrador.\n\nVocê também está conectado a uma VPN, que pode monitorar sua atividade de rede."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerenciado pelo seu pai/mãe, que pode ver e gerenciar informações como os apps que você usa, sua localização e seu tempo de uso."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade de rede, incluindo e-mails, apps e websites."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade pessoal na rede, incluindo e-mails, apps e websites."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Continuar mostrando notificações desse app?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Padrão"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bolha"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Som e vibração desativados"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"O som e a vibração estão desativados, e o balão aparece na parte inferior da seção de conversa"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configurações"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nenhum balão recente"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Os balões recentes e dispensados aparecerão aqui"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar esse grupo de notificações aqui"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificação salva no proxy"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toque para reiniciar o app e usar tela cheia."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Configurações de balões do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menu flutuante"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Devolver à pilha"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gerenciar"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> mais <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mover"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Mover para canto superior esquerdo"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Mover para canto superior direito"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Mover para canto inferior esquerdo"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Mover para canto inferior direito"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Dispensar balão"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Não criar balões de conversa"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Converse usando balões"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Novas conversas aparecerão como ícones flutuantes, ou balões. Toque para abrir o balão. Arraste para movê-lo."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controle os balões a qualquer momento"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toque em \"Gerenciar\" para desativar os balões desse app"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ok"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Configurações de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Acesse as configurações para atualizar a navegação no sistema"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml
index 19cb4ea..2b76a8c 100644
--- a/packages/SystemUI/res/values-pt/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microfone ativado"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s acessou seu microfone"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 24e71fb..d2c5a0b 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Încercați să faceți din nou o captură de ecran"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Captura de ecran nu poate fi salvată din cauza spațiului de stocare limitat"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Crearea capturilor de ecran nu este permisă de aplicație sau de organizația dvs."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Editați captura de ecran"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Închideți captura de ecran"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Previzualizare a capturii de ecran"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Recorder pentru ecran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Se procesează înregistrarea"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Baterie: două bare."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Baterie: trei bare."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Baterie: complet."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procentajul bateriei este necunoscut."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nu există semnal pentru telefon."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Semnal pentru telefon: o bară."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Semnal pentru telefon: două bare."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notificarea a fost închisă."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Balonul a fost respins."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Fereastră pentru notificări."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Setări rapide."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ecranul de blocare."</string>
@@ -523,6 +531,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profilul poate fi monitorizat"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Rețeaua poate fi monitorizată"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Este posibil ca rețeaua să fie monitorizată"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dispozitivul este gestionat de unul dintre părinți"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizația dvs. deține acest dispozitiv și poate monitoriza traficul de rețea"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> deține acest dispozitiv și poate monitoriza traficul din rețea"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Dispozitivul aparține organizației dvs. și este conectat la <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -547,6 +556,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Dezactivați conexiunea prin VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Deconectați rețeaua VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afișați politicile"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Vedeți opțiunile"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Dispozitivul aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratorul dvs. IT poate să monitorizeze și să gestioneze setările, accesul la nivelul companiei, aplicațiile, datele asociate dispozitivului și informațiile despre locația dispozitivului.\n\nPentru mai multe informații, contactați administratorul IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Dispozitivul aparține organizației dvs.\n\nAdministratorul dvs. IT poate să monitorizeze și să gestioneze setările, accesul la nivelul companiei, aplicațiile, datele asociate dispozitivului și informațiile despre locația dispozitivului.\n\nPentru mai multe informații, contactați administratorul IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizația dvs. a instalat un certificat CA pe acest dispozitiv. Traficul dvs. sigur de rețea poate fi monitorizat sau modificat."</string>
@@ -570,6 +580,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administratorul dvs. a activat înregistrarea în jurnal pentru rețea, funcție ce monitorizează traficul de pe dispozitivul dvs.\n\nPentru mai multe informații, contactați administratorul."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Ați acordat unei aplicații permisiunea de a configura o conexiune VPN.\n\nAceastă aplicație poate monitoriza activitatea de pe dispozitiv și în rețea, inclusiv e-mailurile, aplicațiile și site-urile."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Profilul dvs. de serviciu este gestionat de <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratorul dvs. vă poate monitoriza activitatea în rețea, inclusiv e-mailurile, aplicațiile și site-urile.\n\nPentru mai multe informații, contactați administratorul.\n\nDe asemenea, sunteți conectat(ă) la o rețea VPN care vă poate monitoriza activitatea în rețea."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Dispozitivul este gestionat de unul dintre părinți. Părintele poate să vadă și să gestioneze informații cum ar fi aplicațiile pe care le folosești, locația ta și durata de folosire a dispozitivului."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"V-ați conectat la <xliff:g id="APPLICATION">%1$s</xliff:g>, care vă poate monitoriza activitatea în rețea, inclusiv e-mailurile, aplicațiile și site-urile accesate."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Sunteți conectat(ă) la <xliff:g id="APPLICATION">%1$s</xliff:g>, care vă poate monitoriza activitatea în rețeaua personală, inclusiv e-mailurile, aplicațiile și site-urile."</string>
@@ -712,7 +723,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Doriți să continuați afișarea notificărilor de la această aplicație?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silențios"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Prestabilite"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Balon"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automat"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Fără sunet sau vibrații"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Fără sunet sau vibrații și apare în partea de jos a secțiunii de conversație"</string>
@@ -724,8 +734,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Setări"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritate"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu acceptă funcții pentru conversații"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nu există baloane recente"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Baloanele recente și baloanele respinse vor apărea aici"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Aceste notificări nu pot fi modificate."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Acest grup de notificări nu poate fi configurat aici"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Notificare prin proxy"</string>
@@ -986,25 +994,7 @@
     <string name="device_services" msgid="1549944177856658705">"Servicii pentru dispozitiv"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Fără titlu"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Atingeți ca să reporniți aplicația și să treceți în modul ecran complet."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Setări pentru baloanele <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Suplimentar"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Adăugați înapoi în stivă"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Gestionați"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de la <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de la <xliff:g id="APP_NAME">%2$s</xliff:g> și încă <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Mutați"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Mutați în stânga sus"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Mutați în dreapta sus"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Mutați în stânga jos"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Mutați în dreapta jos"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Închideți balonul"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nu afișați conversația în balon"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chat cu baloane"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Conversațiile noi apar ca pictograme flotante sau baloane. Atingeți pentru a deschide balonul. Trageți pentru a-l muta."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlați oricând baloanele"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Atingeți Gestionați pentru a dezactiva baloanele din această aplicație"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Setări <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigarea în sistem a fost actualizată. Pentru a face modificări, accesați Setările."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accesați Setările pentru a actualiza navigarea în sistem"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
@@ -1095,4 +1085,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Asociați un nou dispozitiv"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problemă la citirea măsurării bateriei"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Atingeți pentru mai multe informații"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml
index f4349ff9..04b0a07 100644
--- a/packages/SystemUI/res/values-ro/strings_tv.xml
+++ b/packages/SystemUI/res/values-ro/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Microfon activ"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s a accesat microfonul"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 1ca1c80..4c235ed 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Попробуйте сделать скриншот снова."</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Не удалось сохранить скриншот: недостаточно места."</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Не удалось сделать скриншот: нет разрешения от приложения или организации."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Изменить скриншот"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Закрыть скриншот"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Предварительный просмотр скриншота"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запись видео с экрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Заряд батареи: два деления."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Заряд батареи: три деления."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Батарея полностью заряжена."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Уровень заряда батареи в процентах неизвестен."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Сигнал телефонной сети отсутствует."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Сигнал телефонной сети: одно деление."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Сигнал телефонной сети: два деления."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Уведомление закрыто"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Всплывающий чат закрыт."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Панель уведомлений"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Быстрые настройки"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Экран блокировки."</string>
@@ -526,6 +534,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Действия в профиле могут отслеживаться"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Сеть может отслеживаться"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Сеть может отслеживаться"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Этим устройством управляет один из твоих родителей."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" управляет этим устройством и может отслеживать сетевой трафик"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Это устройство принадлежит вашей организации и подключено к приложению \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
@@ -550,6 +559,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Отключить VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Отключить VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Просмотреть политику"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Показать элементы управления"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nВаш системный администратор может управлять настройками, приложениями и параметрами доступа к корпоративным ресурсам на этом устройстве, а также связанными с ним данными (например, сведениями о местоположении).\n\nЗа подробной информацией обращайтесь к системному администратору."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Это устройство принадлежит вашей организации.\n\nСистемный администратор может управлять настройками, приложениями и параметрами доступа к корпоративным ресурсам на этом устройстве, а также связанными с ним данными (например, сведениями о местоположении).\n\nЗа подробной информацией обращайтесь к системному администратору."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ваша организация установила сертификат ЦС на устройство. Она может отслеживать и изменять защищенный сетевой трафик."</string>
@@ -573,6 +583,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Администратор включил ведение сетевого журнала, чтобы отслеживать трафик на вашем устройстве.\n\nДля получения подробной информации обращайтесь к администратору."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Вы разрешили приложению подключаться к сети VPN.\n\nОно может отслеживать ваши действия на устройстве и в Интернете, включая работу с электронной почтой, приложениями и веб-сайтами."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Вашим рабочим профилем управляет <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nАдминистратор может отслеживать ваши действия в сети, в том числе работу с электронной почтой, приложениями и веб-сайтами.\n\nДля получения подробной информации обращайтесь к администратору.\n\nВы также подключены к сети VPN, в которой можно отслеживать ваши действия."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Этим устройством управляет один из твоих родителей. Он может видеть определенные сведения (например, какие приложения ты используешь и где находишься), а также устанавливать определенные настройки (например, ограничивать время использования устройства)."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"Сеть VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Запущено приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\", которое может отслеживать ваши действия в сети, включая работу с электронной почтой, приложениями и веб-сайтами."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Запущено приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\", которое может отслеживать ваши действия в Интернете (выполняемые в личном профиле), включая работу с электронной почтой, приложениями и веб-сайтами."</string>
@@ -715,7 +726,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Показывать уведомления от этого приложения?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Без звука"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"По умолчанию"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Всплывающая подсказка"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматически"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука или вибрации"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звука или вибрации, появляется в нижней части списка разговоров"</string>
@@ -727,8 +737,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Настройки"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" не поддерживает функции разговоров."</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Нет недавних всплывающих чатов"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Здесь будут появляться недавние и скрытые всплывающие чаты."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Эти уведомления нельзя изменить."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Эту группу уведомлений нельзя настроить здесь."</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Уведомление отправлено через прокси-сервер."</string>
@@ -991,25 +999,7 @@
     <string name="device_services" msgid="1549944177856658705">"Сервисы устройства"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без названия"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Нажмите, чтобы перезапустить приложение и перейти в полноэкранный режим."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Настройки всплывающих чатов от приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Дополнительное меню"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Добавить обратно в стек"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Настроить"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из приложения \"<xliff:g id="APP_NAME">%2$s</xliff:g>\""</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> от приложения \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" и ещё <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Перенести"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Перенести в левый верхний угол"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Перенести в правый верхний угол"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Перенести в левый нижний угол"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Перенести в правый нижний угол"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Скрыть всплывающий чат"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не показывать всплывающий чат для разговора"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Всплывающие чаты"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Новые разговоры будут появляться в виде плавающих значков, или всплывающих чатов. Чтобы открыть чат, нажмите на него, а чтобы переместить – перетащите."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Всплывающие чаты"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Чтобы отключить всплывающие чаты из этого приложения, нажмите \"Настроить\"."</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ОК"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: настройки"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Параметры навигации в системе обновлены. Чтобы изменить их, перейдите в настройки."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Чтобы обновить параметры навигации в системе, перейдите в настройки."</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Переход в режим ожидания"</string>
@@ -1101,4 +1091,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не удается получить данные об уровне заряда батареи"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нажмите, чтобы узнать больше."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml
index b8638b7..a9752ee 100644
--- a/packages/SystemUI/res/values-ru/strings_tv.xml
+++ b/packages/SystemUI/res/values-ru/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Микрофон включен"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Приложение \"%1$s\" использовало доступ к микрофону."</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index eb789c1..c855be3 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"තිර රුව නැවත ගැනීමට උත්සාහ කරන්න"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"සීමිත ගබඩා ඉඩ නිසා තිර රුව සුරැකිය නොහැකිය"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"තිර රූ ගැනීමට යෙදුම හෝ ඔබගේ සංවිධානය ඉඩ නොදේ"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"තිර රුව සංස්කරණය කරන්න"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"තිර රුව ඉවත ලන්න"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"සංස්කරණය කරන්න"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"තිර රුව සංස්කරණය කරන්න"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"අනුචලනය කරන්න"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"තිර රුව අනුචලනය කරන්න"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"තිර රුව ඉවත ලන්න"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"තිර රූ පෙර දසුන"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"තිර රෙකෝඩරය"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"තිර පටිගත කිරීම සකසමින්"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"බැටරිය තීරු දෙකයි."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"බැටරිය තීරු තුනයි."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"බැටරිය පිරී ඇත."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"බැටරි ප්‍රතිශතය නොදනී."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"දුරකථනයක් නැත."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"දුරකථනය තීරු එකයි."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"දුරකථනය තීරු දෙකයි."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"දැනුම්දීම නිෂ්ප්‍රභා කරඇත."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"බුබුල ඉවත දමා ඇත."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"දැනුම්දීම් ආවරණය."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ක්ෂණික සැකසීම්."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"අගුළු තිරය."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ඇතැම් විට පැතිකඩ නිරීක්ෂණය කරන ලදි"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ඇතැම් විට ජාලය නිරීක්ෂණය විය හැක"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ඇතැම් විට ජාලය නිරීක්ෂණය විය හැක"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"මෙම උපාංගය ඔබගේ මාපියන්ගෙන් අයකු විසින් කළමනාකරණය කෙරේ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ඔබේ සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"මෙම උපාංගය ඔබේ සංවිධානයට අයිති අතර <xliff:g id="VPN_APP">%1$s</xliff:g> වෙත සම්බන්ධ කර ඇත"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN අබල කරන්න."</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN විසන්ධි කරන්න"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ප්‍රතිපත්ති පෙන්වන්න"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"පාලන බලන්න"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිතිය.\n\nඔබේ IT පරිපාලකට ඔබේ උපාංගය හා සම්බන්ධිත සැකසීම්, ආයතනික ප්‍රවේශය, යෙදුම්, දත්ත සහ ඔබේ උපාංගයේ ස්ථාන තොරතුරු නිරීක්ෂණය කර කළමනාකරණය කිරීමට හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබේ IT අමතන්න."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය.\n\nඔබේ IT පරිපාලකට ඔබේ උපාංගය හා සම්බන්ධිත සැකසීම්, ආයතනික ප්‍රවේශය, යෙදුම්, දත්ත සහ ඔබේ උපාංගයේ ස්ථාන තොරතුරු නිරීක්ෂණය කර කළමනාකරණය කිරීමට හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබේ IT අමතන්න."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ඔබගේ සංවිධානය ඔබගේ උපාංගය තුළ සහතික අධිකාරියක් ස්ථාපනය කර තිබේ. ඔබගේ ආරක්ෂක ජාල තදබදය නිරීක්ෂණය හෝ වෙනස් කිරීමට පුළුවනි."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"ඔබගේ පරිපාලක ඔබගේ උපාංගය මත තදබදය නිරීක්ෂණය කරන, ජාල ඇතුළු වීම ක්‍රියාත්මක කර ඇත.\n\nවැඩිදුර තොරතුරු සඳහා ඔබේ පරිපාලක අමතන්න."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"ඔබ VPN සම්බන්ධතාවක් පිහිටුවීමට යෙදුමකට අවසරයක් දී ඇත.\n\nමෙම යෙදුමට ඔබේ ඊ-තැපැල්, යෙදුම්, සහ වෙබ් අඩවි ඇතුළු, ඔබගේ උපාංග සහ ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කිරීමට හැකිය."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"ඔබේ කාර්ය පැතිකඩ කළමනාකරණය කරන්නේ <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nඔබේ පරිපාලකට ඔබේ ඊ-තැපැල්, යෙදුම්, සහ වෙබ් අඩවි ඇතුළු, ඔබේ ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකිය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබගේ පරිපාලක අමතන්න.\n\nඔබේ ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, VPN එකකටද ඔබ සබැඳී ඇත"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"මෙම උපාංගය ඔබගේ මාපියන් විසින් කළමනාකරණය කෙරේ. ඔබ භාවිත කරන යෙදුම්, ඔබගේ ස්ථානය සහ ඔබගේ තිර කාලය වැනි තොරතුරු ඔබගේ මාපියන්ට බැලීමට සහ කළමනාකරණය කිරීමට හැකිය."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"ඊ-තැපැල්, යෙදුම් සහ වෙබ් අඩවි ඇතුළු ඔබේ ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION">%1$s</xliff:g> වෙත ඔබ සම්බන්ධ වී ඇත."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"ඊ-තැපැල්, යෙදුම් සහ වෙබ් අඩවි ඇතුළු ඔබේ පෞද්ගලික ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION">%1$s</xliff:g> වෙත ඔබ සම්බන්ධ වී ඇත."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"මෙම යෙදුම වෙතින් දැනුම්දීම් පෙන්වමින් තබන්නද?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"නිහඬ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"පෙරනිමි"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"බුබුළු"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ස්වයංක්‍රිය"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"හඬක් හෝ කම්පනයක් නැත"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"හඬක් හෝ කම්පනයක් නැති අතර සංවාද කොටසේ පහළම දිස් වේ"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"සැකසීම්"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ප්‍රමුඛතාව"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> සංවාද විශේෂාංගවලට සහාය නොදක්වයි"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"මෑත බුබුලු නැත"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"මෑත බුබුලු සහ ඉවත ලූ බුබුලු මෙහි දිස් වනු ඇත"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"මෙම දැනුම්දීම් වෙනස් කළ නොහැක."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"මෙම දැනුම්දීම් සමූහය මෙහි වින්‍යාස කළ නොහැක"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ප්‍රොක්සි කළ දැනුම්දීම"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"උපාංග සේවා"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"මාතෘකාවක් නැත"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"මෙම යෙදුම යළි ඇරඹීමට සහ පූර්ණ තිරයට යාමට තට්ටු කරන්න"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> බුබුළු සඳහා සැකසීම්"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"පිටාර යාම"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"අට්ටිය වෙත ආපසු එක් කරන්න"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"කළමනා කරන්න"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> වෙතින් <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> වෙතින් <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> සහ තවත් <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ක්"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ගෙන යන්න"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ඉහළ වමට ගෙන යන්න"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ඉහළ දකුණට ගෙන යන්න"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"පහළ වමට ගෙන යන්න"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"පහළ දකුණට ගෙන යන්න"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"බුබුලු ඉවත ලන්න"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"සංවාදය බුබුලු නොදමන්න"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"බුබුලු භාවිතයෙන් කතාබහ කරන්න"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"නව සංවාද පාවෙන අයිකන හෝ බුබුලු ලෙස දිස් වේ. බුබුල විවෘත කිරීමට තට්ටු කරන්න. එය ගෙන යාමට අදින්න."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ඕනෑම වේලාවක බුබුලු පාලනය කරන්න"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"මෙම යෙදුමෙන් බුබුලු ක්‍රියාවිරහිත කිරීමට කළමනාකරණය කරන්න තට්ටු කරන්න"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"තේරුණා"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> සැකසීම්"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"පොරොත්තු"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"නව උපාංගය යුගල කරන්න"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ඔබගේ බැටරි මනුව කියවීමේ දෝෂයකි"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings_tv.xml b/packages/SystemUI/res/values-si/strings_tv.xml
index 411c0a0..a1ac371 100644
--- a/packages/SystemUI/res/values-si/strings_tv.xml
+++ b/packages/SystemUI/res/values-si/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"මයික්‍රොෆෝනය සක්‍රියයි"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ඔබේ මයික්‍රොෆෝනයට ප්‍රවේශ වී ඇත"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9ec0771..63a31ce 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Skúste snímku urobiť znova"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Snímka obrazovky sa nedá uložiť z dôvodu nedostatku miesta v úložisku"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Vytváranie snímok obrazovky je zakázané aplikáciou alebo vašou organizáciou"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Upraviť snímku obrazovky"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Zavrieť snímku obrazovky"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ukážka snímky obrazovky"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Spracúva sa záznam obrazovky"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Dve čiarky batérie."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Tri čiarky batérie."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batéria je nabitá."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percento batérie nie je známe."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Žiadna telefónna sieť."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Jeden stĺpec signálu telefónnej siete."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Dve čiarky signálu telefónnej siete."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Upozornenie bolo zrušené."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bublina bola zavretá."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Panel upozornení."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Rýchle nastavenia."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Uzamknutá obrazovka"</string>
@@ -526,6 +534,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil môže byť monitorovaný"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Sieť môže byť sledovaná"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Sieť môže byť monitorovaná"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zariadenie spravuje tvoj rodič"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlastní toto zariadenie a môže sledovať sieťovú premávku"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Toto zariadenie patrí vašej organizácii a je pripojené k sieti <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -550,6 +559,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Deaktivovať VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Odpojiť sieť VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Zobraziť pravidlá"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Zobraziť ovládacie prvky"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Toto zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVáš správca IT môže sledovať a spravovať nastavenia, podnikový prístup, aplikácie, údaje spojené s vaším zariadení a informácie o jeho polohe.\n\nViac sa dozviete od správcu IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Toto zariadenie patrí vašej organizácii.\n\nVáš správca IT môže sledovať a spravovať nastavenia, podnikový prístup, aplikácie, údaje spojené s vaším zariadením a informácie o jeho polohe.\n\n. Viac sa dozviete od správcu IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizácia nainštalovala pre toto zariadenie certifikačnú autoritu. Zabezpečená sieťová premávka môže byť sledovaná či upravená."</string>
@@ -573,6 +583,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Správca aktivoval zapisovanie do denníka siete, ktoré sleduje premávku na vašom zariadení.\n\nĎalšie informácie vám poskytne správca."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Určitej aplikácii ste udelili povolenie nastaviť pripojenie VPN.\n\nTáto aplikácia môže sledovať vaše zariadenie a aktivitu v sieti vrátane e-mailových správ, aplikácií a webových stránok."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Váš pracovný profil spravuje organizácia <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSprávca môže sledovať vašu aktivitu v sieti vrátane e-mailov, aplikácií a webov.\n\nĎalšie informácie vám poskytne správca.\n\nMáte tiež aktívne pripojenie k sieti VPN, ktorá môže sledovať vašu aktivitu v rámci siete."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Toto zariadenie spravuje tvoj rodič. Vidí a môže spravovať informácie, napríklad aplikácie, ktoré používaš, tvoju polohu a čas používania."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Pripojili ste sa k aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g>, ktorá môže sledovať vašu aktivitu v sieti vrátane správ, aplikácií a webových stránok."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Ste pripojený/-á k aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g>, ktorá môže sledovať vašu osobnú aktivitu v sieti vrátane e-mailových správ, aplikácií a webových stránok."</string>
@@ -715,7 +726,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Majú sa upozornenia z tejto aplikácie naďalej zobrazovať?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Tiché"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predvolené"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bublina"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automaticky"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Žiadny zvuk ani vibrácie"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Žiadny zvuk ani vibrácie a zobrazuje sa nižšie v sekcii konverzácií"</string>
@@ -727,8 +737,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Nastavenia"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorita"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nepodporuje funkcie konverzácie"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Žiadne nedávne bubliny"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Tu sa budú zobrazovať nedávne a zavreté bubliny"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tieto upozornenia sa nedajú upraviť."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Túto skupinu upozornení nejde na tomto mieste konfigurovať"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Približné upozornenie"</string>
@@ -991,25 +999,7 @@
     <string name="device_services" msgid="1549944177856658705">"Služby zariadenia"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Klepnutím reštartujete túto aplikáciu a prejdete do režimu celej obrazovky."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Nastavenia bublín aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Rozšírená ponuka"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Pridať späť do zásobníka"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Spravovať"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikácie <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikácie <xliff:g id="APP_NAME">%2$s</xliff:g> a ďalšie (<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>)"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Presunúť"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Presunúť doľava nahor"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Presunúť doprava nahor"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Presunúť doľava nadol"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Presunúť doprava nadol"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Zavrieť bublinu"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nezobrazovať konverzáciu ako bublinu"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Čet pomocou bublín"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nové konverzácie sa zobrazujú ako plávajúce ikony či bubliny. Bublinu otvoríte klepnutím. Premiestnite ju presunutím."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Nastavenie bublín môžete kedykoľvek zmeniť"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bubliny pre túto aplikáciu môžete vypnúť klepnutím na Spravovať"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Dobre"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavenia aplikácie <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostný režim"</string>
@@ -1101,4 +1091,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovať nové zariadenie"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pri čítaní meradla batérie sa vyskytol problém"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím si zobrazíte ďalšie informácie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml
index b52dada..a83cf40 100644
--- a/packages/SystemUI/res/values-sk/strings_tv.xml
+++ b/packages/SystemUI/res/values-sk/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofón je aktívny"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikácia %1$s použila váš mikrofón"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 14f6553..ef22798 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Poskusite znova ustvariti posnetek zaslona"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Shranjevanje posnetka zaslona ni mogoče zaradi omejenega prostora za shranjevanje"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ali vaša organizacija ne dovoljuje posnetkov zaslona"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Urejanje posnetka zaslona"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Opusti posnetek zaslona"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Predogled posnetka zaslona"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snemalnik zaslona"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obdelava videoposnetka zaslona"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Baterija z dvema črticama."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Baterija s tremi črticami."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Baterija je polna."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Neznan odstotek napolnjenosti baterije."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Ni telefona."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon z eno črtico."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon z dvema črticama."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Obvestilo je bilo odstranjeno."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Oblaček je bil opuščen."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Zaslon z obvestili."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Hitre nastavitve."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaklenjen zaslon"</string>
@@ -526,6 +534,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil je morda nadziran"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Omrežje je lahko nadzorovano"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Omrežje je morda nadzorovano"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"To napravo upravlja tvoj starš"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je lastnica te naprave in lahko nadzira omrežni promet"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je lastnica te naprave in lahko nadzira omrežni promet"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Ta naprava pripada vaši organizaciji in je povezana v aplikacijo <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -550,6 +559,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Onemogoči VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Prekini povezavo z VPN-jem"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Prikaži pravilnike"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Ogled kontrolnikov"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nSkrbnik za IT lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, z napravo povezane podatke in podatke o lokaciji naprave.\n\nZa več informacij se obrnite na skrbnika za IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Ta naprava pripada vaši organizaciji.\n\nSkrbnik za IT lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, z napravo povezane podatke in podatke o lokaciji naprave.\n\nZa več informacij se obrnite na skrbnika za IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Vaša organizacija je v to napravo namestila overitelja potrdil. Varni omrežni promet se lahko nadzira ali spreminja."</string>
@@ -573,6 +583,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Skrbnik je vklopil beleženje omrežnega prometa, ki nadzoruje promet v napravi.\n\nČe želite več informacij, se obrnite na skrbnika."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Aplikaciji ste dovolili vzpostavitev povezave VPN.\n\nTa aplikacija lahko nadzira napravo in omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Delovni profil upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSkrbnik lahko nadzira vašo omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nČe želite več informacij, se obrnite na skrbnika.\n\nPovezani ste tudi z omrežjem VPN, ki lahko nadzira vašo omrežno dejavnost."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"To napravo upravlja tvoj starš. Tvoj starš si lahko ogleda in upravlja podatke, na primer katere aplikacije uporabljaš, tvojo lokacijo in koliko časa uporabljaš telefon."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Povezani ste z aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g>, ki lahko nadzira omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Povezani ste z aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g>, ki lahko nadzira vašo osebno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti."</string>
@@ -715,7 +726,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Želite, da so obvestila te aplikacije še naprej prikazana?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Tiho"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Privzeto"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Mehurček"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Samodejno"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Brez zvočnega opozarjanja ali vibriranja"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Brez zvočnega opozarjanja ali vibriranja, prikaz nižje v razdelku s pogovorom"</string>
@@ -727,8 +737,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Nastavitve"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prednost"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podpira pogovornih funkcij"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Ni nedavnih oblačkov"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Tukaj bodo prikazani tako nedavni kot tudi opuščeni oblački"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Za ta obvestila ni mogoče spremeniti nastavitev."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Te skupine obvestil ni mogoče konfigurirati tukaj"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Posredovano obvestilo"</string>
@@ -991,25 +999,7 @@
     <string name="device_services" msgid="1549944177856658705">"Storitve naprave"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Brez naslova"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Dotaknite se za vnovični zagon te aplikacije in preklop v celozaslonski način."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Nastavitve za oblačke aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Prelivanje"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodaj nazaj v sklad"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Upravljanje"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>)"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g> in toliko drugih: <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Premakni"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Premakni zgoraj levo"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Premakni zgoraj desno"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Premakni spodaj levo"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Premakni spodaj desno"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Opusti oblaček"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Pogovora ne prikaži v oblačku"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Klepet z oblački"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Novi pogovori so prikazani kot lebdeče ikone ali oblački. Če želite odpreti oblaček, se ga dotaknite. Če ga želite premakniti, ga povlecite."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljanje oblačkov"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dotaknite se »Upravljanje«, da izklopite oblačke iz te aplikacije"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumem"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Nastavitve za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Krmarjenje po sistemu je posodobljeno. Če želite opraviti spremembe, odprite nastavitve."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Če želite posodobiti krmarjenje po sistemu, odprite nastavitve"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravljenosti"</string>
@@ -1101,4 +1091,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Seznanitev nove naprave"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Težava z branjem indikatorja stanja napolnjenosti baterije"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dotaknite se za več informacij"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml
index 109d797..81f69d9 100644
--- a/packages/SystemUI/res/values-sl/strings_tv.xml
+++ b/packages/SystemUI/res/values-sl/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon je aktiven"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Aplikacija %1$s je dostopala do mikrofona"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 87ca508..d3ebe52 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Provo ta nxjerrësh përsëri pamjen e ekranit"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Pamja e ekranit nuk mund të ruhet për shkak të hapësirës ruajtëse të kufizuar"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Nxjerrja e pamjeve të ekranit nuk lejohet nga aplikacioni ose organizata jote."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Modifiko pamjen e ekranit"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Hiq pamjen e ekranit"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pamja paraprake e imazhit"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Regjistruesi i ekranit"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Regjistrimi i ekranit po përpunohet"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Bateria ka edhe dy vija."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Bateria ka edhe tre vija."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Bateria u mbush."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Përqindja e baterisë e panjohur."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Nuk ka telefon."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefoni ka edhe një vijë."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefoni ka dy vija."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Njoftimi është hequr."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Flluska u hoq."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Streha e njoftimeve."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Cilësimet e shpejta."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ekrani i kyçjes."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profili mund të monitorohet"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Rrjeti mund të jetë i monitoruar"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Rrjeti mund të jetë i monitoruar"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kjo pajisje menaxhohet nga prindi yt."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizata jote e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Kjo pajisje i përket organizatës sate dhe është e lidhur me <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Çaktivizo VPN-në"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Shkëput VPN-në"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Shiko politikat"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Shiko kontrollet"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministratori i teknologjisë së informacionit mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde.\n\nPër më shumë informacione, kontakto me administratorin e teknologjisë së informacionit."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Kjo pajisje i përket organizatës sate.\n\nAdministratori i teknologjisë së informacionit mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde.\n\nPër më shumë informacione, kontakto me administratorin e teknologjisë së informacionit."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organizata jote instaloi një autoritet certifikate në këtë pajisje. Trafiku i rrjetit tënd të sigurt mund të monitorohet ose modifikohet."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administratori yt ka aktivizuar regjistrimin e rrjetit, i cili monitoron trafikun në pajisjen tënde.\n\nPër më shumë informacione, kontakto me administratorin."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"I dhe leje një aplikacioni që të konfigurojë një lidhje VPN.\n\nKy aplikacion mund të monitorojë pajisjen tënde dhe aktivitetin e rrjetit, përfshirë email-et, aplikacionet dhe sajtet e uebit."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratori yt mund të monitorojë aktivitetin tënd të rrjetit, duke përfshirë email-et, aplikacionet dhe sajtet e uebit.\n\nPër më shumë informacion, kontakto me administratorin tënd.\n\nJe i lidhur edhe me një VPN, që mund të monitorojë aktivitetin tënd të rrjetit."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Kjo pajisje menaxhohet nga prindi yt. Prindi yt mund të shohë e menaxhojë informacionin, si p.sh. aplikacionet që përdor, vendndodhjen tënde dhe kohën para ekranit."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Je i lidhur me aplikacionin <xliff:g id="APPLICATION">%1$s</xliff:g> i cili mund të monitorojë aktivitetin tënd në rrjet, duke përfshirë mail-et, aplikacionet dhe sajtet e uebit."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Je i lidhur me aplikacionin <xliff:g id="APPLICATION">%1$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd personal në rrjet, përfshirë email-et, aplikacionet dhe sajtet e uebit."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Do të vazhdosh t\'i shfaqësh njoftimet nga ky aplikacion?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Në heshtje"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"E parazgjedhur"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Flluskë"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatike"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Asnjë tingull ose dridhje"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Asnjë tingull ose dridhje dhe shfaqet më poshtë në seksionin e bisedave"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Cilësimet"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Përparësia"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mbështet veçoritë e bisedës"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nuk ka flluska të fundit"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Flluskat e fundit dhe flluskat e hequra do të shfaqen këtu"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Këto njoftime nuk mund të modifikohen."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ky grup njoftimesh nuk mund të konfigurohet këtu"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Njoftim i dërguar me përfaqësues"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Shërbimet e pajisjes"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Pa titull"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Trokit për ta rinisur këtë aplikacion dhe për të kaluar në ekranin e plotë."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Cilësimet për flluskat e <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Tejkalo"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Shto përsëri te stiva"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Menaxho"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> nga <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> nga <xliff:g id="APP_NAME">%2$s</xliff:g> dhe <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> të tjera"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Zhvendos"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Zhvendos lart majtas"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Lëviz lart djathtas"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Zhvendos poshtë majtas"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Lëvize poshtë djathtas"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Hiqe flluskën"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Mos e vendos bisedën në flluskë"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Bisedo duke përdorur flluskat"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Bisedat e reja shfaqen si ikona pluskuese ose flluska. Trokit për të hapur flluskën. Zvarrit për ta zhvendosur."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrollo flluskat në çdo moment"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Trokit \"Menaxho\" për të çaktivizuar flluskat nga ky aplikacion"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"E kuptova"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Cilësimet e <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigimi i sistemit u përditësua. Për të bërë ndryshime, shko te \"Cilësimet\"."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Shko te \"Cilësimet\" për të përditësuar navigimin e sistemit"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Në gatishmëri"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Çifto pajisjen e re"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem me leximin e matësit të baterisë"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trokit për më shumë informacione"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings_tv.xml b/packages/SystemUI/res/values-sq/strings_tv.xml
index 6cecdb6..124f664 100644
--- a/packages/SystemUI/res/values-sq/strings_tv.xml
+++ b/packages/SystemUI/res/values-sq/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofoni aktiv"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s pati qasje te mikrofoni yt"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 1ad7a91..c401d6c 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Пробајте да поново направите снимак екрана"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Чување снимка екрана није успело због ограниченог меморијског простора"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Апликација или организација не дозвољавају прављење снимака екрана"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Измените снимак екрана"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Одбаците снимак екрана"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Преглед снимка екрана"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Снимач екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Батерија од две црте."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Батерија од три црте."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Батерија је пуна."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Проценат напуњености батерије није познат."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Нема телефона."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Сигнал телефона има једну црту."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Сигнал телефона од две црте."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Обавештење је одбачено."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Облачић је одбачен."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Прозор са обавештењима."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брза подешавања."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Закључан екран."</string>
@@ -523,6 +531,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Профил се можда надгледа"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Мрежа се можда надгледа"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Мрежа се можда надгледа"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Овим уређајем управља родитељ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организација је власник уређаја и може да надгледа мрежни саобраћај"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> је власник овог уређаја и може да надгледа мрежни саобраћај"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Овај уређај припада организацији и повезан је са апликацијом <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -547,6 +556,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Онемогући VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Прекини везу са VPN-ом"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Прикажи смернице"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Прикажи контроле"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Овај уређај припада организацији.\n\nИТ администратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nВише информација потражите од ИТ администратора."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Организација је на овом уређају инсталирала ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
@@ -570,6 +580,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Администратор је укључио евидентирање мреже, које прати саобраћај на уређају.\n\nКонтактирајте администратора за више информација."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Дали сте дозволу апликацији да подешава VPN везу.\n\nТа апликација може да надгледа активности на уређају и мрежи, укључујући имејлове, апликације и веб-сајтове."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> управља пословним профилом.\n\nАдминистратор може да прати активности на мрежи, укључујући имејлове, апликације и веб-сајтове.\n\nКонтактирајте администратора за више информација.\n\nПовезани сте и са VPN-ом, који може да прати активности на мрежи."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Овим уређајем управља родитељ. Родитељ може да види информације, као што су апликације које користиш, твоју локацију и време испред екрана, и да управља њима."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Повезани сте са апликацијом <xliff:g id="APPLICATION">%1$s</xliff:g>, која може да надгледа активности на мрежи, укључујући имејлове, апликације и веб-сајтове."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Повезани сте са апликацијом <xliff:g id="APPLICATION">%1$s</xliff:g>, која може да надгледа активности на личној мрежи, укључујући имејлове, апликације и веб-сајтове."</string>
@@ -712,7 +723,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Желите ли да се обавештења из ове апликације и даље приказују?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Нечујно"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Подразумевано"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Облачић"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Аутоматска"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука и вибрирања"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звука и вибрирања и приказује се у наставку одељка за конверзације"</string>
@@ -724,8 +734,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Подешавања"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава функције конверзације"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Нема недавних облачића"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Овде се приказују недавни и одбачени облачићи"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ова обавештења не могу да се мењају."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ова група обавештења не може да се конфигурише овде"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Обавештење преко проксија"</string>
@@ -986,25 +994,7 @@
     <string name="device_services" msgid="1549944177856658705">"Услуге за уређаје"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслова"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Додирните да бисте рестартовали апликацију и прешли у режим целог екрана."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Подешавања за <xliff:g id="APP_NAME">%1$s</xliff:g> облачиће"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Преклапање"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Додај поново у групу"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Управљајте"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из апликације <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из апликације <xliff:g id="APP_NAME">%2$s</xliff:g> и још <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Премести"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Премести горе лево"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Премести горе десно"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Премести доле лево"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Премести доле десно"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Одбаци облачић"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не користи облачиће за конверзацију"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Ћаскајте у облачићима"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Нове конверзације се приказују као плутајуће иконе или облачићи. Додирните да бисте отворили облачић. Превуците да бисте га преместили."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контролишите облачиће у било ком тренутку"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Додирните Управљајте да бисте искључили облачиће из ове апликације"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Важи"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Подешавања за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Идите у Подешавања да бисте ажурирали навигацију система"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string>
@@ -1095,4 +1085,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Упари нови уређај"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем са очитавањем мерача батерије"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml
index 322938f..21fef7f 100644
--- a/packages/SystemUI/res/values-sr/strings_tv.xml
+++ b/packages/SystemUI/res/values-sr/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Микрофон је активан"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Апликација %1$s је приступила микрофону"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index d34c814..367297e 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Testa att ta en skärmdump igen"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Det går inte att spara skärmdumpen eftersom lagringsutrymmet inte räcker"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisationen tillåter inte att du tar skärmdumpar"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Redigera skärmdump"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Stäng skärmdump"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Förhandsgranskning av skärmdump"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skärminspelare"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandlar skärminspelning"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Batteri: två staplar."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Batteri: tre staplar."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batteriet är fulladdat."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Okänd batterinivå."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Ingen telefon."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon: en stapel."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon: två staplar."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Meddelandet ignorerades."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bubblan ignorerades."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Meddelandepanel."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Snabbinställningar."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Låsskärm."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Det kan hända att profilen övervakas"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Nätverket kan vara övervakat"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Nätverket kan vara övervakat"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Den här enheten hanteras av din förälder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisationen äger den här enheten och kan övervaka nätverkstrafiken"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> äger den här enheten och kan övervaka nätverkstrafiken"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Den här enheten tillhör organisationen och är ansluten till <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Inaktivera VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Koppla från VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Visa policyer"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Visa kontroller"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Den här enheten tillhör <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nIT-administratören kan övervaka och hantera inställningar, företagsåtkomst, appar, data med koppling till enheten och enhetens plats.\n\nKontakta IT-administratören om du vill veta mer."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Den här enheten tillhör organisationen.\n\nIT-administratören kan övervaka och hantera inställningar, företagsåtkomst, appar, data med koppling till enheten och enhetens plats.\n\nKontakta IT-administratören om du vill veta mer."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Organisationen har installerat en certifikatutfärdare på enheten. Din säkra nätverkstrafik kan övervakas och ändras."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administratören har aktiverat nätverksloggning som övervakar trafik på enheten.\n\nKontakta administratören om du vill veta mer."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Du har gett en app behörighet att upprätta en VPN-anslutning.\n\nAppen kan bevaka aktivitet på enheten och nätverket, inklusive e-post, appar och webbplatser."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Jobbprofilen hanteras av <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratören kan övervaka nätverksaktivitet, till exempel e-postmeddelanden, appar och webbplatser.\n\nKontakta administratören om du vill veta mer.\n\nDu är även ansluten till ett VPN som kan övervaka nätverksaktivitet."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Den här enheten hanteras av din förälder. Föräldern kan se och hantera information som vilka appar du använder, din plats och din skärmtid."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Du är ansluten till <xliff:g id="APPLICATION">%1$s</xliff:g> som kan bevaka din nätverksaktivitet, exempelvis e-post, appar och webbplatser."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Du är ansluten till <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan bevaka din privata aktivitet på nätverket, inklusive e-post, appar och webbplatser."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Vill du fortsätta visa aviseringar för den här appen?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Tyst"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bubbla"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatiskt"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Inga ljud eller vibrationer"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Inga ljud eller vibrationer och visas längre ned bland konversationerna"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Inställningar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inte stöd för konversationsfunktioner"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Inga nya bubblor"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"De senaste bubblorna och ignorerade bubblor visas här"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Det går inte att ändra de här aviseringarna."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Den här aviseringsgruppen kan inte konfigureras här"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Avisering via proxy"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Enhetstjänster"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tryck för att starta om appen i helskärmsläge."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Inställningar för <xliff:g id="APP_NAME">%1$s</xliff:g>-bubblor"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Fler menyalternativ"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Lägg tillbaka på stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Hantera"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> från <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> från <xliff:g id="APP_NAME">%2$s</xliff:g> och <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> fler"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Flytta"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Flytta högst upp till vänster"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Flytta högst upp till höger"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Flytta längst ned till vänster"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Flytta längst ned till höger"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Stäng bubbla"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Visa inte konversationen i bubblor"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Chatta med bubblor"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nya konversationer visas som flytande ikoner, så kallade bubblor. Tryck på bubblan om du vill öppna den. Dra den om du vill flytta den."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Styr bubblor när som helst"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tryck på Hantera för att stänga av bubblor från den här appen"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Inställningar för <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen har uppdaterats. Öppna inställningarna om du vill ändra något."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Öppna inställningarna och uppdatera systemnavigeringen"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Viloläge"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parkoppla en ny enhet"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batteriindikatorn visas inte"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryck för mer information"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml
index fb28af4..ad58bfe 100644
--- a/packages/SystemUI/res/values-sv/strings_tv.xml
+++ b/packages/SystemUI/res/values-sv/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofonen är aktiv"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s har fått åtkomst till mikrofonen"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index eab7f69..4cf09c7 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Jaribu kupiga picha ya skrini tena"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Imeshindwa kuhifadhi picha ya skrini kwa sababu nafasi haitoshi"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Programu au shirika lako halikuruhusu kupiga picha za skrini"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Badilisha picha ya skrini"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ondoa picha ya skrini"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Badilisha"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Badilisha picha ya skrini"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Fanya iwe ndefu"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Fanya picha ya skrini iwe ndefu"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ondoa picha ya skrini"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Onyesho la kukagua picha ya skrini"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Kinasa Skrini"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Inachakata rekodi ya skrini"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Pau mbili za betri"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Pau tatu za betri."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Betri imejaa."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Asilimia ya betri haijulikani."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Hakuna simu"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Mwambaa mmoja wa simu."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Miambaa miwili ya simu"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Arifa imetupwa."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Umeondoa kiputo."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Kivuli cha arifa."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Mipangilio ya haraka."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Skrini iliyofungwa."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Huenda wasifu ukafuatiliwa"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Huenda mtandao unafuatiliwa"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Huenda mtandao unafuatiliwa"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kifaa hiki kinadhibitiwa na mzazi wako"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Shirika lako linamiliki kifaa hiki na huenda likafuatilia trafiki ya mtandao"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> inamiliki kifaa hiki na huenda ikafuatilia trafiki ya mtandao"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Kifaa hiki kinamilikiwa na shirika lako na kimeunganishwa kwenye <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Zima VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Ondoa VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Angalia Sera"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Angalia vidhibiti"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nMsimamizi wako wa TEHAMA anaweza kufuatilia na kudhibiti mipangilio, ufikiaji wa maudhui ya shirika, programu, data inayohusiana na kifaa chako na maelezo kuhusu mahali kifaa chako kilipo.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako wa TEHAMA."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Kifaa hiki kinamilikiwa na shirika lako.\n\nMsimamizi wako wa TEHAMA anaweza kufuatilia na kudhibiti mipangilio, ufikiaji wa maudhui ya shirika, programu, data inayohusiana na kifaa chako na maelezo kuhusu mahali kifaa chako kilipo.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako wa TEHAMA."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Shirika lako limesakinisha mamlaka ya cheti kwenye kifaa hiki. Huenda shughuli kwenye mtandao wako salama zikafuatiliwa au kubadilishwa."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Msimamizi wako amewasha kumbukumbu ya kuingia mtandaoni ambayo hufuatilia shughuli kwenye kifaa chako.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Uliruhusu programu iweke muunganisho wa VPN.\n\nProgramu hii inaweza kufuatilia shughuli za kifaa na mtandao wako, ikiwa ni pamoja na barua pepe, programu na tovuti."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Wasifu wako wa kazini unadhibitiwa na <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nMsimamizi wako anaweza kufuatilia shughuli za mtandaoni, ikiwa ni pamoja na barua pepe, programu na tovuti.\n\nKwa maelezo zaidi, wasiliana na msimamizi wako.\n\nUmeunganishwa pia kwenye VPN, ambayo inaweza kufuatilia shughuli zako mtandaoni."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Kifaa hiki kinadhibitiwa na mzazi wako. Mzazi wako anaweza kuona na kudhibiti maelezo kama vile programu unazotumia, mahali ulipo na muda unaotumia kifaa."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Umeunganishwa kwenye <xliff:g id="APPLICATION">%1$s</xliff:g>, ambayo inaweza kufuatilia shughuli za mtandao wako, ikiwa ni pamoja na barua pepe, programu na tovuti."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Umeunganishwa kwenye <xliff:g id="APPLICATION">%1$s</xliff:g>, ambayo inaweza kufuatilia shughuli za mtandao wako, ikiwa ni pamoja na barua pepe, programu na tovuti."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Ungependa kuendelea kuonyesha arifa kutoka programu hii?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Kimya"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Chaguomsingi"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Kiputo"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatiki"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Hakuna sauti wala mtetemo"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Hakuna sauti wala mtetemo na huonekana upande wa chini katika sehemu ya mazungumzo"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Mipangilio"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Kipaumbele"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> haitumii vipengele vya mazungumzo"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Hakuna viputo vya hivi majuzi"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Viputo vya hivi karibuni na vile vilivyoondolewa vitaonekana hapa"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Arifa hizi haziwezi kubadilishwa."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Kikundi hiki cha arifa hakiwezi kuwekewa mipangilio hapa"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Arifa wakilishi"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Huduma za Kifaa"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Wimbo hauna jina"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Gusa ili uzime na uwashe upya programu hii kisha nenda kwenye skrini nzima."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Mipangilio ya viputo vya <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Vipengee vya ziada"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Rejesha kwenye rafu"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Dhibiti"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> kutoka kwa <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> kutoka kwa <xliff:g id="APP_NAME">%2$s</xliff:g> na nyingine<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Sogeza"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Sogeza juu kushoto"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Sogeza juu kulia"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Sogeza chini kushoto"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Sogeza chini kulia"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Ondoa kiputo"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Usiweke viputo kwenye mazungumzo"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Piga gumzo ukitumia viputo"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Mazungumzo mapya huonekena kama aikoni au viputo vinavyoelea. Gusa ili ufungue kiputo. Buruta ili ukisogeze."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Dhibiti viputo wakati wowote"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Gusa Dhibiti ili uzime viputo kwenye programu hii"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Nimeelewa"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Mipangilio ya <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Umesasisha usogezaji kwenye mfumo. Ili ubadilishe, nenda kwenye Mipangilio."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Nenda kwenye mipangilio ili usasishe usogezaji kwenye mfumo"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Hali tuli"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Oanisha kifaa kipya"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Tatizo la kusoma mita ya betri yako"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Gusa ili upate maelezo zaidi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml
index b51f934..5d24972 100644
--- a/packages/SystemUI/res/values-sw/strings_tv.xml
+++ b/packages/SystemUI/res/values-sw/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Maikrofoni Inatumika"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s imefikia maikrofoni yako"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index a72ebef..5d29c91 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ஸ்கிரீன் ஷாட்டை மீண்டும் எடுக்க முயலவும்"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"போதுமான சேமிப்பிடம் இல்லாததால் ஸ்கிரீன்ஷாட்டைச் சேமிக்க முடியவில்லை"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ஸ்கிரீன் ஷாட்டுகளை எடுப்பதை, ஆப்ஸ் அல்லது உங்கள் நிறுவனம் அனுமதிக்கவில்லை"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"ஸ்கிரீன்ஷாட்டைத் திருத்தும்"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ஸ்கிரீன்ஷாட்டை நிராகரி"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"திருத்து"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"ஸ்கிரீன்ஷாட்டைத் திருத்தும்"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"ஸ்க்ரோல்"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"ஸ்கிரீன்ஷாட்டைப் பெரிதாக்கும்"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ஸ்கிரீன்ஷாட்டை நிராகரிக்கும்"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ஸ்கிரீன்ஷாட்டின் மாதிரிக்காட்சி"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ஸ்கிரீன் ரெக்கார்டர்"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"பேட்டரி சக்தி இரண்டு பார் அளவில் உள்ளது."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"பேட்டரி சக்தி மூன்று பார் அளவில் உள்ளது."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"பேட்டரி முழுமையாக உள்ளது."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"பேட்டரி சதவீதம் தெரியவில்லை."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"சிக்னல் இல்லை."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"சிக்னல் ஒரு கோட்டில் உள்ளது."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"சிக்னல் இரண்டு கோட்டில் உள்ளது."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"அறிவிப்பு நிராகரிக்கப்பட்டது."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"குமிழ் நிராகரிக்கப்பட்டது."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"அறிவிப்பு விவரம்."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"உடனடி அமைப்பு."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"லாக் ஸ்கிரீன்."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"சுயவிவரம் கண்காணிக்கப்படலாம்"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"நெட்வொர்க் கண்காணிக்கப்படலாம்"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"நெட்வொர்க் கண்காணிக்கப்படலாம்"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"இந்தச் சாதனம் உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது, அது <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPNஐ முடக்கு"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPNஐத் துண்டி"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"கொள்கைகளைக் காட்டு"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"கட்டுப்பாடுகளைக் காட்டு"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிறுவனத்துக்கு சொந்தமானது.\n\nஉங்கள் IT நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், உங்கள் சாதனத்துடன் தொடர்புடைய தரவு, சாதனத்தின் இருப்பிடத் தகவல்கள் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவல்களுக்கு IT நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது.\n\nஉங்கள் IT நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், உங்கள் சாதனத்துடன் தொடர்புடைய தரவு, சாதனத்தின் இருப்பிடத் தகவல்கள் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்.\n\nமேலும் தகவல்களுக்கு IT நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"உங்கள் நிறுவனம் இந்தச் சாதனத்தில் சான்றிதழ் அங்கீகாரத்தை நிறுவியுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"உங்கள் நிர்வாகி நெட்வொர்க் பதிவெடுத்தலை இயக்கியுள்ளார், இது சாதனத்தில் ட்ராஃபிக்கைக் கண்காணிக்கும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"VPN இணைப்பை அமைக்க, பயன்பாட்டிற்கு அனுமதி வழங்கியுள்ளீர்கள்.\n\nஇந்த ஆப்ஸால் மின்னஞ்சல்கள், ஆப்ஸ் மற்றும் இணையதளங்கள் உட்பட, உங்கள் சாதனத்தையும் நெட்வொர்க் செயல்பாட்டையும் கண்காணிக்க முடியும்."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்.\n\nஉங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய VPN உடனும் இணைக்கப்பட்டுள்ளீர்கள்."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"இந்தச் சாதனம் உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது. நீங்கள் பயன்படுத்தும் ஆப்ஸ், இருப்பிடம், பயன்படுத்திய நேரம் ஆகியவற்றைப் பார்க்கவும் நிர்வகிக்கவும் உங்கள் பெற்றோரால் முடியும்."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள்."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"<xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்த ஆப்ஸால், மின்னஞ்சல்கள், ஆப்ஸ் மற்றும் இணையதளங்கள் உட்பட உங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"இந்த ஆப்ஸின் அறிவிப்புகளைத் தொடர்ந்து காட்டவா?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"நிசப்தம்"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"இயல்புநிலை"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"பபிள்"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"தானியங்கு"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ஒலி / அதிர்வு இல்லை"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ஒலி / அதிர்வு இல்லாமல் உரையாடல் பிரிவின் கீழ்ப் பகுதியில் தோன்றும்"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"அமைப்புகள்"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"முன்னுரிமை"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"உரையாடல் அம்சங்களை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காது"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"சமீபத்திய குமிழ்கள் இல்லை"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"சமீபத்திய குமிழ்களும் நிராகரிக்கப்பட்ட குமிழ்களும் இங்கே தோன்றும்"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"இந்த அறிவுப்புக் குழுக்களை இங்கே உள்ளமைக்க இயலாது"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ப்ராக்ஸியான அறிவிப்பு"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"சாதன சேவைகள்"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"தலைப்பு இல்லை"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கலாம், முழுத்திரையில் பார்க்கலாம்."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> குமிழ்களுக்கான அமைப்புகள்"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ஓவர்ஃப்லோ"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"மீண்டும் ஸ்டேக்கில் சேர்க்கவும்"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"நிர்வகி"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> இலிருந்து <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> மற்றும் மேலும் <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ஆப்ஸிலிருந்து வந்துள்ள அறிவிப்பு: <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"நகர்த்து"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"மேலே இடப்புறமாக நகர்த்து"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"மேலே வலப்புறமாக நகர்த்து"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"கீழே இடப்புறமாக நகர்த்து"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"கீழே வலதுபுறமாக நகர்த்து"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"குமிழை அகற்று"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"உரையாடலைக் குமிழாக்காதே"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"குமிழ்களைப் பயன்படுத்தி அரட்டையடியுங்கள்"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"புதிய உரையாடல்கள் மிதக்கும் ஐகான்களாகவோ குமிழ்களாகவோ தோன்றும். குமிழைத் திறக்க தட்டவும். நகர்த்த இழுக்கவும்."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"குமிழ்களை எப்போது வேண்டுமானாலும் கட்டுப்படுத்தலாம்"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"இந்த ஆப்ஸிலிருந்து வரும் குமிழ்களை முடக்க, நிர்வகி என்பதைத் தட்டவும்"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"சரி"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> அமைப்புகள்"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"சிஸ்டம் நேவிகேஷன் மாற்றப்பட்டது. மாற்றங்களைச் செய்ய ‘அமைப்புகளுக்குச்’ செல்லவும்."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"சிஸ்டம் நேவிகேஷனை மாற்ற ’அமைப்புகளுக்குச்’ செல்லவும்"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"இயக்க நேரம்"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"புதிய சாதனத்தை இணைத்தல்"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"பேட்டரி அளவை அறிவதில் சிக்கல்"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"மேலும் தகவல்களுக்கு தட்டவும்"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings_tv.xml b/packages/SystemUI/res/values-ta/strings_tv.xml
index 1ae3d1d..4ead6cc 100644
--- a/packages/SystemUI/res/values-ta/strings_tv.xml
+++ b/packages/SystemUI/res/values-ta/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"மைக்ரோஃபோன் செயலிலுள்ளது"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s உங்கள் மைக்ரோஃபோனைப் பயன்படுத்தியது"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 0d23f25..578f62b 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"స్క్రీన్‌షాట్ తీయడానికి మళ్లీ ప్రయత్నించండి"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"నిల్వ స్థలం పరిమితంగా ఉన్న కారణంగా స్క్రీన్‌షాట్‌ను సేవ్ చేయడం సాధ్యపడదు"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"స్క్రీన్‌షాట్‌లు తీయడానికి యాప్ లేదా మీ సంస్థ అనుమతించలేదు"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"స్క్రీన్‌షాట్‌ను ఎడిట్ చేస్తుంది"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"స్క్రీన్‌షాట్‌ను మూసివేస్తుంది"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"స్క్రీన్‌షాట్ ప్రివ్యూ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"స్క్రీన్ రికార్డర్"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"బ్యాటరీ రెండు బార్లు."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"బ్యాటరీ మూడు బార్లు."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"బ్యాటరీ నిండింది."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"బ్యాటరీ శాతం తెలియదు."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ఫోన్ లేదు."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"ఫోన్ ఒక బారు."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"ఫోన్ రెండు బార్లు."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"నోటిఫికేషన్ తీసివేయబడింది."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"బబుల్ విస్మరించబడింది."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"నోటిఫికేషన్ షేడ్."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"శీఘ్ర సెట్టింగ్‌లు."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"లాక్ స్క్రీన్."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ప్రొఫైల్‌ని పర్యవేక్షించవచ్చు"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"నెట్‌వర్క్ పర్యవేక్షించబడవచ్చు"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"నెట్‌వర్క్ పర్యవేక్షించబడవచ్చు"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ఈ పరికరం మీ సంస్థకు చెందినది, కాబట్టి అది నెట్‌వర్క్ ట్రాఫిక్‌ను పర్యవేక్షించవచ్చు"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"మీ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది, కాబట్టి అది నెట్‌వర్క్ ట్రాఫిక్‌ను పర్యవేక్షించవచ్చు"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"ఈ పరికరం మీ సంస్థకు చెందినది, ఇది <xliff:g id="VPN_APP">%1$s</xliff:g>కు కనెక్ట్ అయి ఉంది"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPNని నిలిపివేయి"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPNను డిస్‌కనెక్ట్ చేయి"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"విధానాలను వీక్షించండి"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"నియంత్రణలను చూడండి"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది.\n\nసెట్టింగ్‌లను, కార్పొరేట్ యాక్సెస్‌ను, యాప్‌లను, మీ పరికరానికి సంబంధించిన డేటాను, అలాగే మీ పరికరం యొక్క లొకేషన్ సమాచారాన్ని మీ IT అడ్మిన్ పర్యవేక్షించగలరు, మేనేజ్ చేయగలరు.\n\nమరింత సమాచారం కోసం, మీ IT అడ్మిన్‌ను సంప్రదించండి."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"ఈ పరికరం మీ సంస్థకు చెందినది.\n\nసెట్టింగ్‌లను, కార్పొరేట్ యాక్సెస్‌ను, యాప్‌లను, మీ పరికరానికి సంబంధించిన డేటాను, అలాగే మీ పరికరం యొక్క లొకేషన్ సమాచారాన్ని మీ IT అడ్మిన్ పర్యవేక్షించగలరు, మేనేజ్ చేయగలరు.\n\nమరింత సమాచారం కోసం, మీ IT అడ్మిన్‌ను సంప్రదించండి."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"ఈ పరికరంలో మీ సంస్థ ఒక ప్రమాణపత్ర అధికారాన్ని ఇన్‌స్టాల్ చేసింది. మీ సురక్షిత నెట్‌వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"మీ నిర్వాహకులు మీ పరికరంలోని ట్రాఫిక్‌ని పర్యవేక్షించగల నెట్‌వర్క్ లాగింగ్‌ని ఆన్ చేసారు.\n\nమరింత సమాచారం కావాలంటే, మీ నిర్వాహకులను సంప్రదించండి."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"మీరు VPN కనెక్షన్ సెటప్ చేయడానికి ఒక యాప్‌నకు అనుమతి ఇచ్చారు.\n\nఈ యాప్ ఇమెయిల్‌లు,యాప్‌లు మరియు వెబ్‌సైట్‌లతో సహా మీ డివైజ్ మరియు నెట్‌వర్క్ కార్యకలాపాన్ని పర్యవేక్షించగలదు."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ద్వారా మీ కార్యాలయ ప్రొఫైల్ నిర్వహించబడుతోంది.\n\nఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల సామర్థ్యం మీ నిర్వాహకులకు ఉంది.\n\nమరింత సమాచారం కావాలంటే, మీ నిర్వాహకులను సంప్రదించండి.\n\nమీరు VPNకి కూడా కనెక్ట్ అయ్యారు, ఇది మీ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు. మీ తల్లి/తండ్రి, మీరు ఉపయోగించే యాప్‌లు, మీ లొకేషన్, అలాగే మీ పరికర వినియోగ వ్యవధి వంటి సమాచారాన్ని చూడగలరు, మేనేజ్ చేయగలరు."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"మీరు ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"మీరు <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌‍సైట్‌లతో సహా మీ వ్యక్తిగత నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"ఈ యాప్ నుండి నోటిఫికేషన్‌లను చూపిస్తూ ఉండాలా?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"నిశ్శబ్దం"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ఆటోమేటిక్ సెట్టింగ్"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"బబుల్"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ఆటోమేటిక్"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"శబ్దం లేదా వైబ్రేషన్‌లు ఏవీ లేవు"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"శబ్దం లేదా వైబ్రేషన్ లేదు, సంభాషణ విభాగం దిగువన కనిపిస్తుంది"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"సెట్టింగ్‌లు"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ప్రాధాన్యత"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> సంభాషణ ఫీచర్‌లను సపోర్ట్ చేయదు"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ఇటీవలి బబుల్స్ ఏవీ లేవు"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"ఇటీవలి బబుల్స్ మరియు తీసివేసిన బబుల్స్ ఇక్కడ కనిపిస్తాయి"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ఈ నోటిఫికేషన్‌లను సవరించడం వీలుపడదు."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ఈ నోటిఫికేషన్‌ల సమూహాన్ని ఇక్కడ కాన్ఫిగర్ చేయలేము"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"ప్రాక్సీ చేయబడిన నోటిఫికేషన్"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"పరికర సేవలు"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"శీర్షిక లేదు"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ఈ యాప్‌ను పునఃప్రారంభించేలా నొక్కి, ఆపై పూర్తి స్క్రీన్‌‍లోకి వెళ్లండి."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> బబుల్స్ సెట్టింగ్‌లు"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ఓవర్‌ఫ్లో"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"స్ట్యాక్‌కు తిరిగి జోడించండి"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"మేనేజ్ చేయండి"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> నుండి <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> నుండి <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> మరియు మరో <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"తరలించు"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ఎగువ ఎడమవైపునకు జరుపు"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ఎగువ కుడివైపునకు జరుపు"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"దిగువ ఎడమవైపునకు తరలించు"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"దిగవు కుడివైపునకు జరుపు"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"బబుల్‌ను విస్మరించు"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"సంభాషణను బబుల్ చేయవద్దు"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"బబుల్స్‌ను ఉపయోగించి చాట్ చేయండి"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"కొత్త సంభాషణలు తేలియాడే చిహ్నాలుగా లేదా బబుల్స్ లాగా కనిపిస్తాయి. బబుల్‌ని తెరవడానికి నొక్కండి. తరలించడానికి లాగండి."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"బబుల్స్‌ను ఎప్పుడైనా నియంత్రించండి"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ఈ యాప్ నుండి వచ్చే బబుల్స్‌ను ఆఫ్ చేయడానికి మేనేజ్ బటన్‌ను ట్యాప్ చేయండి"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"అర్థమైంది"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> సెట్టింగ్‌లు"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"సిస్టమ్ నావిగేషన్ అప్‌డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్‌లకు వెళ్లండి."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"సిస్టమ్ నావిగేషన్‌ను అప్‌డేట్ చేయడానికి సెట్టింగ్‌లకు వెళ్లండి"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"స్టాండ్‌బై"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"కొత్త పరికరాన్ని పెయిర్ చేయండి"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"మీ బ్యాటరీ మీటర్‌ను చదవడంలో సమస్య"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"మరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings_tv.xml b/packages/SystemUI/res/values-te/strings_tv.xml
index 2791179..112f9bc 100644
--- a/packages/SystemUI/res/values-te/strings_tv.xml
+++ b/packages/SystemUI/res/values-te/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"మైక్రోఫోన్ యాక్టివ్‌గా ఉంది"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"మీ మైక్రోఫోన్‌ను %1$s యాక్సెస్ చేసింది"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 015ac90..cebe1e8 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -30,6 +30,7 @@
         <item>com.android.systemui.volume.VolumeUI</item>
         <item>com.android.systemui.statusbar.tv.TvStatusBar</item>
         <item>com.android.systemui.statusbar.tv.TvNotificationPanel</item>
+        <item>com.android.systemui.statusbar.tv.VpnStatusObserver</item>
         <item>com.android.systemui.usb.StorageNotification</item>
         <item>com.android.systemui.power.PowerUI</item>
         <item>com.android.systemui.media.RingtonePlayer</item>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 094cb76..ffa84d3 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ลองบันทึกภาพหน้าจออีกครั้ง"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"บันทึกภาพหน้าจอไม่ได้เนื่องจากพื้นที่เก็บข้อมูลมีจำกัด"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"แอปหรือองค์กรของคุณไม่อนุญาตให้จับภาพหน้าจอ"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"แก้ไขภาพหน้าจอ"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ปิดภาพหน้าจอ"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"แก้ไข"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"แก้ไขภาพหน้าจอ"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"เลื่อน"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"เลื่อนจับภาพหน้าจอ"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ปิดภาพหน้าจอ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ตัวอย่างภาพหน้าจอ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"โปรแกรมอัดหน้าจอ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"แบตเตอรี่สองขีด"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"แบตเตอรี่สามขีด"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"แบตเตอรี่เต็ม"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ไม่ทราบเปอร์เซ็นต์แบตเตอรี่"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"ไม่มีสัญญาณโทรศัพท์"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"สัญญาณโทรศัพท์หนึ่งขีด"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"สัญญาณโทรศัพท์สองขีด"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"ปิดการแจ้งเตือนแล้ว"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"ปิดบับเบิลแล้ว"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"หน้าต่างแจ้งเตือน"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"การตั้งค่าด่วน"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ล็อกหน้าจอ"</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"อาจมีการตรวจสอบโปรไฟล์"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"เครือข่ายอาจได้รับการตรวจสอบ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"เครือข่ายอาจถูกตรวจสอบ"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"อุปกรณ์นี้จัดการโดยผู้ปกครอง"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้ และอุปกรณ์เชื่อมต่ออยู่กับ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"ปิดใช้ VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"ยกเลิกการเชื่อมต่อ VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"ดูนโยบาย"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"ดูการควบคุม"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นเจ้าของอุปกรณ์นี้\n\nผู้ดูแลระบบไอทีจะตรวจสอบและจัดการการตั้งค่า การเข้าถึงของบริษัท แอป ข้อมูลที่เชื่อมโยงกับอุปกรณ์ และข้อมูลตำแหน่งของอุปกรณ์ได้\n\nติดต่อผู้ดูแลระบบไอทีหากต้องการข้อมูลเพิ่มเติม"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้\n\nผู้ดูแลระบบไอทีจะตรวจสอบและจัดการการตั้งค่า การเข้าถึงของบริษัท แอป ข้อมูลที่เชื่อมโยงกับอุปกรณ์ และข้อมูลตำแหน่งของอุปกรณ์ได้\n\nติดต่อผู้ดูแลระบบไอทีหากต้องการข้อมูลเพิ่มเติม"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"องค์กรของคุณติดตั้งผู้ออกใบรับรองในอุปกรณ์นี้ อาจมีการตรวจสอบหรือแก้ไขการจราจรของข้อมูลในเครือข่ายที่ปลอดภัยของคุณ"</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"ผู้ดูแลระบบได้เปิดการทำบันทึกเครือข่าย ซึ่งจะติดตามดูการรับส่งข้อมูลบนอุปกรณ์ของคุณ\n\nโปรดติดต่อผู้ดูแลระบบสำหรับข้อมูลเพิ่มเติม"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"คุณได้ให้สิทธิ์แอปในการตั้งค่าการเชื่อมต่อ VPN\n\nแอปนี้จะสามารถตรวจสอบอุปกรณ์และกิจกรรมในเครือข่าย รวมถึงอีเมล แอป และเว็บไซต์ได้"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"โปรไฟล์งานของคุณได้รับการจัดการโดย <xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nผู้ดูแลระบบสามารถตรวจสอบกิจกรรมในเครือข่ายของคุณ ซึ่งรวมถึงอีเมล แอป และเว็บไซต์ต่างๆ\n\nโปรดติดต่อผู้ดูแลระบบสำหรับข้อมูลเพิ่มเติม\n\nนอกจากนี้คุณยังเชื่อมต่อกับ VPN ซึ่งตรวจสอบกิจกรรมในเครือข่ายของคุณได้"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"อุปกรณ์นี้จัดการโดยผู้ปกครอง ผู้ปกครองจะดูและจัดการข้อมูลต่างๆ ได้ เช่น แอปที่คุณใช้ ตำแหน่งของคุณ และเวลาอยู่หน้าจอ"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"คุณเชื่อมต่ออยู่กับ <xliff:g id="APPLICATION">%1$s</xliff:g> ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายของคุณ รวมถึงอีเมล แอป และเว็บไซต์"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"คุณเชื่อมต่อกับ <xliff:g id="APPLICATION">%1$s</xliff:g> ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายส่วนตัวของคุณ รวมถึงอีเมล แอป และเว็บไซต์ได้"</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"แสดงการแจ้งเตือนจากแอปนี้ต่อไปไหม"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"ปิดเสียง"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ค่าเริ่มต้น"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"บับเบิล"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"อัตโนมัติ"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"ไม่มีเสียงหรือการสั่น"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ไม่มีเสียงหรือการสั่น และปรากฏต่ำลงมาในส่วนการสนทนา"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"การตั้งค่า"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ลำดับความสำคัญ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่รองรับฟีเจอร์การสนทนา"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ไม่มีบับเบิลเมื่อเร็วๆ นี้"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"บับเบิลที่แสดงและที่ปิดไปเมื่อเร็วๆ นี้จะปรากฏที่นี่"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"แก้ไขการแจ้งเตือนเหล่านี้ไม่ได้"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"การแจ้งเตือนกลุ่มนี้กำหนดค่าที่นี่ไม่ได้"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"การแจ้งเตือนที่ผ่านพร็อกซี"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"บริการของอุปกรณ์"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ไม่มีชื่อ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"แตะเพื่อรีสตาร์ทแอปนี้และแสดงแบบเต็มหน้าจอ"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"การตั้งค่าบับเบิล <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"รายการเพิ่มเติม"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"เพิ่มกลับไปที่สแต็ก"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"จัดการ"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> จาก <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> จาก <xliff:g id="APP_NAME">%2$s</xliff:g> และอีก <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> รายการ"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"ย้าย"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"ย้ายไปด้านซ้ายบน"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"ย้ายไปด้านขวาบน"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"ย้ายไปด้านซ้ายล่าง"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"ย้ายไปด้านขาวล่าง"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"ปิดบับเบิล"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"ไม่ต้องแสดงการสนทนาเป็นบับเบิล"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"แชทโดยใช้บับเบิล"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"การสนทนาใหม่ๆ จะปรากฏเป็นไอคอนแบบลอยหรือบับเบิล แตะเพื่อเปิดบับเบิล ลากเพื่อย้ายที่"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ควบคุมบับเบิลได้ทุกเมื่อ"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"แตะ \"จัดการ\" เพื่อปิดบับเบิลจากแอปนี้"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"รับทราบ"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"การตั้งค่า <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"สแตนด์บาย"</string>
@@ -1087,6 +1072,8 @@
     <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ยกเลิกการเชื่อมต่อแล้ว)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"เชื่อมต่อไม่ได้ ลองใหม่"</string>
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"จับคู่อุปกรณ์ใหม่"</string>
-    <string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิวด์"</string>
-    <string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิวด์ไปยังคลิปบอร์ดแล้ว"</string>
+    <string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
+    <string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"พบปัญหาในการอ่านเครื่องวัดแบตเตอรี่"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"แตะดูข้อมูลเพิ่มเติม"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml
index 783b1f4..0e4c779 100644
--- a/packages/SystemUI/res/values-th/strings_tv.xml
+++ b/packages/SystemUI/res/values-th/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"ไมโครโฟนเปิดใช้งานอยู่"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s เข้าถึงไมโครโฟนแล้ว"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 8ef1869..0fd8b3e 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Subukang kumuhang muli ng screenshot"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Hindi ma-save ang screenshot dahil sa limitadong espasyo ng storage"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Hindi pinahihintulutan ng app o ng iyong organisasyon ang pagkuha ng mga screenshot"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"I-edit ang screenshot"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"I-dismiss ang screenshot"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"I-edit"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"I-edit ang screenshot"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Mag-scroll"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"I-scroll ang screenshot"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"I-dismiss ang screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Preview ng screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Recorder ng Screen"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pinoproseso screen recording"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Baterya na dalawang bar."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Baterya na tatlong bar."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Puno na ang baterya."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Hindi alam ang porsyento ng baterya."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Walang telepono."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telepono na isang bar."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telepono na dalawang bar."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Na-dismiss ang notification."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Na-dismiss na ang bubble."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Mga mabilisang setting."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Maaaring subaybayan ang profile"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Maaaring sinusubaybayan ang network"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Maaaring sinusubaybayan ang network"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Pinapamahalaan ng iyong magulang ang device na ito"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Pagmamay-ari ng organisasyon mo ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Pagmamay-ari ng iyong organisasyon ang device na ito at nakakonekta ito sa <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"I-disable ang VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Idiskonekta ang VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Tingnan ang Mga Patakaran"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Tingnan ang mga kontrol"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito.\n\nMagagawa ng iyong IT admin na subaybayan at pamahalaan ang mga setting, pangkorporasyong access, mga app, data na nauugnay sa device mo, at ang impormasyon ng lokasyon ng iyong device.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong IT admin."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Pagmamay-ari ng iyong organisasyon ang device na ito.\n\nMagagawa ng iyong IT admin na subaybayan at pamahalaan ang mga setting, pangkorporasyong access, mga app, data na nauugnay sa device mo, at ang impormasyon ng lokasyon ng iyong device.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong IT admin."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Nag-install ang iyong organisasyon ng awtoridad sa certificate sa device na ito. Maaaring subaybayan o baguhin ang iyong ligtas na trapiko sa network."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Na-on ng iyong admin ang pag-log sa network, na sumusubaybay sa trapiko ng device mo.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong admin."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Nagbigay ka ng pahintulot sa app upang mag-set up ng VPN na koneksyon.\n\nMaaaring subaybayan ng app na ito ang iyong aktibidad sa device at network, kabilang ang mga email, app at website."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Pinamamahalaan ng <xliff:g id="ORGANIZATION">%1$s</xliff:g> ang iyong profile sa trabaho.\n\nMay kakayahan ang admin mo na subaybayan ang iyong aktibidad sa network, kasama ang mga email, app at website.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa admin mo.\n\nNakakonekta ka rin sa isang VPN, na may kakayahang subaybayan ang iyong aktibidad sa network."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Pinapamahalaan ng iyong magulang ang device na ito. Makikita at mapapamahalaan ng iyong magulang ang impormasyon tulad ng mga app na ginagamit mo, iyong lokasyon, at tagal ng paggamit mo sa device."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Nakakonekta ka sa <xliff:g id="APPLICATION">%1$s</xliff:g>, na maaaring sumubaybay sa iyong aktibidad sa network, kasama ang mga email, app, at website."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Nakakonekta ka sa <xliff:g id="APPLICATION">%1$s</xliff:g>, na maaaring sumubaybay sa iyong personal na aktibidad sa network, kabilang ang mga email, app at website."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Patuloy na ipakita ang mga notification mula sa app na ito?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Naka-silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bubble"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Awtomatiko"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Walang tunog o pag-vibrate"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Walang tunog o pag-vibrate at lumalabas nang mas mababa sa seksyon ng pag-uusap"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Mga Setting"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priyoridad"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Hindi sinusuportahan ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang mga feature ng pag-uusap"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Walang kamakailang bubble"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Lalabas dito ang mga kamakailang bubble at na-dismiss na bubble"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Hindi puwedeng baguhin ang mga notification na ito."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Hindi mako-configure dito ang pangkat na ito ng mga notification"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Na-proxy na notification"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Mga Serbisyo ng Device"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Walang pamagat"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"I-tap para i-restart ang app na ito at mag-full screen."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Mga setting para sa mga bubble ng <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overflow"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Idagdag ulit sa stack"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Pamahalaan"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> mula sa <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> mula sa <xliff:g id="APP_NAME">%2$s</xliff:g> at <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> pa"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Ilipat"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Ilipat sa kaliwa sa itaas"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Ilipat sa kanan sa itaas"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Ilipat sa kaliwa sa ibaba"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Ilipat sa kanan sa ibaba"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"I-dismiss ang bubble"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Huwag ipakita sa bubble ang mga pag-uusap"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Mag-chat gamit ang bubbles"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Lumalabas bilang mga nakalutang na icon o bubble ang mga bagong pag-uusap. I-tap para buksan ang bubble. I-drag para ilipat ito."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolin ang mga bubble anumang oras"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"I-tap ang Pamahalaan para i-off ang mga bubble mula sa app na ito"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Mga setting ng <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Na-update na ang pag-navigate ng system. Para gumawa ng mga pagbabago, pumunta sa Mga Setting."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pumunta sa Mga Setting para i-update ang pag-navigate sa system"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Naka-standby"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Magpares ng bagong device"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nagkaproblema sa pagbabasa ng iyong battery meter"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"I-tap para sa higit pang impormasyon"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml
index bf46b8f..9a66344 100644
--- a/packages/SystemUI/res/values-tl/strings_tv.xml
+++ b/packages/SystemUI/res/values-tl/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Aktibo ang Mikropono"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Na-access ng %1$s ang iyong mikropono"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c17c8f7..6d4023a 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tekrar ekran görüntüsü almayı deneyin"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Depolama alanı sınırlı olduğundan ekran görüntüsü kaydedilemiyor"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Uygulama veya kuruluşunuz, ekran görüntüsü alınmasına izin vermiyor."</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Ekran görüntüsünü düzenleyin"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ekran görüntüsünü kapat"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekran görüntüsü önizlemesi"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Kaydedicisi"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran kaydı işleniyor"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Pil gücü iki çubuk."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Pil gücü üç çubuk."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Pil tam dolu."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pil yüzdesi bilinmiyor."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Telefon sinyali yok."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon sinyali bir çubuk."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon sinyali iki çubuk."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Bildirim kapatıldı."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Balon kapatıldı."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bildirim gölgesi."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Hızlı ayarlar."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Kilit ekranı"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil izlenebilir"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Ağ etkinliği izlenebilir"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Ağ etkinliği izlenebilir"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz ebeveyniniz tarafından yönetiliyor"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu cihaz, kuruluşunuza ait olup ağ trafiği kuruluşunuz tarafından izlenebilir"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait olup ağ trafiği bu kuruluş tarafından izlenebilir"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Bu cihaz, kuruluşunuza ait olup <xliff:g id="VPN_APP">%1$s</xliff:g> uygulamasına bağlı"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN\'yi devre dışı bırak"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN bağlantısını kes"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Politikaları Göster"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Kontrolleri göster"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait.\n\nBT yöneticiniz cihazınızın ayarlarını, şirket erişimini, uygulamaları, cihazınızla ilişkilendirilen verileri, cihazınızın konum bilgilerini izleyip yönetebilir.\n\nDaha fazla bilgi için BT yöneticinize başvurun."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Bu cihaz kuruluşunuza ait.\n\nBT yöneticiniz cihazın ayarlarını, şirket erişimini, uygulamaları, cihazınızla ilişkilendirilen verileri, cihazınızın konum bilgilerini izleyip yönetebilir.\n\nDaha fazla bilgi için BT yöneticinize başvurun."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Kuruluşunuz bu cihaza bir sertifika yetkilisi yükledi. Güvenli ağ trafiğiniz izlenebilir veya değiştirilebilir."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Yöneticiniz,cihazınızdaki trafiği izleyen ağ günlük kaydını açtı.\n\nDaha fazla bilgi için yöneticinizle iletişim kurun."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"VPN bağlantısı kurması için bir uygulamaya izin verdiniz.\n\nBu uygulama, cihazınızın yanı sıra e-postalarınız, uygulamalarınız ve web siteleriniz dahil olmak üzere ağ etkinliğinizi izleyebilir."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"İş profiliniz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tarafından yönetiliyor.\n\nYöneticiniz e-postalar, uygulamalar ve web siteleri de dahil olmak üzere ağ etkinliğinizi izleyebilir.\n\nDaha fazla bilgi için yöneticinizle iletişim kurun.\n\nAyrıca, ağ etkinliğinizi izleyebilen bir VPN\'ye de bağlısınız."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu cihaz ebeveyniniz tarafından yönetiliyor. Kullandığınız uygulamalar, konumunuz ve ekran başında kalma süreniz gibi bilgiler ebeveyniniz tarafından görülüp yönetebilir."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"E-postalarınız, uygulamalarınız ve web siteleriniz dahil olmak üzere ağ etkinliğinizi izleyebilen <xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasına bağlısınız."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"E-postalarınız, uygulamalarınız ve web siteleriniz dahil olmak üzere kişisel ağ etkinliğinizi izleyebilen <xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasına bağlısınız."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Bu uygulamadan gelen bildirimler gösterilmeye devam edilsin mi?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Sessiz"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Varsayılan"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Baloncuk"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatik"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sessiz veya titreşim yok"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sessizdir veya titreşim yoktur ve görüşme bölümünün altında görünür"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ayarlar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Öncelik"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>, sohbet özelliklerini desteklemiyor"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Son kapatılan baloncuk yok"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Son baloncuklar ve kapattığınız baloncuklar burada görünür"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirimler değiştirilemez."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildirim grubu burada yapılandırılamaz"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Proxy uygulanan bildirim"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Cihaz Hizmetleri"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıksız"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Bu uygulamayı yeniden başlatmak ve tam ekrana geçmek için dokunun."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> baloncukları için ayarlar"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Taşma"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Yığına geri ekle"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Yönet"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> uygulamasından <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> uygulamasından <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ve diğer <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Taşı"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Sol üste taşı"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Sağ üste taşı"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Sol alta taşı"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Sağ alta taşı"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Baloncuğu kapat"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Görüşmeyi baloncuk olarak görüntüleme"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Baloncukları kullanarak sohbet edin"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Yeni görüşmeler kayan simgeler veya baloncuk olarak görünür. Açmak için baloncuğa dokunun. Baloncuğu taşımak için sürükleyin."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Baloncukları istediğiniz zaman kontrol edin"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu uygulamanın baloncuklarını kapatmak için Yönet\'e dokunun"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Anladım"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemde gezinme yöntemi güncellendi. Değişiklik yapmak için Ayarlar\'a gidin."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistemde gezinme yöntemini güncellemek için Ayarlar\'a gidin"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Beklemeye alınıyor"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihaz eşle"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pil ölçeriniz okunurken sorun oluştu"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Daha fazla bilgi için dokunun"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml
index 30d1fc9..c7033f1 100644
--- a/packages/SystemUI/res/values-tr/strings_tv.xml
+++ b/packages/SystemUI/res/values-tr/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon Etkin"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s mikrofonunuza erişti"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7dcfc3b..7a78c3d 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Спробуйте зробити знімок екрана ще раз"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Не вдалося зберегти знімок екрана через обмежений обсяг пам’яті"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Додаток або адміністратор вашої організації не дозволяють робити знімки екрана"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Редагувати знімок екрана"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Закрити знімок екрана"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Перегляд знімка екрана"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Відеозапис екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Заряд акумулятора: дві смужки."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Заряд акумулятора: три смужки."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Акумулятор заряджений."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Відсоток заряду акумулятора невідомий."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Немає сигналу телефону."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Одна смужка сигналу телефону."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Дві смужки сигналу телефону."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Сповіщення відхилено."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Спливаюче сповіщення закрито."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Панель сповіщень."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Швидке налаштування."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Заблокований екран."</string>
@@ -526,6 +534,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Профіль може відстежуватись"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Дії в мережі можуть відстежуватися"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Мережа може відстежуватися"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Цим пристроєм керує батько або мати"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Цей пристрій належить вашій організації. Її адміністратор може відстежувати мережевий трафік"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\". Її адміністратор може відстежувати мережевий трафік"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Цей пристрій належить вашій організації. Його підключено до додатка <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -550,6 +559,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Вимкнути VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Від’єднатися від мережі VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Переглянути правила"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Переглянути засоби контролю"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\".\n\nIT-адміністратор може відстежувати й контролювати налаштування, корпоративний доступ, додатки, дані пристрою та інформацію про його місцезнаходження.\n\nЩоб дізнатися більше, зв\'яжіться з IT-адміністратором."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Цей пристрій належить вашій організації.\n\nІТ-адміністратор може відстежувати й контролювати налаштування, корпоративний доступ, додатки, дані пристрою та інформацію про його місцезнаходження.\n\nЩоб дізнатися більше, зв\'яжіться з ІТ-адміністратором."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Адміністратор організації встановив центр сертифікації на цьому пристрої. Захищений мережевий трафік може відстежуватися або змінюватися."</string>
@@ -573,6 +583,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Ваш адміністратор увімкнув реєстрацію в мережі, під час якої на вашому пристрої відстежується трафік.\n\nЩоб дізнатися більше, зв’яжіться з адміністратором."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Ви дозволили додатку під’єднуватися до мережі VPN.\n\nЦей додаток може відстежувати вашу активність на пристрої та в мережі, зокрема в електронній пошті, додатках і на веб-сайтах."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Вашим робочим профілем керує адміністратор організації <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nВін може відстежувати ваші дії в мережі, зокрема електронні листи, додатки та веб-сайти.\n\nЩоб дізнатися більше, зв’яжіться з адміністратором.\n\nВаш пристрій також під’єднано до мережі VPN, у якій можна відстежувати ваші дії в мережі."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Цим пристроєм керує батько або мати. Вони можуть бачити та контролювати, якими додатками ви користуєтесь, де перебуваєте й скільки часу проводите за пристроєм."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Ваш профіль під’єднано до додатка <xliff:g id="APPLICATION">%1$s</xliff:g>, який може відстежувати вашу активність у мережі, зокрема в електронній пошті, додатках і на веб-сайтах."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Ваш профіль під’єднано до додатка <xliff:g id="APPLICATION">%1$s</xliff:g>, який може відстежувати вашу особисту активність у мережі, зокрема в електронній пошті, додатках і на веб-сайтах."</string>
@@ -715,7 +726,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Чи показувати сповіщення з цього додатка надалі?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Без звуку"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"За умовчанням"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Спливаюче сповіщення"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звуку чи вібрації"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звуку чи вібрації, з\'являється нижче в розділі розмов"</string>
@@ -727,8 +737,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Налаштування"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Пріоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не підтримує функції розмов"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Немає нещодавніх спливаючих чатів"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Тут з\'являтимуться нещодавні й закриті спливаючі чати"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ці сповіщення не можна змінити."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Цю групу сповіщень не можна налаштувати тут"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Проксі-сповіщення"</string>
@@ -991,25 +999,7 @@
     <string name="device_services" msgid="1549944177856658705">"Сервіси на пристрої"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без назви"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Натисніть, щоб перезапустити додаток і перейти в повноекранний режим."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Налаштування спливаючих чатів від додатка <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Додаткове меню"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Додати в список"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Налаштувати"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"Cповіщення \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\" від додатка <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"Сповіщення \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\" від додатка <xliff:g id="APP_NAME">%2$s</xliff:g> (і ще <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>)"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Перемістити"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Перемістити ліворуч угору"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Перемістити праворуч угору"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Перемістити ліворуч униз"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Перемістити праворуч униз"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Закрити підказку"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Не показувати спливаючі чати для розмов"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Спливаючий чат"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Нові повідомлення чату з\'являються у вигляді спливаючих значків. Щоб відкрити чат, натисніть його, а щоб перемістити – перетягніть."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контроль спливаючих чатів"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Натисніть \"Налаштувати\", щоб вимкнути спливаючі чати від цього додатка"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Налаштування параметра \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим очікування"</string>
@@ -1101,4 +1091,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Підключити новий пристрій"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не вдалось отримати дані лічильника акумулятора"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Натисніть, щоб дізнатися більше"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings_tv.xml b/packages/SystemUI/res/values-uk/strings_tv.xml
index e3872cc..dbf5955 100644
--- a/packages/SystemUI/res/values-uk/strings_tv.xml
+++ b/packages/SystemUI/res/values-uk/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Мікрофон активовано"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"Додаток %1$s отримав доступ до вашого мікрофона"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 4c0ebaa..ac05019 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"دوبارہ اسکرین شاٹ لینے کی کوشش کریں"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"اسٹوریج کی محدود جگہ کی وجہ سے اسکرین شاٹ کو محفوظ نہیں کیا جا سکتا"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ایپ یا آپ کی تنظیم کی جانب سے اسکرین شاٹس لینے کی اجازت نہیں ہے"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"اسکرین شاٹ میں ترمیم کریں"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"اسکرین شاٹ برخاست کریں"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"اسکرین شاٹ کا پیش منظر"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"سکرین ریکارڈر"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"بیٹری کے دو بارز۔"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"بیٹری کے تین بارز۔"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"بیٹری بھری ہے۔"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"بیٹری کی فیصد نامعلوم ہے۔"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"کوئی فون نہیں ہے۔"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"فون کا ایک بار۔"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"فون کے دو بارز۔"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"اطلاع مسترد ہوگئی۔"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"بلبلہ برخاست کر دیا گیا۔"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"اطلاعاتی شیڈ۔"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"فوری ترتیبات۔"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"مقفل اسکرین۔"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"پروفائل کو مانیٹر کیا جا سکتا ہے"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"نیٹ ورک کو مانیٹر کیا جا سکتا ہے"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"نیٹ ورک کو شاید مانیٹر کیا جائے"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"یہ آلہ آپ کے والدین کے زیر انتظام ہے"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"آپ کی تنظیم اس آلے کی مالک ہے اور نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> اس آلے کی مالک ہے اور نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"یہ آلہ آپ کی تنظیم کا ہے اور <xliff:g id="VPN_APP">%1$s</xliff:g> سے منسلک ہے"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"‏VPN کو غیر فعال کریں"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"‏VPN کو غیر منسلک کریں"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"پالیسیاں دیکھیں"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"کنٹرولز دیکھیں"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"‏یہ آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کا ہے۔\n\nآپ کا IT منتظم ترتیبات، کارپوریٹ رسائی، ایپس، آپ کے آلہ سے وابستہ ڈیٹا اور آپ کے آلہ کے مقام کی معلومات کی نگرانی اور ان کا نظم کر سکتا ہے۔\n\nمزید معلومات کے لیے اپنے IT منتظم سے رابطہ کریں۔"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"‏یہ آلہ آپ کی تنظیم کا ہے۔\n\nآپ کا IT منتظم ترتیبات، کارپوریٹ رسائی، ایپس، آپ کے آلہ سے وابستہ ڈیٹا اور آپ کے آلہ کے مقام کی معلومات کی نگرانی اور ان کا نظم کر سکتا ہے۔\n\nمزید معلومات کے لیے اپنے IT منتظم سے رابطہ کریں۔"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"آپ کی تنظیم نے اس آلے پر ایک سرٹیفکیٹ کی اتھارٹی کو انسٹال کیا ہے۔ آپ کا محفوظ نیٹ ورک ٹریفک مانیٹر ہو سکتا ہے یا اس میں ترمیم کی جا سکتی ہے۔"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"آپ کے ایڈمن نے نیٹ ورک لاگنگ آن کر دی ہے، جو آپ کے آلہ پر ٹریفک کو مانیٹر کرتی ہے۔\n\nمزید معلومات کیلئے اپنے ایڈمن سے رابطہ کریں۔"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"‏آپ نے ایک ایپ کو VPN کنکشن ترتیب دینے کی اجازت دی ہے۔\n\nیہ ایپ ای میلز، ایپس اور ویب سائٹس سمیت آپ کے آلہ اور نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"‏آپ کی دفتری پروفائل <xliff:g id="ORGANIZATION">%1$s</xliff:g> کے زیر نظم ہے۔\n\nآپ کا ایڈمن بشمول ای میلز، ایپس، اور ویب سائٹس، آپ کے نیٹ ورک کی سرگرمی کو مانیٹر کرنے کا اہل ہے۔\n\nمزید معلومات کے لیے اپنے ایڈمن سے رابطہ کریں۔\n\nآپ ایک VPN سے بھی منسلک ہیں، جو آپ کے نیٹ ورک کی سرگرمی کو مانیٹر کر سکتا ہے۔"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"یہ آلہ آپ کے والدین کے زیر انتظام ہے۔ آپ کے والدین آپ کی استعمال والی ایپس، آپ کا مقام اور آپ کے اسکرین کے وقت جیسی معلومات کو دیکھ اور اس کا نظم کر سکتے ہیں۔"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"آپ <xliff:g id="APPLICATION">%1$s</xliff:g> سے منسلک ہیں، جو ای میلز، ایپس اور ویب سائٹس سمیت آپ کے نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"آپ <xliff:g id="APPLICATION">%1$s</xliff:g> سے منسلک ہیں، جو آپ کے نجی نیٹ ورک کی سرگرمی سمیت ای میلز، ایپس اور ویب سائٹس مانیٹر کر سکتی ہے۔"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"اس ایپ کی طرف سے اطلاعات دکھانا جاری رکھیں؟"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"خاموش"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ڈیفالٹ"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"بلبلہ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"خودکار"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"کوئی آواز یا وائبریشن نہیں"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"کوئی آواز یا وائبریشن نہیں اور گفتگو کے سیکشن میں نیچے ظاہر ہوتا ہے"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ترتیبات"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ترجیح"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> گفتگو کی خصوصیات کو سپورٹ نہیں کرتا ہے"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"کوئی حالیہ بلبلہ نہیں"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"حالیہ بلبلے اور برخاست شدہ بلبلے یہاں ظاہر ہوں گے"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ان اطلاعات کی ترمیم نہیں کی جا سکتی۔"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"اطلاعات کے اس گروپ کو یہاں کنفیگر نہیں کیا جا سکتا"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"پراکسی اطلاع"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"آلہ کی سروس"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"کوئی عنوان نہیں ہے"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"یہ ایپ دوبارہ شروع کرنے کے لیے تھپتھپائیں اور پوری اسکرین پر جائیں۔"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> بلبلوں کے لیے ترتیبات"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"اوورفلو"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"انبار میں واپس شامل کریں"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"نظم کریں"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> کی جانب سے <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> اور <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> مزید سے <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"منتقل کریں"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"اوپر بائیں جانب لے جائیں"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"اوپر دائیں جانب لے جائيں"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"نیچے بائیں جانب لے جائیں"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"نیچے دائیں جانب لے جائیں"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"بلبلہ برخاست کریں"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"گفتگو بلبلہ نہ کریں"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"بلبلے کے ذریعے چیٹ کریں"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"نئی گفتگوئیں فلوٹنگ آئیکن یا بلبلے کے طور پر ظاہر ہوں گی۔ بلبلہ کھولنے کے لیے تھپتھپائیں۔ اسے منتقل کرنے کے لیے گھسیٹیں۔"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"کسی بھی وقت بلبلے کو کنٹرول کریں"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"اس ایپ سے بلبلوں کو آف کرنے کے لیے نظم کریں پر تھپتھپائیں"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"سمجھ آ گئی"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ترتیبات"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"اسٹینڈ بائی"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"نئے آلہ کا جوڑا بنائیں"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"آپ کے بیٹری میٹر کو پڑھنے میں دشواری"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"مزید معلومات کے لیے تھپتھپائیں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings_tv.xml b/packages/SystemUI/res/values-ur/strings_tv.xml
index cb50faf..29e4307 100644
--- a/packages/SystemUI/res/values-ur/strings_tv.xml
+++ b/packages/SystemUI/res/values-ur/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"مائیکروفون فعال ہے"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"‏%1$s نے آپ کے مائیکروفون تک رسائی حاصل کی ہے"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 33d4f4c..997197d 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Qayta skrinshot olib ko‘ring"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Xotirada joy kamligi uchun skrinshot saqlanmadi"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ilova yoki tashkilotingiz skrinshot olishni taqiqlagan"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Skrinshotni tahrirlash"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Skrinshotni yopish"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Tahrirlash"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Skrinshotni tahrirlash"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Aylantirish"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Skrinshotni aylantirish"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Skrinshotni yopish"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Skrinshotga razm solish"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrandan yozib olish"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Batareya ikkta panelda."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Batareya uchta panelda."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Batareya to‘la."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batareya quvvati foizi nomaʼlum."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Signal yo‘q."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Telefon bitta panelda."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Telefon ikkita panelda."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Xabarnoma e‘tiborsiz qoldirildi."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Bulutcha yopildi."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Xabarnoma soyasi."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Tezkor sozlamalar."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Qulflash ekrani."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Profil kuzatilishi mumkin"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Tarmoqni kuzatish mumkin"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Tarmoq kuzatilishi mumkin"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu – ota-onangiz tomonidan boshqariladigan qurilma."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu qurilma tashkilotingizga tegishli va tarmoq trafigi tashkilotingiz tomonidan kuzatilishi mumkin"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va tarmoq trafigi tashkilot tomonidan kuzatilishi mumkin"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Bu qurilma tashkilotingizga tegishli va <xliff:g id="VPN_APP">%1$s</xliff:g> tarmogʻiga ulangan"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"VPN tarmog‘ini o‘chirish"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"VPN ulanishini uzish"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Siyosatlarni ko‘rish"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Boshqaruvni chiqarish"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli.\n\nAT administratori sozlamalar, korporativ ruxsat, ilovalar, qurilmaning geolokatsiyasi va unga aloqador axborotlarni kuzatishi va boshqarishi mumkin.\n\nBatafsil axborot uchun AT administratoriga murojaat qiling."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Bu qurilma tashkilotingizga tegishli.\n\nAT administratori sozlamalar, korporativ ruxsat, ilovalar, qurilmaning geolokatsiyasi va unga aloqador axborotlarni kuzatishi va boshqarishi mumkin.\n\nBatafsil axborot uchun AT administratoriga murojaat qiling."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tashkilotingiz bu qurilmada CA sertifikatini o‘rnatdi. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Administrator qurilmangizdagi trafikni nazorat qiluvchi tarmoq jurnalini yoqdi.\n\nBatafsil axborot olish uchun administratoringizga murojaat qiling."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Siz ilovaga VPN tarmog‘iga ulanishga ruxsat bergansiz.\n\nUshbu ilova qurilmangiz va internetdagi harakatlaringizni, jumladan, e-pochta, ilovalar va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Sizning ishchi profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministrator internetdagi harakatlaringizni, jumladan, e-pochta, ilova va xavfsiz veb-saytlar bilan ishlashingizni kuzatishi mumkin.\n\nBatafsil axborot olish uchun administrator bilan bog‘laning.\n\nShuningdek, siz VPN tarmog‘iga ham ulangansiz. U internetdagi harakatlaringizni kuzatishi mumkin."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu – ota-onangiz tomonidan boshqariladigan qurilma. Ota-onangiz siz foydalangan ilovalar, joylashuvingiz va qurilmadan foydalanish vaqti kabi axborotlarni koʻrishi va boshqarishi mumkin."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasi ishga tushirilgan. U tarmoqdagi, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasi ishga tushirilgan. U internetdagi harakatlaringiz, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Bu ilovadan keladigan bildirishnomalar chiqaversinmi?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Tovushsiz"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standart"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Pufaklar"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Tovush yoki tebranishsiz"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Tovush yoki tebranishsiz hamda suhbatlar ruknining pastida chiqadi"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Sozlamalar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Muhim"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasida suhbat funksiyalari ishlamaydi"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Avvalgi bulutchalar topilmadi"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Bu yerda oxirgi va yopilgan bulutcha shaklidagi bildirishnomalar chiqadi"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ushbu bildirishnomalar guruhi bu yerda sozlanmaydi"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Ishonchli bildirishnoma"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Qurilma xizmatlari"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nomsiz"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Bu ilovani qaytadan ishga tushirish va butun ekranga ochish uchun bosing."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> bulutchalari uchun sozlamalar"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Kengaytirilgan"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Yana toʻplamga kiritish"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Boshqarish"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> ilovasidan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> va yana <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ta bildirishnoma"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Surish"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Yuqori chapga surish"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Yuqori oʻngga surish"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Quyi chapga surish"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Quyi oʻngga surish"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Bulutchani yopish"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Suhbatlar bulutchalar shaklida chiqmasin"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Bulutchalar yordamida subhatlashish"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Yangi xabarlar qalqib chiquvchi belgilar yoki bulutchalar kabi chiqadi. Xabarni ochish uchun bildirishnoma ustiga bosing. Xabarni qayta joylash uchun bildirishnomani suring."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bulutchalardagi bildirishnomalar"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu ilova bulutchalarini faolsizlantirish uchun Boshqarish tugmasini bosing"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> sozlamalari"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Tizim navigatsiyasi yangilandi. Buni Sozlamalar orqali oʻzgartirishingiz mumkin."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Tizim navigatsiyasini yangilash uchun Sozlamalarni oching"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Kutib turing"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani ulash"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya quvvati aniqlanmadi"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Batafsil axborot olish uchun bosing"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings_tv.xml b/packages/SystemUI/res/values-uz/strings_tv.xml
index 09bc51e..3cab93d 100644
--- a/packages/SystemUI/res/values-uz/strings_tv.xml
+++ b/packages/SystemUI/res/values-uz/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Mikrofon faol"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s mikrofondan foydalandi"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 179f7c2..1acdbb5 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Hãy thử chụp lại màn hình"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Không thể lưu ảnh chụp màn hình do giới hạn dung lượng bộ nhớ"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ứng dụng hoặc tổ chức của bạn không cho phép chụp ảnh màn hình"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Chỉnh sửa ảnh chụp màn hình"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Đóng ảnh chụp màn hình"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"Chỉnh sửa"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Chỉnh sửa ảnh chụp màn hình"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"Cuộn"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"Cuộn để phóng to ảnh chụp màn hình"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Đóng ảnh chụp màn hình"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Xem trước ảnh chụp màn hình"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Trình ghi màn hình"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Đang xử lý video ghi màn hình"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Mức pin hai vạch."</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Mức pin ba vạch."</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Mức pin đầy."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Tỷ lệ phần trăm pin không xác định."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Không có điện thoại nào."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Tín hiệu điện thoại một vạch."</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Tín hiệu điện thoại hai vạch."</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Đã loại bỏ thông báo."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Đã đóng bong bóng."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bóng thông báo."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Cài đặt nhanh."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Màn hình khóa."</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Hồ sơ có thể được giám sát"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Mạng có thể được giám sát"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Mạng có thể được giám sát"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Thiết bị này do cha mẹ của bạn quản lý"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tổ chức của bạn sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Thiết bị này thuộc về tổ chức của bạn và đã kết nối với <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Tắt VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Ngắt kết nối VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Xem chính sách"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Xem các quyền kiểm soát"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Thiết bị này thuộc về <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nQuản trị viên CNTT có thể giám sát và quản lý các tùy chọn cài đặt, quyền truy cập vào dữ liệu công ty, ứng dụng, dữ liệu liên kết với thiết bị và thông tin vị trí thiết bị của bạn.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên CNTT của bạn."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Thiết bị này thuộc về tổ chức của bạn.\n\nQuản trị viên CNTT có thể giám sát và quản lý các tùy chọn cài đặt, quyền truy cập vào dữ liệu công ty, ứng dụng, dữ liệu liên kết với thiết bị và thông tin vị trí thiết bị của bạn.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên CNTT của bạn."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Tổ chức của bạn đã cài đặt một tổ chức phát hành chứng chỉ trên thiết bị này. Lưu lượng truy cập mạng bảo mật của bạn có thể được giám sát hoặc sửa đổi."</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Quản trị viên đã bật tính năng ghi nhật ký mạng. Tính năng này giám sát lưu lượng truy cập trên thiết bị của bạn.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên của bạn."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Bạn đã cấp cho ứng dụng quyền thiết lập kết nối VPN.\n\nỨng dụng này có thể giám sát hoạt động mạng và thiết bị của bạn, bao gồm email, ứng dụng và trang web."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Hồ sơ công việc của bạn do <xliff:g id="ORGANIZATION">%1$s</xliff:g> quản lý.\n\nQuản trị viên có thể giám sát hoạt động mạng của bạn bao gồm email, ứng dụng và trang web.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên của bạn.\n\nBạn cũng được kết nối với VPN. Dịch vụ này có thể giám sát hoạt động mạng của bạn."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Thiết bị này do cha mẹ bạn quản lý. Cha mẹ có thể có thể xem và quản lý những thông tin như ứng dụng bạn dùng, vị trí của bạn và thời gian bạn sử dụng thiết bị."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Bạn đang kết nối với <xliff:g id="APPLICATION">%1$s</xliff:g>. Ứng dụng này có thể giám sát hoạt động mạng của bạn bao gồm email, ứng dụng và trang web."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Bạn đang kết nối với <xliff:g id="APPLICATION">%1$s</xliff:g>. Ứng dụng này có thể giám sát hoạt động mạng cá nhân của bạn bao gồm email, ứng dụng và trang web."</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Tiếp tục hiển thị các thông báo từ ứng dụng này?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Im lặng"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Mặc định"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Bong bóng"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Tự động"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Không phát âm thanh hoặc rung"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Không phát âm thanh hoặc rung và xuất hiện phía dưới trong phần cuộc trò chuyện"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Cài đặt"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Mức độ ưu tiên"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> không hỗ trợ các tính năng trò chuyện"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Không có bong bóng trò chuyện nào gần đây"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Bong bóng trò chuyện đã đóng và bong bóng trò chuyện gần đây sẽ xuất hiện ở đây"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Không thể sửa đổi các thông báo này."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Không thể định cấu hình nhóm thông báo này tại đây"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Thông báo đã xử lý qua máy chủ proxy"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"Dịch vụ cho thiết bị"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Không có tiêu đề"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Tùy chọn cài đặt cho bong bóng trò chuyện <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Trình đơn mục bổ sung"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Thêm lại vào ngăn xếp"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Quản lý"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> của <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> từ <xliff:g id="APP_NAME">%2$s</xliff:g> và <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> bong bóng khác"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Di chuyển"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Chuyển lên trên cùng bên trái"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Chuyển lên trên cùng bên phải"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Chuyển tới dưới cùng bên trái"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Chuyển tới dưới cùng bên phải"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Đóng bong bóng"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Dừng sử dụng bong bóng cho cuộc trò chuyện"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Trò chuyện bằng bong bóng trò chuyện"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Các cuộc trò chuyện mới sẽ xuất hiện dưới dạng biểu tượng nổi hoặc bong bóng trò chuyện. Nhấn để mở bong bóng trò chuyện. Kéo để di chuyển bong bóng trò chuyện."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kiểm soát bong bóng bất cứ lúc nào"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Nhấn vào nút Quản lý để tắt bong bóng trò chuyện từ ứng dụng này"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"Cài đặt <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Đã cập nhật chế độ di chuyển trên hệ thống. Để thay đổi, hãy chuyển đến phần Cài đặt."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Chuyển đến phần Cài đặt để cập nhật chế độ di chuyển trên hệ thống"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Chế độ chờ"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Ghép nối thiết bị mới"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào khay nhớ tạm."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Đã xảy ra vấn đề khi đọc dung lượng pin của bạn"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Nhấn để biết thêm thông tin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml
index f298407..df09689 100644
--- a/packages/SystemUI/res/values-vi/strings_tv.xml
+++ b/packages/SystemUI/res/values-vi/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Micrô đang hoạt động"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s đang dùng micrô của bạn"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index e1f483c..5b6bb89 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"请再次尝试截屏"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"由于存储空间有限,无法保存屏幕截图"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"此应用或您所在的单位不允许进行屏幕截图"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"编辑屏幕截图"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"关闭屏幕截图"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"屏幕截图预览"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"屏幕录制器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"电池电量为两格。"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"电池电量为三格。"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"电池电量满格。"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"电池电量百分比未知。"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"没有手机信号。"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"手机信号强度为一格。"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"手机信号强度为两格。"</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"已关闭通知。"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"已关闭对话泡。"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"通知栏。"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"快捷设置。"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"锁定屏幕。"</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"资料可能会受到监控"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"网络可能会受到监控"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"网络可能会受到监控"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此设备由您的家长管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"贵单位拥有此设备,且可能会监控网络流量"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>拥有此设备,且可能会监控网络流量"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"此设备归贵单位所有,且已连接到“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"关闭VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"断开VPN连接"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"查看家长控制功能相关信息"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"此设备归<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>所有。\n\n您的 IT 管理员能够监控和管理与您的设备相关的设置、企业权限、应用、数据,以及您设备的位置信息。\n\n如需了解详情,请与您的 IT 管理员联系。"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"此设备归贵单位所有。\n\n您的 IT 管理员能够监控和管理与您的设备相关的设置、企业权限、应用、数据,以及您设备的位置信息。\n\n如需了解详情,请与您的 IT 管理员联系。"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"您所在的单位已在此设备上安装证书授权中心。您的安全网络流量可能会受到监控或修改。"</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"您的管理员已开启网络日志功能,该功能会监控您设备上的流量。\n\n如需更多信息,请与您的管理员联系。"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"您已授权应用设置 VPN 连接。\n\n该应用可以监控您的设备和网络活动,包括收发电子邮件、使用应用和浏览网站。"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"您的工作资料由“<xliff:g id="ORGANIZATION">%1$s</xliff:g>”管理。\n\n您的管理员能够监控您的网络活动,其中包括收发电子邮件、使用应用和访问网站。\n\n如需更多信息,请与您的管理员联系。\n\n此外,您还连接到了 VPN,它同样可以监控您的网络活动。"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"此设备由您的家长管理。您的家长可以查看和管理相关信息,例如您使用的应用、您的位置信息和设备使用时间。"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"您已连接到“<xliff:g id="APPLICATION">%1$s</xliff:g>”(该应用能够监控您的网络活动,其中包括收发电子邮件、使用应用和浏览网站)。"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"您已连接到<xliff:g id="APPLICATION">%1$s</xliff:g>,该应用可以监控您的个人网络活动,包括收发电子邮件、使用应用和浏览网站。"</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"要继续显示来自此应用的通知吗?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"静音"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"默认"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"气泡"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自动"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"不发出提示音,也不振动"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不发出提示音,也不振动;显示在对话部分的靠下位置"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"设置"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"优先"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>不支持对话功能"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"最近没有对话泡"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"此处会显示最近的对话泡和已关闭的对话泡"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"无法修改这些通知。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"您无法在此处配置这组通知"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"代理通知"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"设备服务"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"无标题"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"点按即可重启此应用并进入全屏模式。"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g>对话泡的设置"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"菜单"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"重新加入叠放"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"管理"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>:<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g>和另外 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> 个应用:<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"移动"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"移至左上角"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"移至右上角"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"移至左下角"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"移至右下角"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"关闭对话泡"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"不以对话泡形式显示对话"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"使用对话泡聊天"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"新对话会以浮动图标或对话泡形式显示。点按即可打开对话泡。拖动即可移动对话泡。"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"随时控制对话泡"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"点按“管理”按钮,可关闭来自此应用的对话泡"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"知道了"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>设置"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系统导航已更新。要进行更改,请转到“设置”。"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"转到“设置”即可更新系统导航"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待机"</string>
@@ -1089,4 +1079,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"读取电池计量器时出现问题"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"点按即可了解详情"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
index aa3e251..3d07311 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"麦克风处于启用状态"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s访问过您的麦克风"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index f986ef33..9c065fb 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"請再嘗試拍攝螢幕擷取畫面"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"由於儲存空間有限,因此無法儲存螢幕擷取畫面"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"應用程式或您的機構不允許擷取螢幕畫面"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"編輯螢幕截圖"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"關閉螢幕截圖"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"編輯"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"編輯螢幕截圖"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"拍攝長截圖"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"以捲動畫面的方式拍攝長截圖"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"關閉螢幕截圖"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"螢幕截圖預覽"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"螢幕畫面錄影工具"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在處理螢幕錄影內容"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"電池電量為兩格。"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"電池電量為三格。"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"電池已滿。"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"電量百分比不明。"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"沒有電話訊號。"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"電話訊號強度為一格。"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"電話訊號強度為兩格。"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"通知已關閉。"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"對話氣泡已關閉。"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"通知欄。"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"快速設定。"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"上鎖畫面。"</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"個人檔案可能受到監控"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"網絡可能會受到監控"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"網絡可能會受到監控"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此裝置由您的家長管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"您的機構擁有此裝置,並可能會監察網絡流量"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」擁有此裝置,並可能會監察網絡流量"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"此裝置屬於您的機構,並已連結至「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"停用 VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"中斷 VPN 連線"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"查看控制項"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"此裝置屬於 <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>。\n\n您的 IT 管理員可監察及管理與裝置相關聯的設定、公司存取權、應用程式和資料,以及裝置的位置資料。\n\n如要瞭解詳情,請與您的 IT 管理員聯絡。"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"此裝置屬於您的機構。\n\n您的 IT 管理員可監察及管理與裝置相關聯的設定、公司存取權、應用程式和資料,以及裝置的位置資料。\n\n如要瞭解詳情,請與您的 IT 管理員聯絡。"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"您的機構已在此裝置中安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"您的管理員已開啟網絡記錄功能,以監控您裝置上的流量。\n\n如需瞭解詳情,請聯絡您的管理員。"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"您已授權應用程式設定 VPN 連線。\n\n這個應用程式能夠監控您的裝置和網絡活動,包括電郵、應用程式和網站。"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"您的工作設定檔由<xliff:g id="ORGANIZATION">%1$s</xliff:g>管理。\n\n您的管理員可以監控您的網絡活動,包括收發電郵、使用應用程式和瀏覽網站。\n\n如需瞭解詳情,請聯絡您的管理員。\n\n此外,由於您已連接至 VPN,因此 VPN 可監控您的網絡活動。"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"此裝置由您的家長管理。家長可以查看及管理裝置上的資料,例如您使用的應用程式、位置和裝置使用時間。"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"您已連結至「<xliff:g id="APPLICATION">%1$s</xliff:g>」,此應用程式可以監控您的網絡活動,包括電郵、應用程式和網站。"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"您已連結至<xliff:g id="APPLICATION">%1$s</xliff:g>,它能夠監控您的個人網絡活動,包括電郵、應用程式和網站。"</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"要繼續顯示此應用程式的通知嗎?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"靜音"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"預設"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"氣泡"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"無音效或震動"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"無音效或震動,並在對話部分的較低位置顯示"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"設定"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"重要"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"沒有最近曾使用的小視窗"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"最近使用和關閉的小視窗會在這裡顯示"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在此設定這組通知"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"代理通知"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"裝置服務"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"輕按即可重新開啟此應用程式並放大至全螢幕。"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」小視窗設定"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"顯示更多"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"加回堆疊"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"管理"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"來自「<xliff:g id="APP_NAME">%2$s</xliff:g>」的 <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"來自「<xliff:g id="APP_NAME">%2$s</xliff:g>」及另外 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> 個應用程式的<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"移動"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"移去左上角"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"移去右上角"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"移去左下角"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"移去右下角"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"關閉小視窗氣泡"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"不要透過小視窗顯示對話"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"使用小視窗進行即時通訊"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"新對話會以浮動圖示 (小視窗) 顯示。輕按即可開啟小視窗。拖曳即可移動小視窗。"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"隨時控制小視窗設定"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"輕按「管理」即可關閉此應用程式的小視窗"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"知道了"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"「<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>」設定"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統導覽已更新。如需變更,請前往「設定」。"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"前往「設定」更新系統導覽"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕按即可瞭解詳情"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
index 45d3229..b0baf19 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"麥克風已啟用"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"「%1$s」已存取您的麥克風"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index b442b79..85aae2e 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -86,8 +86,11 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"請再次嘗試拍攝螢幕截圖"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"由於儲存空間有限,因此無法儲存螢幕截圖"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"這個應用程式或貴機構不允許擷取螢幕畫面"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"編輯螢幕截圖"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"關閉螢幕截圖"</string>
+    <string name="screenshot_edit_label" msgid="8754981973544133050">"編輯"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"編輯螢幕截圖"</string>
+    <string name="screenshot_scroll_label" msgid="7682877978685434621">"拍攝長截圖"</string>
+    <string name="screenshot_scroll_description" msgid="7855773867093272175">"以捲動畫面的方式拍攝長截圖"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"關閉螢幕截圖"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"螢幕截圖預覽"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"螢幕錄影器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string>
@@ -182,6 +185,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"電池電量兩格。"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"電池電量三格。"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"電池電量已滿。"</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"電池電量不明。"</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"沒有電話訊號。"</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"電話訊號強度一格。"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"電話訊號強度兩格。"</string>
@@ -255,7 +259,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"已關閉通知。"</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"已關閉泡泡。"</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"通知欄。"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"快捷設定。"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"螢幕鎖定。"</string>
@@ -520,6 +523,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"設定檔可能會受到監控"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"網路可能會受到監控"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"網路可能會受到監控"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"這個裝置是由你的家長管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"貴機構擁有這部裝置,而且可能會監控網路流量"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,而且該機構可能會監控網路流量"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"這部裝置的擁有者為貴機構,並且已連線到「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
@@ -544,6 +548,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"停用 VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"中斷 VPN 連線"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"查看監護功能相關資訊"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」。\n\n你的 IT 管理員可以監控及管理與裝置相關聯的設定、公司系統權限、應用程式和資料,以及裝置的位置資訊。\n\n如要瞭解詳情,請與你的 IT 管理員聯絡。"</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"這部裝置的擁有者為貴機構。\n\n你的 IT 管理員可以監控及管理與裝置相關聯的設定、公司系統權限、應用程式和資料,以及裝置的位置資訊。\n\n如要瞭解詳情,請與你的 IT 管理員聯絡。"</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"貴機構已為這個裝置安裝憑證授權單位憑證。你的安全網路流量可能會受到監控或修改。"</string>
@@ -567,6 +572,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"你的管理員已啟用網路記錄功能,可監控你裝置的流量。\n\n如需詳細資訊,請與你的管理員聯絡。"</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"你已授權一個應用程式設定 VPN 連線。\n\n這個應用程式可以監控你的裝置和網路活動,包括收發電子郵件、使用應用程式和瀏覽網站。"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"你的工作資料夾是由下列機構管理:<xliff:g id="ORGANIZATION">%1$s</xliff:g>。\n\n你的管理員可以監控你的網路活動,包括收發電子郵件、使用應用程式及瀏覽網站。\n\n如需詳細資訊,請與你的管理員聯絡。\n\n此外,由於你已連線至 VPN,因此你的網路活動也會受到 VPN 監控。"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"這個裝置是由你的家長管理。家長可以查看及管理裝置上的資訊,例如你使用的應用程式、所在位置和裝置使用時間。"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"由於你已連結至「<xliff:g id="APPLICATION">%1$s</xliff:g>」,因此你的網路活動 (包括收發電子郵件、使用應用程式和瀏覽網站) 可能會受到這個應用程式監控。"</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"由於你已連線至 <xliff:g id="APPLICATION">%1$s</xliff:g>,你的個人網路活動也會受到這個應用程式監控,包括收發電子郵件、使用應用程式和瀏覽網站。"</string>
@@ -709,7 +715,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"要繼續顯示這個應用程式的通知嗎?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"靜音"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"預設"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"泡泡"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"不震動或發出聲音"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不震動或發出聲音,並調整排序到其他對話下方"</string>
@@ -721,8 +726,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"設定"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"最近沒有任何對話框"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"最近的對話框和已關閉的對話框會顯示在這裡"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在這裡設定這個通知群組"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"經過 Proxy 處理的通知"</string>
@@ -981,25 +984,7 @@
     <string name="device_services" msgid="1549944177856658705">"裝置服務"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"輕觸即可重新啟動這個應用程式並進入全螢幕模式。"</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」對話框的設定"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"溢位"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"重新加入堆疊"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"管理"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>:<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"「<xliff:g id="APP_NAME">%2$s</xliff:g>」和其他 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> 個應用程式:<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"移動"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"移至左上方"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"移至右上方"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"移至左下方"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"移至右下方"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"關閉對話框"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"不要以對話框形式顯示對話"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"透過對話框來聊天"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"新的對話會以浮動圖示或對話框形式顯示。輕觸即可開啟對話框,拖曳則可移動對話框。"</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"你隨時可以控管對話框的各項設定"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"輕觸 [管理] 即可關閉來自這個應用程式的對話框"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"我知道了"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"「<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>」設定"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"請前往「設定」更新系統操作機制"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
@@ -1089,4 +1074,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕觸即可瞭解詳情"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
index fdd0884..64e0538c 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"麥克風已開啟"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"「%1$s」已存取你的麥克風"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 764f0b7..1a10121 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -86,8 +86,16 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Zama ukuthatha isithombe-skrini futhi"</string>
     <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Ayikwazi ukulondoloza isithombe-skrini ngenxa yesikhala sesitoreji esikhawulelwe"</string>
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ukuthatha izithombe-skrini akuvunyelwe uhlelo lokusebenza noma inhlangano yakho"</string>
-    <string name="screenshot_edit" msgid="3510496440489019191">"Hlela isithombe-skrini"</string>
-    <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Cashisa isithombe-skrini"</string>
+    <!-- no translation found for screenshot_edit_label (8754981973544133050) -->
+    <skip />
+    <!-- no translation found for screenshot_edit_description (3333092254706788906) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_label (7682877978685434621) -->
+    <skip />
+    <!-- no translation found for screenshot_scroll_description (7855773867093272175) -->
+    <skip />
+    <!-- no translation found for screenshot_dismiss_description (4702341245899508786) -->
+    <skip />
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ukubuka kuqala isithombe-skrini"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Irekhoda yesikrini"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Icubungula okokuqopha iskrini"</string>
@@ -182,6 +190,7 @@
     <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"Amabha amabili ebhethri"</string>
     <string name="accessibility_battery_three_bars" msgid="118341923832368291">"Amabha amathathu ebhethri"</string>
     <string name="accessibility_battery_full" msgid="1480463938961288494">"Ibhethri igcwele."</string>
+    <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Iphesenti lebhethri alaziwa."</string>
     <string name="accessibility_no_phone" msgid="8828412144430247025">"Ayikho ifoni."</string>
     <string name="accessibility_phone_one_bar" msgid="8786055123727785588">"Ibha eyodwa yefoni"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"Amabha amabilil efoni."</string>
@@ -255,7 +264,6 @@
     <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Isaziso sichithiwe."</string>
-    <string name="accessibility_bubble_dismissed" msgid="270358867566720729">"Ibhamuza licashisiwe."</string>
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Umthunzi wesaziso."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Izilingiselelo ezisheshayo."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Khiya isikrini."</string>
@@ -520,6 +528,7 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"Iphrofayela ingaqashwa"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"Inethiwekhi kungenzeka iqashiwe"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"Inethiwekhi kungenzeka iqashiwe"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Le divayisi iphethwe ngumzali wakho"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Inhlangano yakho ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"I-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="6096715329056415588">"Le divayisi ngeyenhlangano yakho futhi ixhunywe ku-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
@@ -544,6 +553,7 @@
     <string name="disable_vpn" msgid="482685974985502922">"Khubaza i-VPN"</string>
     <string name="disconnect_vpn" msgid="26286850045344557">"Nqamula i-VPN"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Buka izinqubomgomo"</string>
+    <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Buka izilawuli"</string>
     <string name="monitoring_description_named_management" msgid="505833016545056036">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nUmphathi wakho we-IT angakwazi ukugada nokulawula amasethingi, ukufinyelela kwenhlangano, izinhlelo zokusebenza, idatha ehlobene nedivayisi yakho, nolwazi lwendawo yedivayisi yakho.\n\nUkuze uthole ulwazi olwengeziwe, xhumana nomphathi wakho we-IT."</string>
     <string name="monitoring_description_management" msgid="4308879039175729014">"Le divayisi ngeyenhlangano.\n\nUmphathi wakho we-IT angakwazi ukugada nokulawula amasethingi, ukufinyelela kwenhlangano, izinhlelo zokusebenza, idatha ehlobene nedivayisi yakho, nolwazi lwendawo yedivayisi yakho.\n\nUkuze uthole ulwazi olwengeziwe, xhumana nomphathi wakho we-IT."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Inhlangano yakho ifake ukugunyazwa kwesitifiketi kule divayisi. Ithrafikhi yenethiwekhi yakho evikelekile kungenzeka iqashelwe noma ilungiswe."</string>
@@ -567,6 +577,7 @@
     <string name="monitoring_description_network_logging" msgid="577305979174002252">"Umlawuli wakho uvule ukungena kwenethiwekhi, okuhlola ithrafikhi kudivayisi yakho.\n\nNgolwazi olubanzi xhumana nomlawuli wakho."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"Unikeze uhlelo lokusebenza imvume yokusetha ukuxhumana kwe-VPN.\n\nLolu hlelo lokusebenza lungahlola idivayisi yakho nomsebenzi wenethiwekhi, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"Iphrofayela yakho yomsebenzi iphethwe ngu-<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nUmlawuli wakho uyakwazi ukwengamela umsebenzi wakho wenethiwekhi kufaka phakathi ama-imeyili, izinhlelo zokusebenza, namawebhusayithi.\n\nNgolwazi olubanzi, xhumana nomlawuli wakho.\n\nFuthi uxhumekile ku-VPN, engangamela umsebenzi wakho wenethiwekhi."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Le divayisi iphethwe ngumzali wakho. Umzali wakho angabona futhi aphathe ulwazi olunjengezinhlelo zokusebenza ozisebenzisayo, indawo yakho, kanye nesikhathi sesikrini."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"I-VPN"</string>
     <string name="monitoring_description_app" msgid="376868879287922929">"Uxhumeke ku-<xliff:g id="APPLICATION">%1$s</xliff:g>, engaqapha umsebenzi wakho wenethiwekhi, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi."</string>
     <string name="monitoring_description_app_personal" msgid="1970094872688265987">"Uxhumeke ku-<xliff:g id="APPLICATION">%1$s</xliff:g>, engahlola umsebenzi wenethiwekhi yakho yomuntu siqu, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi."</string>
@@ -709,7 +720,6 @@
     <string name="inline_keep_showing_app" msgid="4393429060390649757">"Qhubeka nokubonisa izaziso kusuka kulolu hlelo lokusebenza?"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Kuthulile"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Okuzenzekelayo"</string>
-    <string name="notification_bubble_title" msgid="8330481035191903164">"Ibhamuza"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Okuzenzekelayo"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Awukho umsindo noma ukudlidliza"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Awukho umsindo noma ukudlidliza futhi ivela ngezansi esigabeni sengxoxo"</string>
@@ -721,8 +731,6 @@
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Izilungiselelo"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Okubalulekile"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayisekeli izici zengxoxo"</string>
-    <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Awekho amabhamuza akamuva"</string>
-    <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Amabhamuza akamuva namabhamuza asusiwe azobonakala lapha."</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Lezi zaziso azikwazi ukushintshwa."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Leli qembu lezaziso alikwazi ukulungiselelwa lapha"</string>
     <string name="notification_delegate_header" msgid="1264510071031479920">"Isaziso sommeli"</string>
@@ -981,25 +989,7 @@
     <string name="device_services" msgid="1549944177856658705">"Amasevisi edivayisi"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Asikho isihloko"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Thepha ukuze uqale kabusha lolu hlelo lokusebenza uphinde uye kusikrini esigcwele."</string>
-    <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Izilungiselelo zamabhamuza e-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Ukuphuphuma"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Engeza emuva kusitaki"</string>
-    <string name="manage_bubbles_text" msgid="6856830436329494850">"Phatha"</string>
-    <string name="bubble_content_description_single" msgid="5175160674436546329">"I-<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> kusuka ku-<xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="bubble_content_description_stack" msgid="7907610717462651870">"I-<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> kusukela ku-<xliff:g id="APP_NAME">%2$s</xliff:g> nokungu-<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ngaphezulu"</string>
     <string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Hambisa"</string>
-    <string name="bubble_accessibility_action_move_top_left" msgid="4347227665275929728">"Hambisa phezulu kwesokunxele"</string>
-    <string name="bubble_accessibility_action_move_top_right" msgid="6916868852433483569">"Hambisa phezulu ngakwesokudla"</string>
-    <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Hambisa inkinobho ngakwesokunxele"</string>
-    <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Hambisa inkinobho ngakwesokudla"</string>
-    <string name="bubble_dismiss_text" msgid="1314082410868930066">"Cashisa ibhamuza"</string>
-    <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Ungayibhamuzi ingxoxo"</string>
-    <string name="bubbles_user_education_title" msgid="5547017089271445797">"Xoxa usebenzisa amabhamuza"</string>
-    <string name="bubbles_user_education_description" msgid="1160281719576715211">"Izingxoxo ezintsha zivela njengezithonjana ezintantayo, noma amabhamuza. Thepha ukuze uvule ibhamuza. Hudula ukuze ulihambise."</string>
-    <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Lawula amabhamuza noma nini"</string>
-    <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Thepha okuthi Phatha ukuvala amabhamuza kusuka kulolu hlelo lokusebenza"</string>
-    <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ngiyezwa"</string>
-    <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> izilungiselelo"</string>
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Ukuzulazula kwesistimu kubuyekeziwe. Ukuze wenze ushintsho, hamba kokuthi Izilungiselelo."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Hamba kuzilungiselelo ukuze ubuyekeze ukuzulazula kwesistimu"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ilindile"</string>
@@ -1086,7 +1076,9 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"amadivayisi akhethiwe angu-<xliff:g id="COUNT">%1$d</xliff:g>"</string>
     <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (inqamukile)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Ayikwazanga ukuxhumeka. Zama futhi."</string>
-    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhanqa idivayisi entsha"</string>
+    <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhangqa idivayisi entsha"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
+    <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kube khona inkinga ngokufunda imitha yakho yebhethri"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Thepha ukuze uthole olunye ulwazi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml
index 4fed753..46ff929 100644
--- a/packages/SystemUI/res/values-zu/strings_tv.xml
+++ b/packages/SystemUI/res/values-zu/strings_tv.xml
@@ -21,4 +21,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="mic_active" msgid="5766614241012047024">"Imakrofoni iyasebenza"</string>
     <string name="app_accessed_mic" msgid="2754428675130470196">"%1$s ifinyelele imakrofoni yakho"</string>
+    <!-- no translation found for notification_vpn_connected (3891023882833274730) -->
+    <skip />
+    <!-- no translation found for notification_vpn_disconnected (7150747626448044843) -->
+    <skip />
+    <!-- no translation found for notification_disclosure_vpn_text (3873532735584866236) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 6df8b4e..be36316 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -204,10 +204,6 @@
     <color name="global_screenshot_dismiss_foreground">@color/GM2_grey_500</color>
     <color name="global_screenshot_background_protection_start">#40000000</color> <!-- 25% black -->
 
-    <!-- Bubbles -->
-    <color name="bubbles_light">#FFFFFF</color>
-    <color name="bubbles_dark">@color/GM2_grey_800</color>
-
     <!-- GM2 colors -->
     <color name="GM2_grey_50">#F8F9FA</color>
     <color name="GM2_grey_100">#F1F3F4</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 17dc400..a2e9f39 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1159,90 +1159,6 @@
     <!-- Radius of Ongoing App Ops chip corners -->
     <dimen name="ongoing_appops_chip_bg_corner_radius">16dp</dimen>
 
-
-    <!-- How much each bubble is elevated. -->
-    <dimen name="bubble_elevation">1dp</dimen>
-    <!-- How much the bubble flyout text container is elevated. -->
-    <dimen name="bubble_flyout_elevation">4dp</dimen>
-    <!-- How much padding is around the left and right sides of the flyout text. -->
-    <dimen name="bubble_flyout_padding_x">12dp</dimen>
-    <!-- How much padding is around the top and bottom of the flyout text. -->
-    <dimen name="bubble_flyout_padding_y">10dp</dimen>
-    <!-- Size of the triangle that points from the flyout to the bubble stack. -->
-    <dimen name="bubble_flyout_pointer_size">6dp</dimen>
-    <!-- How much space to leave between the flyout (tip of the arrow) and the bubble stack. -->
-    <dimen name="bubble_flyout_space_from_bubble">8dp</dimen>
-    <!-- How much space to leave between the flyout text and the avatar displayed in the flyout. -->
-    <dimen name="bubble_flyout_avatar_message_space">6dp</dimen>
-    <!-- Padding between status bar and bubbles when displayed in expanded state -->
-    <dimen name="bubble_padding_top">16dp</dimen>
-    <!-- Size of individual bubbles. -->
-    <dimen name="individual_bubble_size">60dp</dimen>
-    <!-- Size of bubble bitmap. -->
-    <dimen name="bubble_bitmap_size">52dp</dimen>
-    <!-- Size of bubble icon bitmap. -->
-    <dimen name="bubble_overflow_icon_bitmap_size">24dp</dimen>
-    <!-- Extra padding added to the touchable rect for bubbles so they are easier to grab. -->
-    <dimen name="bubble_touch_padding">12dp</dimen>
-    <!-- Size of the circle around the bubbles when they're in the dismiss target. -->
-    <dimen name="bubble_dismiss_encircle_size">52dp</dimen>
-    <!-- Padding around the view displayed when the bubble is expanded -->
-    <dimen name="bubble_expanded_view_padding">4dp</dimen>
-    <!-- This should be at least the size of bubble_expanded_view_padding; it is used to include
-         a slight touch slop around the expanded view. -->
-    <dimen name="bubble_expanded_view_slop">8dp</dimen>
-    <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded -->
-    <dimen name="bubble_expanded_default_height">180dp</dimen>
-    <!-- Default height of bubble overflow -->
-    <dimen name="bubble_overflow_height">480dp</dimen>
-    <!-- Bubble overflow padding when there are no bubbles  -->
-    <dimen name="bubble_overflow_empty_state_padding">16dp</dimen>
-    <!-- Padding of container for overflow bubbles -->
-    <dimen name="bubble_overflow_padding">15dp</dimen>
-    <!-- Padding of label for bubble overflow view -->
-    <dimen name="bubble_overflow_text_padding">7dp</dimen>
-    <!-- Height of bubble overflow empty state illustration -->
-    <dimen name="bubble_empty_overflow_image_height">200dp</dimen>
-    <!-- Padding of bubble overflow empty state subtitle -->
-    <dimen name="bubble_empty_overflow_subtitle_padding">50dp</dimen>
-    <!-- Height of the triangle that points to the expanded bubble -->
-    <dimen name="bubble_pointer_height">8dp</dimen>
-    <!-- Width of the triangle that points to the expanded bubble -->
-    <dimen name="bubble_pointer_width">12dp</dimen>
-    <!-- Extra padding around the dismiss target for bubbles -->
-    <dimen name="bubble_dismiss_slop">16dp</dimen>
-    <!-- Height of button allowing users to adjust settings for bubbles. -->
-    <dimen name="bubble_manage_button_height">48dp</dimen>
-    <!-- Max width of the message bubble-->
-    <dimen name="bubble_message_max_width">144dp</dimen>
-    <!-- Min width of the message bubble -->
-    <dimen name="bubble_message_min_width">32dp</dimen>
-    <!-- Interior padding of the message bubble -->
-    <dimen name="bubble_message_padding">4dp</dimen>
-    <!-- Offset between bubbles in their stacked position. -->
-    <dimen name="bubble_stack_offset">10dp</dimen>
-    <!-- Offset between stack y and animation y for bubble swap. -->
-    <dimen name="bubble_swap_animation_offset">15dp</dimen>
-    <!-- How far offscreen the bubble stack rests. Cuts off padding and part of icon bitmap. -->
-    <dimen name="bubble_stack_offscreen">9dp</dimen>
-    <!-- How far down the screen the stack starts. -->
-    <dimen name="bubble_stack_starting_offset_y">120dp</dimen>
-    <!-- Space between the pointer triangle and the bubble expanded view -->
-    <dimen name="bubble_pointer_margin">8dp</dimen>
-    <!-- Padding applied to the bubble dismiss target. Touches in this padding cause the bubbles to
-         snap to the dismiss target. -->
-    <dimen name="bubble_dismiss_target_padding_x">40dp</dimen>
-    <dimen name="bubble_dismiss_target_padding_y">20dp</dimen>
-    <dimen name="bubble_manage_menu_elevation">4dp</dimen>
-
-    <!-- Bubbles user education views -->
-    <dimen name="bubbles_manage_education_width">160dp</dimen>
-    <!-- The inset from the top bound of the manage button to place the user education. -->
-    <dimen name="bubbles_manage_education_top_inset">65dp</dimen>
-    <!-- Size of padding for the user education cling, this should at minimum be larger than
-        individual_bubble_size + some padding. -->
-    <dimen name="bubble_stack_user_education_side_inset">72dp</dimen>
-
     <!-- Size of the RAT type for CellularTile -->
     <dimen name="celltile_rat_type_size">10sp</dimen>
 
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 7d3135a..5f68bdb4 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -130,12 +130,6 @@
     <item type="id" name="action_snooze_assistant_suggestion_1"/>
     <item type="id" name="action_snooze"/>
 
-    <!-- Accessibility actions for bubbles. -->
-    <item type="id" name="action_move_top_left"/>
-    <item type="id" name="action_move_top_right"/>
-    <item type="id" name="action_move_bottom_left"/>
-    <item type="id" name="action_move_bottom_right"/>
-
     <!-- For StatusIconContainer to tag its icon views -->
     <item type="id" name="status_bar_view_state_tag" />
 
@@ -146,17 +140,6 @@
     <!-- Optional cancel button on Keyguard -->
     <item type="id" name="cancel_button"/>
 
-    <!-- For saving PhysicsAnimationLayout animations/animators as view tags. -->
-    <item type="id" name="translation_x_dynamicanimation_tag"/>
-    <item type="id" name="translation_y_dynamicanimation_tag"/>
-    <item type="id" name="translation_z_dynamicanimation_tag"/>
-    <item type="id" name="alpha_dynamicanimation_tag"/>
-    <item type="id" name="scale_x_dynamicanimation_tag"/>
-    <item type="id" name="scale_y_dynamicanimation_tag"/>
-    <item type="id" name="physics_animator_tag"/>
-    <item type="id" name="target_animator_tag" />
-    <item type="id" name="reorder_animator_tag"/>
-
     <!-- Global Actions Menu -->
     <item type="id" name="global_actions_view" />
 
diff --git a/packages/SystemUI/res/values/integers.xml b/packages/SystemUI/res/values/integers.xml
index b1e91c8..b50b5c1 100644
--- a/packages/SystemUI/res/values/integers.xml
+++ b/packages/SystemUI/res/values/integers.xml
@@ -22,17 +22,6 @@
     <integer name="qs_footer_actions_width">0</integer>
     <integer name="qs_footer_actions_weight">1</integer>
 
-    <!-- Maximum number of bubbles to render and animate at one time. While the animations used are
-         lightweight translation animations, this number can be reduced on lower end devices if any
-         performance issues arise. -->
-    <integer name="bubbles_max_rendered">5</integer>
-
-    <!-- Number of columns in bubble overflow. -->
-    <integer name="bubbles_overflow_columns">4</integer>
-
-    <!-- Maximum number of bubbles we allow in overflow before we dismiss the oldest one. -->
-    <integer name="bubbles_max_overflow">16</integer>
-
     <integer name="magnification_default_scale">2</integer>
 
     <!-- The position of the volume dialog on the screen.
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d5c9823..773ef7d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -233,10 +233,16 @@
     <!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] -->
     <string name="screenshot_failed_to_capture_text">Taking screenshots isn\'t allowed by the app or
         your organization</string>
+    <!-- Label for UI element which allows editing the screenshot [CHAR LIMIT=30] -->
+    <string name="screenshot_edit_label">Edit</string>
     <!-- Content description indicating that tapping the element will allow editing the screenshot [CHAR LIMIT=NONE] -->
-    <string name="screenshot_edit">Edit screenshot</string>
+    <string name="screenshot_edit_description">Edit screenshot</string>
+    <!-- Label for UI element which allows scrolling and extending the screenshot to be taller [CHAR LIMIT=30] -->
+    <string name="screenshot_scroll_label">Scroll</string>
+    <!-- Content description UI element which allows scrolling and extending the screenshot to be taller [CHAR LIMIT=NONE] -->
+    <string name="screenshot_scroll_description">Scroll screenshot</string>
     <!-- Content description indicating that tapping a button will dismiss the screenshots UI [CHAR LIMIT=NONE] -->
-    <string name="screenshot_dismiss_ui_description">Dismiss screenshot</string>
+    <string name="screenshot_dismiss_description">Dismiss screenshot</string>
     <!-- Content description indicating that the view is a preview of the screenshot that was just taken [CHAR LIMIT=NONE] -->
     <string name="screenshot_preview_description">Screenshot preview</string>
 
@@ -646,9 +652,6 @@
     <!-- Content description to tell the user a notification has been removed from the notification shade -->
     <string name="accessibility_notification_dismissed">Notification dismissed.</string>
 
-    <!-- Content description to tell the user a bubble has been dismissed. -->
-    <string name="accessibility_bubble_dismissed">Bubble dismissed.</string>
-
     <!-- Content description for the notification shade panel (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_desc_notification_shade">Notification shade.</string>
     <!-- Content description for the quick settings panel (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -1846,9 +1849,6 @@
     <string name="notification_alert_title">Default</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance title -->
-    <string name="notification_bubble_title">Bubble</string>
-
-    <!-- [CHAR LIMIT=100] Notification Importance title -->
     <string name="notification_automatic_title">Automatic</string>
 
     <!-- [CHAR LIMIT=150] Notification Importance title: low importance level summary -->
@@ -1881,12 +1881,6 @@
     <!-- Text shown in notification guts for conversation notifications that don't implement the full feature -->
     <string name="no_shortcut"><xliff:g id="app_name" example="YouTube">%1$s</xliff:g> doesn\u2019t support conversation features</string>
 
-    <!-- [CHAR LIMIT=NONE] Empty overflow title -->
-    <string name="bubble_overflow_empty_title">No recent bubbles</string>
-
-    <!-- [CHAR LIMIT=NONE] Empty overflow subtitle -->
-    <string name="bubble_overflow_empty_subtitle">Recent bubbles and dismissed bubbles will appear here</string>
-
     <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
     <string name="notification_unblockable_desc">These notifications can\'t be modified.</string>
 
@@ -2607,45 +2601,8 @@
     <!-- Description of the restart button in the hint of size compatibility mode. [CHAR LIMIT=NONE] -->
     <string name="restart_button_description">Tap to restart this app and go full screen.</string>
 
-    <!-- Text used for content description of settings button in the header of expanded bubble
-         view. [CHAR_LIMIT=NONE] -->
-    <string name="bubbles_settings_button_description">Settings for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> bubbles</string>
-    <!-- Content description for button that shows bubble overflow on click [CHAR LIMIT=NONE] -->
-    <string name="bubble_overflow_button_content_description">Overflow</string>
-    <!-- Action to add overflow bubble back to stack. [CHAR LIMIT=NONE] -->
-    <string name="bubble_accessibility_action_add_back">Add back to stack</string>
-    <!-- The text for the manage bubbles link. [CHAR LIMIT=NONE] -->
-    <string name="manage_bubbles_text">Manage</string>
-    <!-- Content description when a bubble is focused. [CHAR LIMIT=NONE] -->
-    <string name="bubble_content_description_single"><xliff:g id="notification_title" example="some title">%1$s</xliff:g> from <xliff:g id="app_name" example="YouTube">%2$s</xliff:g></string>
-    <!-- Content description when the stack of bubbles is focused. [CHAR LIMIT=NONE] -->
-    <string name="bubble_content_description_stack"><xliff:g id="notification_title" example="some title">%1$s</xliff:g> from <xliff:g id="app_name" example="YouTube">%2$s</xliff:g> and <xliff:g id="bubble_count" example="4">%3$d</xliff:g> more</string>
     <!-- Action in accessibility menu to move the stack of bubbles [CHAR LIMIT=20] -->
     <string name="bubble_accessibility_action_move">Move</string>
-    <!-- Action in accessibility menu to move the stack of bubbles to the top left of the screen. [CHAR LIMIT=30] -->
-    <string name="bubble_accessibility_action_move_top_left">Move top left</string>
-    <!-- Action in accessibility menu to move the stack of bubbles to the top right of the screen. [CHAR LIMIT=30] -->
-    <string name="bubble_accessibility_action_move_top_right">Move top right</string>
-    <!-- Action in accessibility menu to move the stack of bubbles to the bottom left of the screen. [CHAR LIMIT=30]-->
-    <string name="bubble_accessibility_action_move_bottom_left">Move bottom left</string>
-    <!-- Action in accessibility menu to move the stack of bubbles to the bottom right of the screen. [CHAR LIMIT=30]-->
-    <string name="bubble_accessibility_action_move_bottom_right">Move bottom right</string>
-    <!-- Text used for the bubble dismiss area. Bubbles dragged to, or flung towards, this area will go away. [CHAR LIMIT=30] -->
-    <string name="bubble_dismiss_text">Dismiss bubble</string>
-    <!-- Button text to stop a conversation from bubbling [CHAR LIMIT=60]-->
-    <string name="bubbles_dont_bubble_conversation">Don\u2019t bubble conversation</string>
-    <!-- Title text for the bubbles feature education cling shown when a bubble is on screen for the first time. [CHAR LIMIT=60]-->
-    <string name="bubbles_user_education_title">Chat using bubbles</string>
-    <!-- Descriptive text for the bubble feature education cling shown when a bubble is on screen for the first time. [CHAR LIMIT=NONE] -->
-    <string name="bubbles_user_education_description">New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it.</string>
-    <!-- Title text for the bubble "manage" button tool tip highlighting where users can go to control bubble settings. [CHAR LIMIT=60]-->
-    <string name="bubbles_user_education_manage_title">Control bubbles anytime</string>
-    <!-- Descriptive text for the bubble "manage" button tool tip highlighting where users can go to control bubble settings. [CHAR LIMIT=80]-->
-    <string name="bubbles_user_education_manage">Tap Manage to turn off bubbles from this app</string>
-    <!-- Button text for dismissing the bubble "manage" button tool tip  [CHAR LIMIT=20]-->
-    <string name="bubbles_user_education_got_it">Got it</string>
-    <!-- Label for the button that takes the user to the notification settings for the given app. -->
-    <string name="bubbles_app_settings"><xliff:g id="notification_title" example="Android Messages">%1$s</xliff:g> settings</string>
 
     <!-- Notification content text when the system navigation mode changes as a result of changing the default launcher [CHAR LIMIT=NONE] -->
     <string name="notification_content_system_nav_changed">System navigation updated. To make changes, go to Settings.</string>
diff --git a/packages/SystemUI/res/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml
index 5d7f08e..13271d6 100644
--- a/packages/SystemUI/res/values/strings_tv.xml
+++ b/packages/SystemUI/res/values/strings_tv.xml
@@ -20,4 +20,10 @@
     <!-- Title and subtitle for AudioRecordingIndicator -->
     <string name="mic_active">Microphone Active</string>
     <string name="app_accessed_mic">%1$s accessed your microphone</string>
+
+    <string name="notification_vpn_connected">VPN is connected</string>
+    <string name="notification_vpn_disconnected">VPN is disconnected</string>
+    <!-- Disclosure text in the connected notification that indicates that the device is connected to a VPN. The placeholder is the VPN name. [CHAR LIMIT=40] -->
+    <string name="notification_disclosure_vpn_text">Via <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string>
+
 </resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 4238019..dd57af3 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -34,8 +34,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.graphics.Rect;
@@ -45,7 +43,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.IRecentsAnimationController;
@@ -58,7 +55,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.Future;
 import java.util.function.Consumer;
 
 public class ActivityManagerWrapper {
@@ -74,14 +70,7 @@
     // Should match the value in AssistManager
     private static final String INVOCATION_TIME_MS_KEY = "invocation_time_ms";
 
-    private final PackageManager mPackageManager;
-    private final BackgroundExecutor mBackgroundExecutor;
-
-    private ActivityManagerWrapper() {
-        final Context context = AppGlobals.getInitialApplication();
-        mPackageManager = context.getPackageManager();
-        mBackgroundExecutor = BackgroundExecutor.get();
-    }
+    private ActivityManagerWrapper() { }
 
     public static ActivityManagerWrapper getInstance() {
         return sInstance;
@@ -159,60 +148,12 @@
      * Removes the outdated snapshot of home task.
      */
     public void invalidateHomeTaskSnapshot(final Activity homeActivity) {
-        mBackgroundExecutor.submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    ActivityTaskManager.getService().invalidateHomeTaskSnapshot(
-                            homeActivity.getActivityToken());
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to invalidate home snapshot", e);
-                }
-            }
-        });
-    }
-
-    /**
-     * @return the activity label, badging if necessary.
-     */
-    public String getBadgedActivityLabel(ActivityInfo info, int userId) {
-        return getBadgedLabel(info.loadLabel(mPackageManager).toString(), userId);
-    }
-
-    /**
-     * @return the application label, badging if necessary.
-     */
-    public String getBadgedApplicationLabel(ApplicationInfo appInfo, int userId) {
-        return getBadgedLabel(appInfo.loadLabel(mPackageManager).toString(), userId);
-    }
-
-    /**
-     * @return the content description for a given task, badging it if necessary.  The content
-     * description joins the app and activity labels.
-     */
-    public String getBadgedContentDescription(ActivityInfo info, int userId,
-            ActivityManager.TaskDescription td) {
-        String activityLabel;
-        if (td != null && td.getLabel() != null) {
-            activityLabel = td.getLabel();
-        } else {
-            activityLabel = info.loadLabel(mPackageManager).toString();
+        try {
+            ActivityTaskManager.getService().invalidateHomeTaskSnapshot(
+                    homeActivity.getActivityToken());
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to invalidate home snapshot", e);
         }
-        String applicationLabel = info.applicationInfo.loadLabel(mPackageManager).toString();
-        String badgedApplicationLabel = getBadgedLabel(applicationLabel, userId);
-        return applicationLabel.equals(activityLabel)
-                ? badgedApplicationLabel
-                : badgedApplicationLabel + " " + activityLabel;
-    }
-
-    /**
-     * @return the given label for a user, badging if necessary.
-     */
-    private String getBadgedLabel(String label, int userId) {
-        if (userId != UserHandle.myUserId()) {
-            label = mPackageManager.getUserBadgedLabel(label, new UserHandle(userId)).toString();
-        }
-        return label;
     }
 
     /**
@@ -342,59 +283,33 @@
     /**
      * Requests that the system close any open system windows (including other SystemUI).
      */
-    public Future<?> closeSystemWindows(final String reason) {
-        return mBackgroundExecutor.submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    ActivityManager.getService().closeSystemDialogs(reason);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to close system windows", e);
-                }
-            }
-        });
+    public void closeSystemWindows(final String reason) {
+        try {
+            ActivityManager.getService().closeSystemDialogs(reason);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to close system windows", e);
+        }
     }
 
     /**
      * Removes a task by id.
      */
     public void removeTask(final int taskId) {
-        mBackgroundExecutor.submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    ActivityTaskManager.getService().removeTask(taskId);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to remove task=" + taskId, e);
-                }
-            }
-        });
+        try {
+            ActivityTaskManager.getService().removeTask(taskId);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to remove task=" + taskId, e);
+        }
     }
 
     /**
      * Removes all the recent tasks.
      */
     public void removeAllRecentTasks() {
-        mBackgroundExecutor.submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    ActivityTaskManager.getService().removeAllVisibleRecentTasks();
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to remove all tasks", e);
-                }
-            }
-        });
-    }
-
-    /**
-     * Cancels the current window transtion to/from Recents for the given task id.
-     */
-    public void cancelWindowTransition(int taskId) {
         try {
-            ActivityTaskManager.getService().cancelTaskWindowTransition(taskId);
+            ActivityTaskManager.getService().removeAllVisibleRecentTasks();
         } catch (RemoteException e) {
-            Log.w(TAG, "Failed to cancel window transition for task=" + taskId, e);
+            Log.w(TAG, "Failed to remove all tasks", e);
         }
     }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/BackgroundExecutor.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/BackgroundExecutor.java
deleted file mode 100644
index 0bd89a7..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/BackgroundExecutor.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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
- */
-
-package com.android.systemui.shared.system;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-/**
- * Offloads work from other threads by running it in a background thread.
- */
-public class BackgroundExecutor {
-
-    private static final BackgroundExecutor sInstance = new BackgroundExecutor();
-
-    private final ExecutorService mExecutorService = Executors.newFixedThreadPool(2);
-
-    /**
-     * @return the static instance of the background executor.
-     */
-    public static BackgroundExecutor get() {
-        return sInstance;
-    }
-
-    /**
-     * Runs the given {@param callable} on one of the background executor threads.
-     */
-    public <T> Future<T> submit(Callable<T> callable) {
-        return mExecutorService.submit(callable);
-    }
-
-    /**
-     * Runs the given {@param runnable} on one of the background executor threads.
-     */
-    public Future<?> submit(Runnable runnable) {
-        return mExecutorService.submit(runnable);
-    }
-
-    /**
-     * Runs the given {@param runnable} on one of the background executor threads. Return
-     * {@param result} when the future is resolved.
-     */
-    public <T> Future<T> submit(Runnable runnable, T result) {
-        return mExecutorService.submit(runnable, result);
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index adaee55..065d084 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -37,7 +37,7 @@
 /**
  * Tracks all the task stack listeners
  */
-public class TaskStackChangeListeners extends TaskStackListener {
+public class TaskStackChangeListeners {
 
     private static final String TAG = TaskStackChangeListeners.class.getSimpleName();
     private static final TaskStackChangeListeners INSTANCE = new TaskStackChangeListeners();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java
deleted file mode 100644
index de2a3e4..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.Canvas;
-import android.graphics.Rect;
-import android.graphics.RecordingCanvas;
-import android.view.View;
-import android.view.ViewRootImpl;
-import android.view.WindowCallbacks;
-
-public class WindowCallbacksCompat {
-
-    private final WindowCallbacks mWindowCallbacks = new WindowCallbacks() {
-        @Override
-        public void onWindowSizeIsChanging(Rect newBounds, boolean fullscreen, Rect systemInsets,
-                Rect stableInsets) {
-            WindowCallbacksCompat.this.onWindowSizeIsChanging(newBounds, fullscreen, systemInsets,
-                    stableInsets);
-        }
-
-        @Override
-        public void onWindowDragResizeStart(Rect initialBounds, boolean fullscreen,
-                Rect systemInsets, Rect stableInsets, int resizeMode) {
-            WindowCallbacksCompat.this.onWindowDragResizeStart(initialBounds, fullscreen,
-                    systemInsets, stableInsets, resizeMode);
-        }
-
-        @Override
-        public void onWindowDragResizeEnd() {
-            WindowCallbacksCompat.this.onWindowDragResizeEnd();
-        }
-
-        @Override
-        public boolean onContentDrawn(int offsetX, int offsetY, int sizeX, int sizeY) {
-            return WindowCallbacksCompat.this.onContentDrawn(offsetX, offsetY, sizeX, sizeY);
-        }
-
-        @Override
-        public void onRequestDraw(boolean reportNextDraw) {
-            WindowCallbacksCompat.this.onRequestDraw(reportNextDraw);
-        }
-
-        @Override
-        public void onPostDraw(RecordingCanvas canvas) {
-            WindowCallbacksCompat.this.onPostDraw(canvas);
-        }
-    };
-
-    private final View mView;
-
-    public WindowCallbacksCompat(View view) {
-        mView = view;
-    }
-
-    public void onWindowSizeIsChanging(Rect newBounds, boolean fullscreen, Rect systemInsets,
-            Rect stableInsets) { }
-
-    public void onWindowDragResizeStart(Rect initialBounds, boolean fullscreen, Rect systemInsets,
-            Rect stableInsets, int resizeMode) { }
-
-    public void onWindowDragResizeEnd() { }
-
-    public boolean onContentDrawn(int offsetX, int offsetY, int sizeX, int sizeY) {
-        return false;
-    }
-
-    public void onRequestDraw(boolean reportNextDraw) {
-        if (reportNextDraw) {
-            reportDrawFinish();
-        }
-    }
-
-    public void onPostDraw(Canvas canvas) { }
-
-    public void reportDrawFinish() {
-        mView.getViewRootImpl().reportDrawFinish();
-    }
-
-    public boolean attach() {
-        ViewRootImpl root = mView.getViewRootImpl();
-        if (root != null) {
-            root.addWindowCallbacks(mWindowCallbacks);
-            root.requestInvalidateRootRenderNode();
-            return true;
-        }
-        return false;
-    }
-
-    public void detach() {
-        ViewRootImpl root = mView.getViewRootImpl();
-        if (root != null) {
-            root.removeWindowCallbacks(mWindowCallbacks);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 628193d..5b89f7f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -22,6 +22,7 @@
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
 
 import com.android.internal.colorextraction.ColorExtractor;
 import com.android.keyguard.clock.ClockManager;
@@ -30,6 +31,9 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ClockPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.AnimatableProperty;
+import com.android.systemui.statusbar.notification.PropertyAnimator;
+import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.NotificationIconContainer;
 import com.android.systemui.util.ViewController;
@@ -51,6 +55,7 @@
     private final ClockManager mClockManager;
     private final KeyguardSliceViewController mKeyguardSliceViewController;
     private final NotificationIconAreaController mNotificationIconAreaController;
+    private FrameLayout mNewLockscreenClockFrame;
 
     private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
 
@@ -114,6 +119,7 @@
         mColorExtractor.addOnColorsChangedListener(mColorsListener);
         mView.updateColors(getGradientColors());
         updateAodIcons();
+        mNewLockscreenClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view);
     }
 
     @Override
@@ -180,6 +186,21 @@
     }
 
     /**
+     * Update position of the view, with optional animation. Move the slice view and the clock
+     * slightly towards the center in order to prevent burn-in. Y positioning occurs at the
+     * view parent level.
+     */
+    void updatePosition(int x, AnimationProperties props, boolean animate) {
+        x = Math.abs(x);
+        if (mNewLockscreenClockFrame != null) {
+            PropertyAnimator.setProperty(mNewLockscreenClockFrame, AnimatableProperty.TRANSLATION_X,
+                    -x, props, animate);
+        }
+        mKeyguardSliceViewController.updatePosition(x, props, animate);
+        mNotificationIconAreaController.updatePosition(x, props, animate);
+    }
+
+    /**
      * Update lockscreen mode that may change clock display.
      */
     void updateLockScreenMode(int mode) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
index 8b55b06..02b18b2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
@@ -42,6 +42,9 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardSliceProvider;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.notification.AnimatableProperty;
+import com.android.systemui.statusbar.notification.PropertyAnimator;
+import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.ViewController;
@@ -199,6 +202,13 @@
         Trace.endSection();
     }
 
+    /**
+     * Update position of the view, with optional animation
+     */
+    void updatePosition(int x, AnimationProperties props, boolean animate) {
+        PropertyAnimator.setProperty(mView, AnimatableProperty.TRANSLATION_X, x, props, animate);
+    }
+
     void showSlice(Slice slice) {
         Trace.beginSection("KeyguardSliceViewController#showSlice");
         if (slice == null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index cc0d1b6..cc7b832 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -186,12 +186,23 @@
     /**
      * Update position of the view with an optional animation
      */
-    public void updatePosition(int clockTranslationX, int clockTranslationY,
-            boolean animateClock) {
-        PropertyAnimator.setProperty(mView, AnimatableProperty.X,
-                clockTranslationX, CLOCK_ANIMATION_PROPERTIES, animateClock);
-        PropertyAnimator.setProperty(mView, AnimatableProperty.Y,
-                clockTranslationY, CLOCK_ANIMATION_PROPERTIES, animateClock);
+    public void updatePosition(int x, int y, boolean animate) {
+        PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, CLOCK_ANIMATION_PROPERTIES,
+                animate);
+
+        if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
+            // reset any prior movement
+            PropertyAnimator.setProperty(mView, AnimatableProperty.X, 0,
+                    CLOCK_ANIMATION_PROPERTIES, animate);
+
+            mKeyguardClockSwitchController.updatePosition(x, CLOCK_ANIMATION_PROPERTIES, animate);
+        } else {
+            // reset any prior movement
+            mKeyguardClockSwitchController.updatePosition(0, CLOCK_ANIMATION_PROPERTIES, animate);
+
+            PropertyAnimator.setProperty(mView, AnimatableProperty.X, x,
+                    CLOCK_ANIMATION_PROPERTIES, animate);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 0e6bc24..31b0701 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -289,6 +289,8 @@
     private final DevicePolicyManager mDevicePolicyManager;
     private final BroadcastDispatcher mBroadcastDispatcher;
     private boolean mLogoutEnabled;
+    // cached value to avoid IPCs
+    private boolean mIsUdfpsEnrolled;
     // If the user long pressed the lock icon, disabling face auth for the current session.
     private boolean mLockIconPressed;
     private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -1857,7 +1859,15 @@
 
     private void updateLockScreenMode() {
         mLockScreenMode = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.SHOW_NEW_LOCKSCREEN, mAuthController.isUdfpsEnrolled() ? 1 : 0);
+                Settings.Global.SHOW_NEW_LOCKSCREEN,
+                isUdfpsEnrolled() ? 1 : 0);
+    }
+
+    private void updateUdfpsEnrolled(int userId) {
+        mIsUdfpsEnrolled = mAuthController.isUdfpsEnrolled(userId);
+    }
+    public boolean isUdfpsEnrolled() {
+        return mIsUdfpsEnrolled;
     }
 
     private final UserSwitchObserver mUserSwitchObserver = new UserSwitchObserver() {
@@ -2098,6 +2108,7 @@
         }
         if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
         int userId = getCurrentUser();
+        updateUdfpsEnrolled(userId);
         if (isUnlockWithFingerprintPossible(userId)) {
             if (mFingerprintCancelSignal != null) {
                 mFingerprintCancelSignal.cancel();
@@ -3069,6 +3080,7 @@
                     + " expected=" + (shouldListenForFingerprint() ? 1 : 0));
             pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
             pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
+            pw.println("    udfpsEnrolled=" + isUdfpsEnrolled());
         }
         if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
             final int userId = ActivityManager.getCurrentUser();
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 8147f66..d3ac9ac 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -89,6 +89,7 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
+import com.android.systemui.util.settings.SecureSettings;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -120,6 +121,7 @@
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final Handler mMainHandler;
     private final TunerService mTunerService;
+    private final SecureSettings mSecureSettings;
     private DisplayManager.DisplayListener mDisplayListener;
     private CameraAvailabilityListener mCameraListener;
     private final UserTracker mUserTracker;
@@ -199,11 +201,13 @@
     @Inject
     public ScreenDecorations(Context context,
             @Main Handler handler,
+            SecureSettings secureSettings,
             BroadcastDispatcher broadcastDispatcher,
             TunerService tunerService,
             UserTracker userTracker) {
         super(context);
         mMainHandler = handler;
+        mSecureSettings = secureSettings;
         mBroadcastDispatcher = broadcastDispatcher;
         mTunerService = tunerService;
         mUserTracker = userTracker;
@@ -309,7 +313,7 @@
 
             // Watch color inversion and invert the overlay as needed.
             if (mColorInversionSetting == null) {
-                mColorInversionSetting = new SecureSetting(mContext, mHandler,
+                mColorInversionSetting = new SecureSetting(mSecureSettings, mHandler,
                         Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
                         mUserTracker.getUserId()) {
                     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index b30103e..17bb40e 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -108,12 +108,14 @@
                     .setPip(mWMComponent.getPip())
                     .setSplitScreen(mWMComponent.getSplitScreen())
                     .setOneHanded(mWMComponent.getOneHanded())
+                    .setBubbles(mWMComponent.getBubbles())
                     .setShellDump(mWMComponent.getShellDump());
         } else {
             // TODO: Call on prepareSysUIComponentBuilder but not with real components.
             builder = builder.setPip(Optional.ofNullable(null))
                     .setSplitScreen(Optional.ofNullable(null))
                     .setOneHanded(Optional.ofNullable(null))
+                    .setBubbles(Optional.ofNullable(null))
                     .setShellDump(Optional.ofNullable(null));
         }
         mSysUIComponent = builder
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 98424be..724d197ba 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -146,6 +146,13 @@
     }
 
     @Override
+    public void onPerformScaleAction(int displayId, float scale) {
+        if (mWindowMagnificationConnectionImpl != null) {
+            mWindowMagnificationConnectionImpl.onPerformScaleAction(displayId, scale);
+        }
+    }
+
+    @Override
     public void requestWindowMagnificationConnection(boolean connect) {
         if (connect) {
             setWindowMagnificationConnection();
@@ -247,5 +254,15 @@
                 }
             }
         }
+
+        void onPerformScaleAction(int displayId, float scale) {
+            if (mConnectionCallback != null) {
+                try {
+                    mConnectionCallback.onPerformScaleAction(displayId, scale);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Failed to inform performing scale action", e);
+                }
+            }
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index fd89baa..87dc6a5 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -719,12 +719,14 @@
         private boolean performA11yAction(int action) {
             if (action == R.id.accessibility_action_zoom_in) {
                 final float scale = mScale + A11Y_CHANGE_SCALE_DIFFERENCE;
-                setScale(A11Y_ACTION_SCALE_RANGE.clamp(scale));
+                mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
+                        A11Y_ACTION_SCALE_RANGE.clamp(scale));
                 return true;
             }
             if (action == R.id.accessibility_action_zoom_out) {
                 final float scale = mScale - A11Y_CHANGE_SCALE_DIFFERENCE;
-                setScale(A11Y_ACTION_SCALE_RANGE.clamp(scale));
+                mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
+                        A11Y_ACTION_SCALE_RANGE.clamp(scale));
                 return true;
             }
             if (action == R.id.accessibility_action_move_up) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
index e405a89..fb1d1b6 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
@@ -37,4 +37,13 @@
      * @param sourceBounds The magnified bounds in screen coordinates.
      */
     void onSourceBoundsChanged(int displayId, Rect sourceBounds);
+
+    /**
+     * Called when the accessibility action of scale requests to be performed.
+     * It is invoked from System UI. And the action is provided by the mirror window.
+     *
+     * @param displayId The logical display id.
+     * @param scale the target scale, or {@link Float#NaN} to leave unchanged
+     */
+    void onPerformScaleAction(int displayId, float scale);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index c72bc25..a6b1b90 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -56,6 +56,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -81,6 +82,7 @@
 
     @Nullable private final List<FingerprintSensorPropertiesInternal> mFpProps;
     @Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;
+    @Nullable private final List<FingerprintSensorPropertiesInternal> mUdfpsProps;
 
     // TODO: These should just be saved from onSaveState
     private SomeArgs mCurrentDialogArgs;
@@ -314,6 +316,16 @@
                 : null;
         mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null;
 
+        List<FingerprintSensorPropertiesInternal> udfpsProps = new ArrayList<>();
+        if (mFpProps != null) {
+            for (FingerprintSensorPropertiesInternal props : mFpProps) {
+                if (props.isAnyUdfpsType()) {
+                    udfpsProps.add(props);
+                }
+            }
+        }
+        mUdfpsProps = !udfpsProps.isEmpty() ? udfpsProps : null;
+
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
 
@@ -326,15 +338,9 @@
         mCommandQueue.addCallback(this);
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
 
-        if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
-            final List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties =
-                    mFingerprintManager.getSensorPropertiesInternal();
-            for (FingerprintSensorPropertiesInternal props : fingerprintSensorProperties) {
-                if (props.isAnyUdfpsType()) {
-                    mUdfpsController = mUdfpsControllerFactory.get();
-                    break;
-                }
-            }
+        if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()
+                && mUdfpsProps != null) {
+            mUdfpsController = mUdfpsControllerFactory.get();
         }
 
         try {
@@ -484,12 +490,14 @@
     }
 
    /**
-     * Whether the current user has a UDFP enrolled.
+     * Whether the passed userId has enrolled UDFPS.
      */
-    public boolean isUdfpsEnrolled() {
-        // TODO: (b/171392825) right now only checks whether the UDFPS sensor exists on this device
-        //  but not whether user has enrolled or not
-        return mUdfpsController != null;
+    public boolean isUdfpsEnrolled(int userId) {
+        if (mUdfpsController == null) {
+            return false;
+        }
+
+        return mFingerprintManager.hasEnrolledTemplatesForAnySensor(userId, mUdfpsProps);
     }
 
     private void showDialog(SomeArgs args, boolean skipAnimation, Bundle savedState) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
deleted file mode 100644
index ffb650d6..0000000
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.systemui.bubbles;
-
-import static android.app.Notification.EXTRA_MESSAGES;
-import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
-import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST;
-import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;
-
-import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_EXPERIMENTS;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.Person;
-import android.content.Context;
-import android.content.pm.LauncherApps;
-import android.content.pm.ShortcutInfo;
-import android.graphics.Color;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.graphics.ColorUtils;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.ContrastColorUtil;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.people.PeopleHubNotificationListenerKt;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Common class for experiments controlled via secure settings.
- */
-public class BubbleExperimentConfig {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
-
-    private static final int BUBBLE_HEIGHT = 10000;
-
-    private static final String ALLOW_ANY_NOTIF_TO_BUBBLE = "allow_any_notif_to_bubble";
-    private static final boolean ALLOW_ANY_NOTIF_TO_BUBBLE_DEFAULT = false;
-
-    private static final String ALLOW_MESSAGE_NOTIFS_TO_BUBBLE = "allow_message_notifs_to_bubble";
-    private static final boolean ALLOW_MESSAGE_NOTIFS_TO_BUBBLE_DEFAULT = false;
-
-    private static final String ALLOW_SHORTCUTS_TO_BUBBLE = "allow_shortcuts_to_bubble";
-    private static final boolean ALLOW_SHORTCUT_TO_BUBBLE_DEFAULT = false;
-
-    private static final String WHITELISTED_AUTO_BUBBLE_APPS = "whitelisted_auto_bubble_apps";
-
-    /**
-     * When true, if a notification has the information necessary to bubble (i.e. valid
-     * contentIntent and an icon or image), then a {@link android.app.Notification.BubbleMetadata}
-     * object will be created by the system and added to the notification.
-     * <p>
-     * This does not produce a bubble, only adds the metadata based on the notification info.
-     */
-    static boolean allowAnyNotifToBubble(Context context) {
-        return Settings.Secure.getInt(context.getContentResolver(),
-                ALLOW_ANY_NOTIF_TO_BUBBLE,
-                ALLOW_ANY_NOTIF_TO_BUBBLE_DEFAULT ? 1 : 0) != 0;
-    }
-
-    /**
-     * Same as {@link #allowAnyNotifToBubble(Context)} except it filters for notifications that
-     * are using {@link Notification.MessagingStyle} and have remote input.
-     */
-    static boolean allowMessageNotifsToBubble(Context context) {
-        return Settings.Secure.getInt(context.getContentResolver(),
-                ALLOW_MESSAGE_NOTIFS_TO_BUBBLE,
-                ALLOW_MESSAGE_NOTIFS_TO_BUBBLE_DEFAULT ? 1 : 0) != 0;
-    }
-
-    /**
-     * When true, if the notification is able to bubble via {@link #allowAnyNotifToBubble(Context)}
-     * or {@link #allowMessageNotifsToBubble(Context)} or via normal BubbleMetadata, then a new
-     * BubbleMetadata object is constructed based on the shortcut info.
-     * <p>
-     * This does not produce a bubble, only adds the metadata based on shortcut info.
-     */
-    static boolean useShortcutInfoToBubble(Context context) {
-        return Settings.Secure.getInt(context.getContentResolver(),
-                ALLOW_SHORTCUTS_TO_BUBBLE,
-                ALLOW_SHORTCUT_TO_BUBBLE_DEFAULT ? 1 : 0) != 0;
-    }
-
-    /**
-     * Returns whether the provided package is whitelisted to bubble.
-     */
-    static boolean isPackageWhitelistedToAutoBubble(Context context, String packageName) {
-        String unsplitList = Settings.Secure.getString(context.getContentResolver(),
-                WHITELISTED_AUTO_BUBBLE_APPS);
-        if (unsplitList != null) {
-            // We expect the list to be separated by commas and no white space (but we trim in case)
-            String[] packageList = unsplitList.split(",");
-            for (int i = 0; i < packageList.length; i++) {
-                if (packageList[i].trim().equals(packageName)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * If {@link #allowAnyNotifToBubble(Context)} is true, this method creates and adds
-     * {@link android.app.Notification.BubbleMetadata} to the notification entry as long as
-     * the notification has necessary info for BubbleMetadata.
-     *
-     * @return whether an adjustment was made.
-     */
-    static boolean adjustForExperiments(Context context, NotificationEntry entry,
-            boolean previouslyUserCreated, boolean userBlocked) {
-        Notification.BubbleMetadata metadata = null;
-        boolean addedMetadata = false;
-        boolean whiteListedToAutoBubble =
-                isPackageWhitelistedToAutoBubble(context, entry.getSbn().getPackageName());
-
-        Notification notification = entry.getSbn().getNotification();
-        boolean isMessage = Notification.MessagingStyle.class.equals(
-                notification.getNotificationStyle());
-        boolean bubbleNotifForExperiment = (isMessage && allowMessageNotifsToBubble(context))
-                || allowAnyNotifToBubble(context);
-
-        boolean useShortcutInfo = useShortcutInfoToBubble(context);
-        String shortcutId = entry.getSbn().getNotification().getShortcutId();
-
-        boolean hasMetadata = entry.getBubbleMetadata() != null;
-        if ((!hasMetadata && (previouslyUserCreated || bubbleNotifForExperiment))
-                || useShortcutInfo) {
-            if (DEBUG_EXPERIMENTS) {
-                Log.d(TAG, "Adjusting " + entry.getKey() + " for bubble experiment."
-                        + " allowMessages=" + allowMessageNotifsToBubble(context)
-                        + " isMessage=" + isMessage
-                        + " allowNotifs=" + allowAnyNotifToBubble(context)
-                        + " useShortcutInfo=" + useShortcutInfo
-                        + " previouslyUserCreated=" + previouslyUserCreated);
-            }
-        }
-
-        if (useShortcutInfo && shortcutId != null) {
-            // We don't actually get anything useful from ShortcutInfo so just check existence
-            ShortcutInfo info = getShortcutInfo(context, entry.getSbn().getPackageName(),
-                    entry.getSbn().getUser(), shortcutId);
-            if (info != null) {
-                metadata = createForShortcut(shortcutId);
-            }
-
-            // Replace existing metadata with shortcut, or we're bubbling for experiment
-            boolean shouldBubble = entry.getBubbleMetadata() != null
-                    || bubbleNotifForExperiment
-                    || previouslyUserCreated;
-            if (shouldBubble && metadata != null) {
-                if (DEBUG_EXPERIMENTS) {
-                    Log.d(TAG, "Adding experimental shortcut bubble for: " + entry.getKey());
-                }
-                entry.setBubbleMetadata(metadata);
-                addedMetadata = true;
-            }
-        }
-
-        // Didn't get metadata from a shortcut & we're bubbling for experiment
-        if (entry.getBubbleMetadata() == null
-                && (bubbleNotifForExperiment || previouslyUserCreated)) {
-            metadata = createFromNotif(context, entry);
-            if (metadata != null) {
-                if (DEBUG_EXPERIMENTS) {
-                    Log.d(TAG, "Adding experimental notification bubble for: " + entry.getKey());
-                }
-                entry.setBubbleMetadata(metadata);
-                addedMetadata = true;
-            }
-        }
-
-        boolean bubbleForWhitelist = !userBlocked
-                && whiteListedToAutoBubble
-                && (addedMetadata || hasMetadata);
-        if ((previouslyUserCreated && addedMetadata) || bubbleForWhitelist) {
-            // Update to a previous bubble (or new autobubble), set its flag now.
-            if (DEBUG_EXPERIMENTS) {
-                Log.d(TAG, "Setting FLAG_BUBBLE for: " + entry.getKey());
-            }
-            entry.setFlagBubble(true);
-            return true;
-        }
-        return addedMetadata;
-    }
-
-    static Notification.BubbleMetadata createFromNotif(Context context, NotificationEntry entry) {
-        Notification notification = entry.getSbn().getNotification();
-        final PendingIntent intent = notification.contentIntent;
-        Icon icon = null;
-        // Use the icon of the person if available
-        List<Person> personList = getPeopleFromNotification(entry);
-        if (personList.size() > 0) {
-            final Person person = personList.get(0);
-            if (person != null) {
-                icon = person.getIcon();
-                if (icon == null) {
-                    // Lets try and grab the icon constructed by the layout
-                    Drawable d = PeopleHubNotificationListenerKt.extractAvatarFromRow(entry);
-                    if (d instanceof  BitmapDrawable) {
-                        icon = Icon.createWithBitmap(((BitmapDrawable) d).getBitmap());
-                    }
-                }
-            }
-        }
-        if (icon == null) {
-            boolean shouldTint = notification.getLargeIcon() == null;
-            icon = shouldTint
-                    ? notification.getSmallIcon()
-                    : notification.getLargeIcon();
-            if (shouldTint) {
-                int notifColor = entry.getSbn().getNotification().color;
-                notifColor = ColorUtils.setAlphaComponent(notifColor, 255);
-                notifColor = ContrastColorUtil.findContrastColor(notifColor, Color.WHITE,
-                        true /* findFg */, 3f);
-                icon.setTint(notifColor);
-            }
-        }
-        if (intent != null) {
-            return new Notification.BubbleMetadata.Builder(intent, icon)
-                    .setDesiredHeight(BUBBLE_HEIGHT)
-                    .build();
-        }
-        return null;
-    }
-
-    static Notification.BubbleMetadata createForShortcut(String shortcutId) {
-        return new Notification.BubbleMetadata.Builder(shortcutId)
-                .setDesiredHeight(BUBBLE_HEIGHT)
-                .build();
-    }
-
-    static ShortcutInfo getShortcutInfo(Context context, String packageName, UserHandle user,
-            String shortcutId) {
-        LauncherApps launcherAppService =
-                (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
-        LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery();
-        if (packageName != null) {
-            query.setPackage(packageName);
-        }
-        if (shortcutId != null) {
-            query.setShortcutIds(Arrays.asList(shortcutId));
-        }
-        query.setQueryFlags(FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST);
-        List<ShortcutInfo> shortcuts = launcherAppService.getShortcuts(query, user);
-        return shortcuts != null && shortcuts.size() > 0
-                ? shortcuts.get(0)
-                : null;
-    }
-
-    static List<Person> getPeopleFromNotification(NotificationEntry entry) {
-        Bundle extras = entry.getSbn().getNotification().extras;
-        ArrayList<Person> personList = new ArrayList<>();
-        if (extras == null) {
-            return personList;
-        }
-
-        List<Person> p = extras.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST);
-
-        if (p != null) {
-            personList.addAll(p);
-        }
-
-        if (Notification.MessagingStyle.class.equals(
-                entry.getSbn().getNotification().getNotificationStyle())) {
-            final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES);
-            if (!ArrayUtils.isEmpty(messages)) {
-                for (Notification.MessagingStyle.Message message :
-                        Notification.MessagingStyle.Message
-                                .getMessagesFromBundleArray(messages)) {
-                    personList.add(message.getSenderPerson());
-                }
-            }
-        }
-        return personList;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java
deleted file mode 100644
index 5a7e033..0000000
--- a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.systemui.bubbles.dagger;
-
-import android.app.INotificationManager;
-import android.content.Context;
-import android.content.pm.LauncherApps;
-import android.os.Handler;
-import android.view.WindowManager;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.bubbles.BubbleController;
-import com.android.systemui.bubbles.Bubbles;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.FeatureFlags;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
-import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.wmshell.BubblesManager;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.WindowManagerShellWrapper;
-import com.android.wm.shell.common.FloatingContentCoordinator;
-
-import java.util.Optional;
-
-import dagger.Module;
-import dagger.Provides;
-
-/** */
-@Module
-public interface BubbleModule {
-
-    /**
-     */
-    @SysUISingleton
-    @Provides
-    static Bubbles newBubbleController(Context context,
-            FloatingContentCoordinator floatingContentCoordinator,
-            IStatusBarService statusBarService,
-            WindowManager windowManager,
-            WindowManagerShellWrapper windowManagerShellWrapper,
-            LauncherApps launcherApps,
-            UiEventLogger uiEventLogger,
-            @Main Handler mainHandler,
-            ShellTaskOrganizer organizer) {
-        return BubbleController.create(context, null /* synchronizer */, floatingContentCoordinator,
-                statusBarService, windowManager, windowManagerShellWrapper, launcherApps,
-                uiEventLogger, mainHandler, organizer);
-    }
-
-    /** Provides Optional of BubbleManager */
-    @SysUISingleton
-    @Provides
-    static Optional<BubblesManager> provideBubblesManager(Context context,
-            Optional<Bubbles> bubblesOptional,
-            NotificationShadeWindowController notificationShadeWindowController,
-            StatusBarStateController statusBarStateController, ShadeController shadeController,
-            ConfigurationController configurationController,
-            @Nullable IStatusBarService statusBarService, INotificationManager notificationManager,
-            NotificationInterruptStateProvider interruptionStateProvider,
-            ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager,
-            NotificationGroupManagerLegacy groupManager, NotificationEntryManager entryManager,
-            NotifPipeline notifPipeline, SysUiState sysUiState, FeatureFlags featureFlags,
-            DumpManager dumpManager) {
-        return Optional.ofNullable(BubblesManager.create(context, bubblesOptional,
-                notificationShadeWindowController, statusBarStateController, shadeController,
-                configurationController, statusBarService, notificationManager,
-                interruptionStateProvider, zenModeController, notifUserManager,
-                groupManager, entryManager, notifPipeline, sysUiState, featureFlags, dumpManager));
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
index aa11df4..a3a937a 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
@@ -301,7 +301,7 @@
     }
 
     fun findNearestStep(value: Float): Float {
-        var minDiff = 1000f
+        var minDiff = Float.MAX_VALUE
 
         var f = rangeTemplate.getMinValue()
         while (f <= rangeTemplate.getMaxValue()) {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
index 554d9cb..53383d6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
@@ -22,9 +22,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.UiEventLoggerImpl;
 import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
-import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.animation.FlingAnimationUtils;
-import com.android.wm.shell.common.FloatingContentCoordinator;
 
 import javax.inject.Singleton;
 
@@ -51,22 +49,6 @@
         GlobalConcurrencyModule.class})
 public class GlobalModule {
 
-    // TODO(b/161980186): Currently only used by Bubbles, can move back to WMShellBaseModule once
-    //                    Bubbles has migrated over
-    @Singleton
-    @Provides
-    static FloatingContentCoordinator provideFloatingContentCoordinator() {
-        return new FloatingContentCoordinator();
-    }
-
-    // TODO(b/161980186): Currently only used by Bubbles, can move back to WMShellBaseModule once
-    //                    Bubbles has migrated over
-    @Singleton
-    @Provides
-    static WindowManagerShellWrapper provideWindowManagerShellWrapper() {
-        return new WindowManagerShellWrapper();
-    }
-
     // TODO(b/162923491): This should not be a singleton at all, the display metrics can change and
     //                    callers should be creating a new builder on demand
     @Singleton
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index d73633e..b94a68b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -27,6 +27,7 @@
 import com.android.systemui.util.InjectionInflationController;
 import com.android.wm.shell.ShellDump;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.splitscreen.SplitScreen;
@@ -64,6 +65,9 @@
         Builder setOneHanded(Optional<OneHanded> o);
 
         @BindsInstance
+        Builder setBubbles(Optional<Bubbles> b);
+
+        @BindsInstance
         Builder setInputConsumerController(InputConsumerController i);
 
         @BindsInstance
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 1f6288a..c0013d8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -24,7 +24,6 @@
 import com.android.systemui.accessibility.SystemActions;
 import com.android.systemui.accessibility.WindowMagnification;
 import com.android.systemui.biometrics.AuthController;
-import com.android.systemui.bubbles.dagger.BubbleModule;
 import com.android.systemui.globalactions.GlobalActionsComponent;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.dagger.KeyguardModule;
@@ -51,8 +50,7 @@
 /**
  * SystemUI objects that are injectable should go here.
  */
-@Module(includes = {RecentsModule.class, StatusBarModule.class, BubbleModule.class,
-        KeyguardModule.class})
+@Module(includes = {RecentsModule.class, StatusBarModule.class, KeyguardModule.class})
 public abstract class SystemUIBinder {
     /** Inject into AuthController. */
     @Binds
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index a982ec5..780bb5b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -16,32 +16,49 @@
 
 package com.android.systemui.dagger;
 
+import android.app.INotificationManager;
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.BootCompleteCache;
 import com.android.systemui.BootCompleteCacheImpl;
 import com.android.systemui.appops.dagger.AppOpsModule;
 import com.android.systemui.assist.AssistModule;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.controls.dagger.ControlsModule;
 import com.android.systemui.demomode.dagger.DemoModeModule;
 import com.android.systemui.doze.dagger.DozeComponent;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.log.dagger.LogModule;
 import com.android.systemui.model.SysUiState;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.dagger.PowerModule;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.screenshot.dagger.ScreenshotModule;
 import com.android.systemui.settings.dagger.SettingsModule;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.FeatureFlags;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
+import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.people.PeopleHubModule;
 import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
+import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.policy.dagger.SmartRepliesInflationModule;
 import com.android.systemui.statusbar.policy.dagger.StatusBarPolicyModule;
 import com.android.systemui.tuner.dagger.TunerModule;
@@ -53,6 +70,10 @@
 import com.android.systemui.util.time.SystemClock;
 import com.android.systemui.util.time.SystemClockImpl;
 import com.android.systemui.volume.dagger.VolumeModule;
+import com.android.systemui.wmshell.BubblesManager;
+import com.android.wm.shell.bubbles.Bubbles;
+
+import java.util.Optional;
 
 import dagger.Binds;
 import dagger.BindsOptionalOf;
@@ -126,10 +147,28 @@
     @BindsOptionalOf
     abstract StatusBar optionalStatusBar();
 
-    @BindsOptionalOf
-    abstract Bubbles optionalBubbles();
-
     @SysUISingleton
     @Binds
     abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
+
+    /** Provides Optional of BubbleManager */
+    @SysUISingleton
+    @Provides
+    static Optional<BubblesManager> provideBubblesManager(Context context,
+            Optional<Bubbles> bubblesOptional,
+            NotificationShadeWindowController notificationShadeWindowController,
+            StatusBarStateController statusBarStateController, ShadeController shadeController,
+            ConfigurationController configurationController,
+            @Nullable IStatusBarService statusBarService, INotificationManager notificationManager,
+            NotificationInterruptStateProvider interruptionStateProvider,
+            ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager,
+            NotificationGroupManagerLegacy groupManager, NotificationEntryManager entryManager,
+            NotifPipeline notifPipeline, SysUiState sysUiState, FeatureFlags featureFlags,
+            DumpManager dumpManager) {
+        return Optional.ofNullable(BubblesManager.create(context, bubblesOptional,
+                notificationShadeWindowController, statusBarStateController, shadeController,
+                configurationController, statusBarService, notificationManager,
+                interruptionStateProvider, zenModeController, notifUserManager,
+                groupManager, entryManager, notifPipeline, sysUiState, featureFlags, dumpManager));
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
index 6635286..8f3d8ea 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -21,6 +21,7 @@
 import com.android.wm.shell.ShellDump;
 import com.android.wm.shell.ShellInit;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.splitscreen.SplitScreen;
@@ -64,13 +65,11 @@
     InputConsumerController getInputConsumerController();
 
     // TODO(b/162923491): To be removed once Bubbles migrates over to the Shell
-
     @WMSingleton
     ShellTaskOrganizer getShellTaskOrganizer();
 
     // TODO(b/162923491): We currently pass the instances through to SysUI, but that may change
     //                    depending on the threading mechanism we go with
-
     @WMSingleton
     Optional<OneHanded> getOneHanded();
 
@@ -79,4 +78,7 @@
 
     @WMSingleton
     Optional<SplitScreen> getSplitScreen();
+
+    @WMSingleton
+    Optional<Bubbles> getBubbles();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index f07e5af..ebfce66 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -44,6 +44,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.UiEventLoggerImpl;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.plugins.SensorManagerPlugin;
 import com.android.systemui.statusbar.phone.DozeParameters;
@@ -156,7 +157,7 @@
                         findSensorWithType(config.udfpsLongPressSensorType()),
                         "doze_pulse_on_auth",
                         true /* settingDef */,
-                        authController.isUdfpsEnrolled() /* configured */,
+                        authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser()),
                         DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS,
                         true /* reports touch coordinates */,
                         true /* touchscreen */,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 4d41950..c52b8ca 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -19,7 +19,7 @@
 import android.view.View.OnAttachStateChangeListener;
 import android.view.View.OnLayoutChangeListener;
 
-import com.android.systemui.Dependency;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTileView;
@@ -34,6 +34,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
@@ -57,7 +58,6 @@
      */
     private final ArrayList<View> mQuickQsViews = new ArrayList<>();
     private final QuickQSPanel mQuickQsPanel;
-    private final QSPanel mQsPanel;
     private final QSPanelController mQsPanelController;
     private final QuickQSPanelController mQuickQSPanelController;
     private final QSSecurityFooter mSecurityFooter;
@@ -83,34 +83,36 @@
     private boolean mFullRows;
     private int mNumQuickTiles;
     private float mLastPosition;
-    private QSTileHost mHost;
+    private final QSTileHost mHost;
+    private final Executor mExecutor;
+    private final TunerService mTunerService;
     private boolean mShowCollapsedOnKeyguard;
 
     @Inject
-    public QSAnimator(QS qs, QuickQSPanel quickPanel, QSPanel panel,
-            QSPanelController qsPanelController, QuickQSPanelController quickQSPanelController,
-            QSTileHost qsTileHost,
-            QSSecurityFooter securityFooter) {
+    public QSAnimator(QS qs, QuickQSPanel quickPanel, QSPanelController qsPanelController,
+            QuickQSPanelController quickQSPanelController, QSTileHost qsTileHost,
+            QSSecurityFooter securityFooter, @Main Executor executor, TunerService tunerService) {
         mQs = qs;
         mQuickQsPanel = quickPanel;
-        mQsPanel = panel;
         mQsPanelController = qsPanelController;
         mQuickQSPanelController = quickQSPanelController;
         mSecurityFooter = securityFooter;
         mHost = qsTileHost;
+        mExecutor = executor;
+        mTunerService = tunerService;
         mHost.addCallback(this);
-        mQsPanel.addOnAttachStateChangeListener(this);
+        mQsPanelController.addOnAttachStateChangeListener(this);
         qs.getView().addOnLayoutChangeListener(this);
-        if (mQsPanel.isAttachedToWindow()) {
+        if (mQsPanelController.isAttachedToWindow()) {
             onViewAttachedToWindow(null);
         }
-        QSTileLayout tileLayout = mQsPanel.getTileLayout();
+        QSTileLayout tileLayout = mQsPanelController.getTileLayout();
         if (tileLayout instanceof PagedTileLayout) {
             mPagedLayout = ((PagedTileLayout) tileLayout);
         } else {
             Log.w(TAG, "QS Not using page layout");
         }
-        panel.setPageListener(this);
+        mQsPanelController.setPageListener(this);
     }
 
     public void onRtlChanged() {
@@ -153,14 +155,14 @@
 
     @Override
     public void onViewAttachedToWindow(View v) {
-        Dependency.get(TunerService.class).addTunable(this, ALLOW_FANCY_ANIMATION,
+        mTunerService.addTunable(this, ALLOW_FANCY_ANIMATION,
                 MOVE_FULL_ROWS, QuickQSPanel.NUM_QUICK_TILES);
     }
 
     @Override
     public void onViewDetachedFromWindow(View v) {
         mHost.removeCallback(this);
-        Dependency.get(TunerService.class).removeTunable(this);
+        mTunerService.removeTunable(this);
     }
 
     @Override
@@ -205,7 +207,7 @@
         mAllViews.clear();
         mQuickQsViews.clear();
 
-        QSTileLayout tileLayout = mQsPanel.getTileLayout();
+        QSTileLayout tileLayout = mQsPanelController.getTileLayout();
         mAllViews.add((View) tileLayout);
         int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0;
         int width = mQs.getView() != null ? mQs.getView().getMeasuredWidth() : 0;
@@ -223,7 +225,8 @@
             View view = mQs.getView();
 
             // This case: less tiles to animate in small displays.
-            if (count < mQuickQsPanel.getTileLayout().getNumVisibleTiles() && mAllowFancy) {
+            if (count < mQuickQSPanelController.getTileLayout().getNumVisibleTiles()
+                    && mAllowFancy) {
                 // Quick tiles.
                 QSTileView quickTileView = mQuickQSPanelController.getTileView(tile);
                 if (quickTileView == null) continue;
@@ -254,7 +257,8 @@
                     translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff);
 
                     // xDiff is negative here and this makes it "more" negative
-                    final int translationX = mQsPanel.isLayoutRtl() ? xDiff - width : xDiff + width;
+                    final int translationX =
+                            mQsPanelController.isLayoutRtl() ? xDiff - width : xDiff + width;
                     translationXBuilder.addFloat(quickTileView, "translationX", 0,
                             translationX);
                 }
@@ -288,7 +292,7 @@
 
         if (mAllowFancy) {
             // Make brightness appear static position and alpha in through second half.
-            View brightness = mQsPanel.getBrightnessView();
+            View brightness = mQsPanelController.getBrightnessView();
             if (brightness != null) {
                 firstPageBuilder.addFloat(brightness, "translationY", heightDiff, 0);
                 mBrightnessAnimator = new TouchAnimator.Builder()
@@ -311,13 +315,13 @@
             // Fade in the security footer and the divider as we reach the final position
             builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY);
             builder.addFloat(mSecurityFooter.getView(), "alpha", 0, 1);
-            if (mQsPanel.getDivider() != null) {
-                builder.addFloat(mQsPanel.getDivider(), "alpha", 0, 1);
+            if (mQsPanelController.getDivider() != null) {
+                builder.addFloat(mQsPanelController.getDivider(), "alpha", 0, 1);
             }
             mAllPagesDelayedAnimator = builder.build();
             mAllViews.add(mSecurityFooter.getView());
-            if (mQsPanel.getDivider() != null) {
-                mAllViews.add(mQsPanel.getDivider());
+            if (mQsPanelController.getDivider() != null) {
+                mAllViews.add(mQsPanelController.getDivider());
             }
 
             float px = 0;
@@ -447,14 +451,14 @@
     @Override
     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
             int oldTop, int oldRight, int oldBottom) {
-        mQsPanel.post(mUpdateAnimators);
+        mExecutor.execute(mUpdateAnimators);
     }
 
     @Override
     public void onTilesChanged() {
         // Give the QS panels a moment to generate their new tiles, then create all new animators
         // hooked up to the new views.
-        mQsPanel.post(mUpdateAnimators);
+        mExecutor.execute(mUpdateAnimators);
     }
 
     private final TouchAnimator.Listener mNonFirstPageListener =
@@ -470,11 +474,8 @@
                 }
             };
 
-    private Runnable mUpdateAnimators = new Runnable() {
-        @Override
-        public void run() {
-            updateAnimators();
-            setCurrentPosition();
-        }
+    private final Runnable mUpdateAnimators = () -> {
+        updateAnimators();
+        setCurrentPosition();
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index a351510..80bfa79 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -35,7 +35,7 @@
 import com.android.wm.shell.animation.PhysicsAnimator;
 
 /**
- * Wrapper view with background which contains {@link QSPanel} and {@link BaseStatusBarHeader}
+ * Wrapper view with background which contains {@link QSPanel} and {@link QuickStatusBarHeader}
  */
 public class QSContainerImpl extends FrameLayout {
 
@@ -57,7 +57,6 @@
             SpringForce.DAMPING_RATIO_LOW_BOUNCY);
     private int mBackgroundBottom = -1;
     private int mHeightOverride = -1;
-    private QSPanel mQSPanel;
     private View mQSDetail;
     private QuickStatusBarHeader mHeader;
     private float mQsExpansion;
@@ -81,7 +80,6 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mQSPanel = findViewById(R.id.quick_settings_panel);
         mQSPanelContainer = findViewById(R.id.expanded_qs_scroll_view);
         mQSDetail = findViewById(R.id.qs_detail);
         mHeader = findViewById(R.id.header);
@@ -90,22 +88,18 @@
         mBackground = findViewById(R.id.quick_settings_background);
         mStatusBarBackground = findViewById(R.id.quick_settings_status_bar_background);
         mBackgroundGradient = findViewById(R.id.quick_settings_gradient_view);
-        updateResources();
         mHeader.getHeaderQsPanel().setMediaVisibilityChangedListener((visible) -> {
             if (mHeader.getHeaderQsPanel().isShown()) {
                 mAnimateBottomOnNextLayout = true;
             }
         });
-        mQSPanel.setMediaVisibilityChangedListener((visible) -> {
-            if (mQSPanel.isShown()) {
-                mAnimateBottomOnNextLayout = true;
-            }
-        });
-
-
         setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
     }
 
+    void onMediaVisibilityChanged(boolean qsVisible) {
+        mAnimateBottomOnNextLayout = qsVisible;
+    }
+
     private void setBackgroundBottom(int value) {
         // We're saving the bottom separately since otherwise the bottom would be overridden in
         // the layout and the animation wouldn't properly start at the old position.
@@ -124,7 +118,6 @@
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         setBackgroundGradientVisibility(newConfig);
-        updateResources();
         mSizePoint.set(0, 0); // Will be retrieved on next measure pass.
     }
 
@@ -197,7 +190,7 @@
         mBackground.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
     }
 
-    private void updateResources() {
+    void updateResources(QSPanelController qsPanelController) {
         LayoutParams layoutParams = (LayoutParams) mQSPanelContainer.getLayoutParams();
         layoutParams.topMargin = mContext.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.quick_qs_offset_height);
@@ -209,7 +202,7 @@
         boolean marginsChanged = padding != mContentPadding;
         mContentPadding = padding;
         if (marginsChanged) {
-            updatePaddingsAndMargins();
+            updatePaddingsAndMargins(qsPanelController);
         }
     }
 
@@ -275,7 +268,7 @@
         updateExpansion();
     }
 
-    private void updatePaddingsAndMargins() {
+    private void updatePaddingsAndMargins(QSPanelController qsPanelController) {
         for (int i = 0; i < getChildCount(); i++) {
             View view = getChildAt(i);
             if (view == mStatusBarBackground || view == mBackgroundGradient
@@ -288,8 +281,8 @@
             lp.leftMargin = mSideMargins;
             if (view == mQSPanelContainer) {
                 // QS panel lays out some of its content full width
-                mQSPanel.setContentMargins(mContentPadding, mContentPadding);
-                Pair<Integer, Integer> margins = mQSPanel.getVisualSideMargins();
+                qsPanelController.setContentMargins(mContentPadding, mContentPadding);
+                Pair<Integer, Integer> margins = qsPanelController.getVisualSideMargins();
                 // Apply paddings based on QSPanel
                 mQSCustomizer.setContentPaddings(margins.first, margins.second);
             } else if (view == mHeader) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
index 4b9f431..27d3221 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
@@ -16,7 +16,10 @@
 
 package com.android.systemui.qs;
 
+import android.content.res.Configuration;
+
 import com.android.systemui.qs.dagger.QSScope;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.ViewController;
 
 import javax.inject.Inject;
@@ -24,13 +27,26 @@
 /** */
 @QSScope
 public class QSContainerImplController extends ViewController<QSContainerImpl> {
+    private final QSPanelController mQsPanelController;
     private final QuickStatusBarHeaderController mQuickStatusBarHeaderController;
+    private final ConfigurationController mConfigurationController;
+
+    private final ConfigurationController.ConfigurationListener mConfigurationListener =
+            new ConfigurationController.ConfigurationListener() {
+        @Override
+        public void onConfigChanged(Configuration newConfig) {
+            mView.updateResources(mQsPanelController);
+        }
+    };
 
     @Inject
-    QSContainerImplController(QSContainerImpl view,
-            QuickStatusBarHeaderController quickStatusBarHeaderController) {
+    QSContainerImplController(QSContainerImpl view, QSPanelController qsPanelController,
+            QuickStatusBarHeaderController quickStatusBarHeaderController,
+            ConfigurationController configurationController) {
         super(view);
+        mQsPanelController = qsPanelController;
         mQuickStatusBarHeaderController = quickStatusBarHeaderController;
+        mConfigurationController = configurationController;
     }
 
     @Override
@@ -44,10 +60,19 @@
 
     @Override
     protected void onViewAttached() {
+        mView.updateResources(mQsPanelController);
+        mQsPanelController.setMediaVisibilityChangedListener((visible) -> {
+            if (mQsPanelController.isShown()) {
+                mView.onMediaVisibilityChanged(true);
+            }
+        });
+
+        mConfigurationController.addCallback(mConfigurationListener);
     }
 
     @Override
     protected void onViewDetached() {
+        mConfigurationController.removeCallback(mConfigurationListener);
     }
 
     public QSContainerImpl getView() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index cfcceb2..619729e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -57,7 +57,7 @@
     protected TextView mDetailDoneButton;
     private QSDetailClipper mClipper;
     private DetailAdapter mDetailAdapter;
-    private QSPanel mQsPanel;
+    private QSPanelController mQsPanelController;
 
     protected View mQsDetailHeader;
     protected TextView mQsDetailHeaderTitle;
@@ -114,19 +114,20 @@
             public void onClick(View v) {
                 announceForAccessibility(
                         mContext.getString(R.string.accessibility_desc_quick_settings));
-                mQsPanel.closeDetail();
+                mQsPanelController.closeDetail();
             }
         };
         mDetailDoneButton.setOnClickListener(doneListener);
     }
 
     /** */
-    public void setQsPanel(QSPanel panel, QuickStatusBarHeader header, QSFooter footer) {
-        mQsPanel = panel;
+    public void setQsPanel(QSPanelController panelController, QuickStatusBarHeader header,
+            QSFooter footer) {
+        mQsPanelController = panelController;
         mHeader = header;
         mFooter = footer;
         mHeader.setCallback(mQsPanelCallback);
-        mQsPanel.setCallback(mQsPanelCallback);
+        mQsPanelController.setCallback(mQsPanelCallback);
     }
 
     public void setHost(QSTileHost host) {
@@ -221,7 +222,7 @@
             listener = mTeardownDetailWhenDone;
             mHeader.setVisibility(View.VISIBLE);
             mFooter.setVisibility(View.VISIBLE);
-            mQsPanel.setGridContentVisibility(true);
+            mQsPanelController.setGridContentVisibility(true);
             mQsPanelCallback.onScanStateChanged(false);
         }
         sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
@@ -362,7 +363,7 @@
         public void onAnimationEnd(Animator animation) {
             // Only hide content if still in detail state.
             if (mDetailAdapter != null) {
-                mQsPanel.setGridContentVisibility(false);
+                mQsPanelController.setGridContentVisibility(false);
                 mHeader.setVisibility(View.INVISIBLE);
                 mFooter.setVisibility(View.INVISIBLE);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailDisplayer.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailDisplayer.java
new file mode 100644
index 0000000..7d87e174
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailDisplayer.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.qs;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.plugins.qs.DetailAdapter;
+
+import javax.inject.Inject;
+
+/**
+ * Proxy class for talking with the QSPanel and showing custom content within it.
+ */
+@SysUISingleton
+public class QSDetailDisplayer {
+    private QSPanelController mQsPanelController;
+
+    @Inject
+    public QSDetailDisplayer() {
+    }
+
+    public void setQsPanelController(QSPanelController qsPanelController) {
+        mQsPanelController = qsPanelController;
+    }
+
+    /** Show the supplied DetailAdapter in the Quick Settings. */
+    public void showDetailAdapter(DetailAdapter detailAdapter, int x, int y) {
+        if (mQsPanelController != null) {
+            mQsPanelController.showDetailDapater(detailAdapter, x, y);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 0a2533a..e38bd4b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -17,23 +17,11 @@
 
 import android.view.View;
 
-import androidx.annotation.Nullable;
-
 /**
  * The bottom footer of the quick settings panel.
  */
 public interface QSFooter {
     /**
-     * Sets the given {@link QSPanel} to be the one that will display the quick settings.
-     */
-    void setQSPanel(@Nullable QSPanel panel);
-
-    /**
-     * Sets the given {@link QuickQSPanel} to be the one associated with quick settings.
-     */
-    default void setQQSPanel(@Nullable QuickQSPanel panel) {};
-
-    /**
      * Sets whether or not the footer should be visible.
      *
      * @param visibility One of {@link View#VISIBLE}, {@link View#INVISIBLE} or {@link View#GONE}.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
index 8b9dae1..7e20be6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
@@ -59,7 +59,6 @@
     private boolean mShouldShowBuildText;
 
     private boolean mQsDisabled;
-    private QuickQSPanel mQuickQsPanel;
 
     private boolean mExpanded;
 
@@ -115,8 +114,6 @@
 
         updateResources();
 
-        addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight,
-                oldBottom) -> updateAnimator(right - left));
         setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
         setBuildText();
     }
@@ -139,9 +136,7 @@
         }
     }
 
-    private void updateAnimator(int width) {
-        int numTiles = mQuickQsPanel != null ? mQuickQsPanel.getNumQuickTiles()
-                : QuickQSPanel.getDefaultMaxTiles();
+    void updateAnimator(int width, int numTiles) {
         int size = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size)
                 - mContext.getResources().getDimensionPixelSize(dimen.qs_quick_tile_padding);
         int remaining = (width - numTiles * size) / (numTiles - 1);
@@ -289,19 +284,6 @@
         return mExpanded && mMultiUserSwitch.isMultiUserEnabled();
     }
 
-    /** */
-    public void setQSPanel(final QSPanel qsPanel) {
-        if (qsPanel != null) {
-            mMultiUserSwitch.setQsPanel(qsPanel);
-            qsPanel.setFooterPageIndicator(mPageIndicator);
-        }
-    }
-
-    public void setQQSPanel(@Nullable QuickQSPanel panel) {
-        mQuickQsPanel = panel;
-    }
-
-
     void onUserInfoChanged(Drawable picture, boolean isGuestUser) {
         if (picture != null && isGuestUser && !(picture instanceof UserIconDrawable)) {
             picture = picture.getConstantState().newDrawable(getResources()).mutate();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index e3af04b..8110fda 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -26,8 +26,6 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import androidx.annotation.Nullable;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -35,6 +33,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.phone.MultiUserSwitch;
 import com.android.systemui.statusbar.phone.SettingsButton;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.UserInfoController;
@@ -55,11 +54,15 @@
     private final DeviceProvisionedController mDeviceProvisionedController;
     private final UserTracker mUserTracker;
     private final QSPanelController mQsPanelController;
+    private final QSDetailDisplayer mQsDetailDisplayer;
+    private final QuickQSPanelController mQuickQSPanelController;
     private final TunerService mTunerService;
     private final MetricsLogger mMetricsLogger;
     private final SettingsButton mSettingsButton;
     private final TextView mBuildText;
     private final View mEdit;
+    private final MultiUserSwitch mMultiUserSwitch;
+    private final PageIndicator mPageIndicator;
 
     private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener =
             new UserInfoController.OnUserInfoChangedListener() {
@@ -119,8 +122,9 @@
     QSFooterViewController(QSFooterView view, UserManager userManager,
             UserInfoController userInfoController, ActivityStarter activityStarter,
             DeviceProvisionedController deviceProvisionedController, UserTracker userTracker,
-            QSPanelController qsPanelController, TunerService tunerService,
-            MetricsLogger metricsLogger) {
+            QSPanelController qsPanelController, QSDetailDisplayer qsDetailDisplayer,
+            QuickQSPanelController quickQSPanelController,
+            TunerService tunerService, MetricsLogger metricsLogger) {
         super(view);
         mUserManager = userManager;
         mUserInfoController = userInfoController;
@@ -128,17 +132,24 @@
         mDeviceProvisionedController = deviceProvisionedController;
         mUserTracker = userTracker;
         mQsPanelController = qsPanelController;
+        mQsDetailDisplayer = qsDetailDisplayer;
+        mQuickQSPanelController = quickQSPanelController;
         mTunerService = tunerService;
         mMetricsLogger = metricsLogger;
 
         mSettingsButton = mView.findViewById(R.id.settings_button);
         mBuildText = mView.findViewById(R.id.build);
         mEdit = mView.findViewById(android.R.id.edit);
+        mMultiUserSwitch = mView.findViewById(R.id.multi_user_switch);
+        mPageIndicator = mView.findViewById(R.id.footer_page_indicator);
     }
 
-
     @Override
     protected void onViewAttached() {
+        mView.addOnLayoutChangeListener(
+                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                        mView.updateAnimator(
+                                right - left, mQuickQSPanelController.getNumQuickTiles()));
         mSettingsButton.setOnClickListener(mSettingsOnClickListener);
         mBuildText.setOnLongClickListener(view -> {
             CharSequence buildText = mBuildText.getText();
@@ -158,6 +169,8 @@
                 mActivityStarter.postQSRunnableDismissingKeyguard(() ->
                         mQsPanelController.showEdit(view)));
 
+        mMultiUserSwitch.setQSDetailDisplayer(mQsDetailDisplayer);
+        mQsPanelController.setFooterPageIndicator(mPageIndicator);
         mView.updateEverything(isTunerEnabled());
     }
 
@@ -166,12 +179,6 @@
         setListening(false);
     }
 
-
-    @Override
-    public void setQSPanel(@Nullable QSPanel panel) {
-        mView.setQSPanel(panel);
-    }
-
     @Override
     public void setVisibility(int visibility) {
         mView.setVisibility(visibility);
@@ -220,11 +227,6 @@
     }
 
     @Override
-    public void setQQSPanel(@Nullable QuickQSPanel panel) {
-        mView.setQQSPanel(panel);
-    }
-
-    @Override
     public void disable(int state1, int state2, boolean animate) {
         mView.disable(state2, isTunerEnabled());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 1a7d366..0fe018e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -38,7 +38,7 @@
 import com.android.systemui.media.MediaHost;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.customize.QSCustomizer;
+import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSFragmentComponent;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarState;
@@ -69,7 +69,6 @@
     private QSAnimator mQSAnimator;
     private HeightListener mPanelView;
     protected QuickStatusBarHeader mHeader;
-    private QSCustomizer mQSCustomizer;
     protected NonInterceptingScrollView mQSPanelScrollView;
     private QSDetail mQSDetail;
     private boolean mListening;
@@ -81,6 +80,8 @@
 
     private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
     private final InjectionInflationController mInjectionInflater;
+    private final CommandQueue mCommandQueue;
+    private final QSDetailDisplayer mQsDetailDisplayer;
     private final QSFragmentComponent.Factory mQsComponentFactory;
     private final QSTileHost mHost;
     private boolean mShowCollapsedOnKeyguard;
@@ -97,14 +98,18 @@
     private float mLastHeaderTranslation;
     private QSPanelController mQSPanelController;
     private QuickQSPanelController mQuickQSPanelController;
+    private QSCustomizerController mQSCustomizerController;
 
     @Inject
     public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
             InjectionInflationController injectionInflater, QSTileHost qsTileHost,
             StatusBarStateController statusBarStateController, CommandQueue commandQueue,
+            QSDetailDisplayer qsDetailDisplayer,
             QSFragmentComponent.Factory qsComponentFactory) {
         mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
         mInjectionInflater = injectionInflater;
+        mCommandQueue = commandQueue;
+        mQsDetailDisplayer = qsDetailDisplayer;
         mQsComponentFactory = qsComponentFactory;
         commandQueue.observe(getLifecycle(), this);
         mHost = qsTileHost;
@@ -144,20 +149,23 @@
         mQSPanelController.setHeaderContainer(view.findViewById(R.id.header_text_container));
         mFooter = qsFragmentComponent.getQSFooter();
 
+        mQsDetailDisplayer.setQsPanelController(mQSPanelController);
+
         mQSContainerImplController = qsFragmentComponent.getQSContainerImplController();
         mQSContainerImplController.init();
         mContainer = mQSContainerImplController.getView();
 
-        mQSDetail.setQsPanel(mQSPanelController.getView(), mHeader, mFooter);
+        mQSDetail.setQsPanel(mQSPanelController, mHeader, mFooter);
         mQSAnimator = qsFragmentComponent.getQSAnimator();
 
-        mQSCustomizer = view.findViewById(R.id.qs_customize);
-        mQSCustomizer.setQs(this);
+        mQSCustomizerController = qsFragmentComponent.getQSCustomizerController();
+        mQSCustomizerController.init();
+        mQSCustomizerController.setQs(this);
         if (savedInstanceState != null) {
             setExpanded(savedInstanceState.getBoolean(EXTRA_EXPANDED));
             setListening(savedInstanceState.getBoolean(EXTRA_LISTENING));
             setEditLocation(view);
-            mQSCustomizer.restoreInstanceState(savedInstanceState);
+            mQSCustomizerController.restoreInstanceState(savedInstanceState);
             if (mQsExpanded) {
                 mQSPanelController.getTileLayout().restoreInstanceState(savedInstanceState);
             }
@@ -181,7 +189,8 @@
         if (mListening) {
             setListening(false);
         }
-        mQSCustomizer.setQs(null);
+        mQSCustomizerController.setQs(null);
+        mQsDetailDisplayer.setQsPanelController(null);
     }
 
     @Override
@@ -189,7 +198,7 @@
         super.onSaveInstanceState(outState);
         outState.putBoolean(EXTRA_EXPANDED, mQsExpanded);
         outState.putBoolean(EXTRA_LISTENING, mListening);
-        mQSCustomizer.saveInstanceState(outState);
+        mQSCustomizerController.saveInstanceState(outState);
         if (mQsExpanded) {
             mQSPanelController.getTileLayout().saveInstanceState(outState);
         }
@@ -236,25 +245,23 @@
         int[] loc = edit.getLocationOnScreen();
         int x = loc[0] + edit.getWidth() / 2;
         int y = loc[1] + edit.getHeight() / 2;
-        mQSCustomizer.setEditLocation(x, y);
+        mQSCustomizerController.setEditLocation(x, y);
     }
 
     @Override
     public void setContainer(ViewGroup container) {
         if (container instanceof NotificationsQuickSettingsContainer) {
-            mQSCustomizer.setContainer((NotificationsQuickSettingsContainer) container);
+            mQSCustomizerController.setContainer((NotificationsQuickSettingsContainer) container);
         }
     }
 
     @Override
     public boolean isCustomizing() {
-        return mQSCustomizer.isCustomizing();
+        return mQSCustomizerController.isCustomizing();
     }
 
     public void setHost(QSTileHost qsh) {
-        mQSPanelController.setCustomizer(mQSCustomizer);
         mHeader.setQSPanel(mQSPanelController.getView());
-        mFooter.setQSPanel(mQSPanelController.getView());
         mQSDetail.setHost(qsh);
     }
 
@@ -321,17 +328,9 @@
         return mQSPanelController;
     }
 
-    public QSPanel getQsPanel() {
-        return mQSPanelController.getView();
-    }
-
-    public QSCustomizer getCustomizer() {
-        return mQSCustomizer;
-    }
-
     @Override
     public boolean isShowingDetail() {
-        return mQSPanelController.isShowingCustomize() || mQSDetail.isShowingDetail();
+        return mQSCustomizerController.isCustomizing() || mQSDetail.isShowingDetail();
     }
 
     @Override
@@ -417,7 +416,7 @@
             }
         }
         mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
-        mQSPanelController.getQsTileRevealController().setExpansion(expansion);
+        mQSPanelController.setRevealExpansion(expansion);
         mQSPanelController.getTileLayout().setExpansion(expansion);
         mQSPanelScrollView.setTranslationY(translationScaleY * heightDiff);
         if (fullyCollapsed) {
@@ -553,9 +552,10 @@
     public void notifyCustomizeChanged() {
         // The customize state changed, so our height changed.
         mContainer.updateExpansion();
-        mQSPanelScrollView.setVisibility(!mQSCustomizer.isCustomizing() ? View.VISIBLE
+        mQSPanelScrollView.setVisibility(!mQSCustomizerController.isCustomizing() ? View.VISIBLE
                 : View.INVISIBLE);
-        mFooter.setVisibility(!mQSCustomizer.isCustomizing() ? View.VISIBLE : View.INVISIBLE);
+        mFooter.setVisibility(
+                !mQSCustomizerController.isCustomizing() ? View.VISIBLE : View.INVISIBLE);
         // Let the panel know the position changed and it needs to update where notifications
         // and whatnot are.
         mPanelView.onQsHeightChanged();
@@ -567,7 +567,7 @@
      */
     @Override
     public int getDesiredHeight() {
-        if (mQSCustomizer.isCustomizing()) {
+        if (mQSCustomizerController.isCustomizing()) {
             return getView().getHeight();
         }
         if (mQSDetail.isClosingDetail()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 76f2446..758e0c5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -46,7 +46,6 @@
 import com.android.systemui.media.MediaHost;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.settings.ToggleSliderView;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
@@ -56,7 +55,6 @@
 import com.android.systemui.util.animation.DisappearParameters;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.function.Consumer;
 
@@ -84,7 +82,6 @@
 
     private final H mHandler = new H();
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
-    private QSTileRevealController mQsTileRevealController;
     /** Whether or not the QS media player feature is enabled. */
     protected boolean mUsingMediaPlayer;
     private int mVisualMarginStart;
@@ -117,7 +114,6 @@
     private int mVisualTilePadding;
     private boolean mUsingHorizontalLayout;
 
-    private QSCustomizer mCustomizePanel;
     private Record mDetailRecord;
 
     private BrightnessMirrorController mBrightnessMirrorController;
@@ -186,10 +182,6 @@
 
             initMediaHostState();
         }
-        if (mRegularTileLayout instanceof PagedTileLayout) {
-            mQsTileRevealController = new QSTileRevealController(mContext, this,
-                    (PagedTileLayout) mRegularTileLayout);
-        }
         mQSLogger.logAllTilesChangeListening(mListening, getDumpableTag(), "");
     }
 
@@ -297,14 +289,6 @@
         setMeasuredDimension(getMeasuredWidth(), height);
     }
 
-    public QSTileRevealController getQsTileRevealController() {
-        return mQsTileRevealController;
-    }
-
-    public boolean isShowingCustomize() {
-        return mCustomizePanel != null && mCustomizePanel.isCustomizing();
-    }
-
     @Override
     protected void onDetachedFromWindow() {
         if (mTileLayout != null) {
@@ -362,10 +346,6 @@
         mCallback = callback;
     }
 
-    void setCustomizer(QSCustomizer customizer) {
-        mCustomizePanel = customizer;
-    }
-
     /**
      * Links the footer's page indicator, which is used in landscape orientation to save space.
      *
@@ -608,12 +588,6 @@
         }
     }
 
-    public void onCollapse() {
-        if (mCustomizePanel != null && mCustomizePanel.isShown()) {
-            mCustomizePanel.hide();
-        }
-    }
-
     public void setExpanded(boolean expanded) {
         if (mExpanded == expanded) return;
         mQSLogger.logPanelExpanded(expanded, getDumpableTag());
@@ -684,10 +658,6 @@
         return mExpanded;
     }
 
-    void updateRevealedTiles(Collection<QSTile> tiles) {
-        mQsTileRevealController.updateRevealedTiles(tiles);
-    }
-
     void addTile(QSPanelControllerBase.TileRecord tileRecord) {
         final QSTile.Callback callback = new QSTile.Callback() {
             @Override
@@ -742,29 +712,7 @@
         mTileLayout.removeTile(tileRecord);
     }
 
-    public void showEdit(final View v) {
-        v.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mCustomizePanel != null) {
-                    if (!mCustomizePanel.isCustomizing()) {
-                        int[] loc = v.getLocationOnScreen();
-                        int x = loc[0] + v.getWidth() / 2;
-                        int y = loc[1] + v.getHeight() / 2;
-                        mCustomizePanel.show(x, y);
-                    }
-                }
-
-            }
-        });
-    }
-
-    public void closeDetail() {
-        if (mCustomizePanel != null && mCustomizePanel.isShown()) {
-            // Treat this as a detail panel for now, to make things easy.
-            mCustomizePanel.hide();
-            return;
-        }
+    void closeDetail() {
         showDetail(false, mDetailRecord);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index f222b0d..eef7e39 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.content.res.Configuration;
+import android.util.Pair;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -28,13 +29,16 @@
 import com.android.systemui.R;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.qs.customize.QSCustomizer;
+import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.settings.BrightnessController;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
 import com.android.systemui.tuner.TunerService;
 
+import java.util.function.Consumer;
+
 import javax.inject.Inject;
 
 /**
@@ -44,6 +48,7 @@
 public class QSPanelController extends QSPanelControllerBase<QSPanel> {
     private final QSSecurityFooter mQsSecurityFooter;
     private final TunerService mTunerService;
+    private final QSCustomizerController mQsCustomizerController;
     private final BrightnessController mBrightnessController;
 
     private final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener =
@@ -61,18 +66,26 @@
 
     @Inject
     QSPanelController(QSPanel view, QSSecurityFooter qsSecurityFooter, TunerService tunerService,
-            QSTileHost qstileHost, DumpManager dumpManager,
-            MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
+            QSTileHost qstileHost, QSCustomizerController qsCustomizerController,
+            QSTileRevealController.Factory qsTileRevealControllerFactory,
+            DumpManager dumpManager, MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
             BrightnessController.Factory brightnessControllerFactory) {
-        super(view, qstileHost, metricsLogger, uiEventLogger, dumpManager);
+        super(view, qstileHost, qsCustomizerController, qsTileRevealControllerFactory,
+                metricsLogger, uiEventLogger, dumpManager);
         mQsSecurityFooter = qsSecurityFooter;
         mTunerService = tunerService;
+        mQsCustomizerController = qsCustomizerController;
         mQsSecurityFooter.setHostEnvironment(qstileHost);
         mBrightnessController = brightnessControllerFactory.create(
                 mView.findViewById(R.id.brightness_slider));
     }
 
     @Override
+    public void onInit() {
+        mQsCustomizerController.init();
+    }
+
+    @Override
     protected void onViewAttached() {
         super.onViewAttached();
         mTunerService.addTunable(mView, QS_SHOW_BRIGHTNESS);
@@ -110,20 +123,6 @@
         mView.setHeaderContainer(headerContainer);
     }
 
-    public QSPanel.QSTileLayout getTileLayout() {
-        return mView.getTileLayout();
-    }
-
-    /** */
-    public void setCustomizer(QSCustomizer customizer) {
-        mView.setCustomizer(customizer);
-    }
-
-    /** */
-    public boolean isShowingCustomize() {
-        return mView.isShowingCustomize();
-    }
-
     /** */
     public void setVisibility(int visibility) {
         mView.setVisibility(visibility);
@@ -148,11 +147,6 @@
     }
 
     /** */
-    public QSTileRevealController getQsTileRevealController() {
-        return mView.getQsTileRevealController();
-    }
-
-    /** */
     public MediaHost getMediaHost() {
         return mView.getMediaHost();
     }
@@ -196,6 +190,70 @@
 
     /** Start customizing the Quick Settings. */
     public void showEdit(View view) {
-        mView.showEdit(view);
+        view.post(() -> {
+            if (!mQsCustomizerController.isCustomizing()) {
+                int[] loc = view.getLocationOnScreen();
+                int x = loc[0] + view.getWidth() / 2;
+                int y = loc[1] + view.getHeight() / 2;
+                mQsCustomizerController.show(x, y, false);
+            }
+        });
+    }
+
+    /** */
+    public void setCallback(QSDetail.Callback qsPanelCallback) {
+        mView.setCallback(qsPanelCallback);
+    }
+
+    /** */
+    public void setGridContentVisibility(boolean visible) {
+        mView.setGridContentVisibility(visible);
+    }
+
+    public boolean isLayoutRtl() {
+        return mView.isLayoutRtl();
+    }
+
+    public View getBrightnessView() {
+        return mView.getBrightnessView();
+    }
+
+    public View getDivider() {
+        return mView.getDivider();
+    }
+
+    /** */
+    public void setPageListener(PagedTileLayout.PageListener listener) {
+        mView.setPageListener(listener);
+    }
+
+    /** */
+    public void setMediaVisibilityChangedListener(Consumer<Boolean> visibilityChangedListener) {
+        mView.setMediaVisibilityChangedListener(visibilityChangedListener);
+    }
+
+    public boolean isShown() {
+        return mView.isShown();
+    }
+
+    /** */
+    public void setContentMargins(int startMargin, int endMargin) {
+        mView.setContentMargins(startMargin, endMargin);
+    }
+
+    /** */
+    public Pair<Integer, Integer> getVisualSideMargins() {
+        return mView.getVisualSideMargins();
+    }
+
+    /** */
+    public void showDetailDapater(DetailAdapter detailAdapter, int x, int y) {
+        mView.showDetailAdapter(true, detailAdapter, new int[]{x, y});
+    }
+
+    /** */
+    public void setFooterPageIndicator(PageIndicator pageIndicator) {
+        mView.setFooterPageIndicator(pageIndicator);
     }
 }
+
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 68a6cdc..a3daf0e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -29,6 +29,7 @@
 import com.android.systemui.media.MediaHost;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTileView;
+import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.util.ViewController;
 
@@ -46,6 +47,8 @@
 public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewController<T>
         implements Dumpable{
     protected final QSTileHost mHost;
+    private final QSCustomizerController mQsCustomizerController;
+    private final QSTileRevealController.Factory mQsTileRevealControllerFactory;
     private final MediaHost mMediaHost;
     private final MetricsLogger mMetricsLogger;
     private final UiEventLogger mUiEventLogger;
@@ -53,6 +56,9 @@
     protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
 
     private int mLastOrientation;
+    private String mCachedSpecs = "";
+    private QSTileRevealController mQsTileRevealController;
+    private float mRevealExpansion;
 
     private final QSHost.Callback mQSHostCallback = this::setTiles;
 
@@ -66,12 +72,15 @@
                     }
                 }
             };
-    private String mCachedSpecs = "";
 
     protected QSPanelControllerBase(T view, QSTileHost host,
+            QSCustomizerController qsCustomizerController,
+            QSTileRevealController.Factory qsTileRevealControllerFactory,
             MetricsLogger metricsLogger, UiEventLogger uiEventLogger, DumpManager dumpManager) {
         super(view);
         mHost = host;
+        mQsCustomizerController = qsCustomizerController;
+        mQsTileRevealControllerFactory = qsTileRevealControllerFactory;
         mMediaHost = mView.getMediaHost();
         mMetricsLogger = metricsLogger;
         mUiEventLogger = uiEventLogger;
@@ -80,6 +89,13 @@
 
     @Override
     protected void onViewAttached() {
+        QSPanel.QSTileLayout regularTileLayout = mView.createRegularTileLayout();
+        if (regularTileLayout instanceof PagedTileLayout) {
+            mQsTileRevealController = mQsTileRevealControllerFactory.create(
+                    (PagedTileLayout) regularTileLayout);
+            mQsTileRevealController.setExpansion(mRevealExpansion);
+        }
+
         mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
         mHost.addCallback(mQSHostCallback);
         mMediaHost.addVisibilityChangeListener(aBoolean -> {
@@ -111,7 +127,7 @@
     /** */
     public void setTiles(Collection<QSTile> tiles, boolean collapsedView) {
         if (!collapsedView) {
-            mView.updateRevealedTiles(tiles);
+            mQsTileRevealController.updateRevealedTiles(tiles);
         }
         for (QSPanelControllerBase.TileRecord record : mRecords) {
             mView.removeTile(record);
@@ -192,6 +208,10 @@
 
     /** */
     public void closeDetail() {
+        if (mQsCustomizerController.isShown()) {
+            mQsCustomizerController.hide();
+            return;
+        }
         mView.closeDetail();
     }
 
@@ -228,6 +248,13 @@
         }
     }
 
+    /** Set the expansion on the associated {@link QSTileRevealController}. */
+    public void setRevealExpansion(float expansion) {
+        mRevealExpansion = expansion;
+        if (mQsTileRevealController != null) {
+            mQsTileRevealController.setExpansion(expansion);
+        }
+    }
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -241,6 +268,10 @@
         }
     }
 
+    public QSPanel.QSTileLayout getTileLayout() {
+        return mView.getTileLayout();
+    }
+
     /** */
     public static final class TileRecord extends QSPanel.Record {
         public QSTile tile;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
index 3d4a417..9414d0e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
@@ -8,6 +8,7 @@
 
 import com.android.systemui.Prefs;
 import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSScope;
 
 import java.util.Collection;
@@ -17,13 +18,13 @@
 import javax.inject.Inject;
 
 /** */
-@QSScope
 public class QSTileRevealController {
     private static final long QS_REVEAL_TILES_DELAY = 500L;
 
     private final Context mContext;
     private final QSPanel mQSPanel;
     private final PagedTileLayout mPagedTileLayout;
+    private final QSCustomizerController mQsCustomizerController;
     private final ArraySet<String> mTilesToReveal = new ArraySet<>();
     private final Handler mHandler = new Handler();
 
@@ -38,12 +39,12 @@
             });
         }
     };
-
-    @Inject
-    QSTileRevealController(Context context, QSPanel qsPanel, PagedTileLayout pagedTileLayout) {
+    QSTileRevealController(Context context, QSPanel qsPanel, PagedTileLayout pagedTileLayout,
+            QSCustomizerController qsCustomizerController) {
         mContext = context;
         mQSPanel = qsPanel;
         mPagedTileLayout = pagedTileLayout;
+        mQsCustomizerController = qsCustomizerController;
     }
 
     public void setExpansion(float expansion) {
@@ -62,7 +63,7 @@
 
         final Set<String> revealedTiles = Prefs.getStringSet(
                 mContext, QS_TILE_SPECS_REVEALED, Collections.EMPTY_SET);
-        if (revealedTiles.isEmpty() || mQSPanel.isShowingCustomize()) {
+        if (revealedTiles.isEmpty() || mQsCustomizerController.isCustomizing()) {
             // Do not reveal QS tiles the user has upon first load or those that they directly
             // added through customization.
             addTileSpecsToRevealed(tileSpecs);
@@ -79,4 +80,24 @@
         revealedTiles.addAll(specs);
         Prefs.putStringSet(mContext, QS_TILE_SPECS_REVEALED, revealedTiles);
     }
+
+    /** TODO(b/168904199): Remove this once QSPanel has its rejection removed. */
+    @QSScope
+    static class Factory {
+        private final Context mContext;
+        private final QSPanel mQsPanel;
+        private final QSCustomizerController mQsCustomizerController;
+
+        @Inject
+        Factory(Context context, QSPanel qsPanel, QSCustomizerController qsCustomizerController) {
+            mContext = context;
+            mQsPanel = qsPanel;
+            mQsCustomizerController = qsCustomizerController;
+        }
+
+        QSTileRevealController create(PagedTileLayout pagedTileLayout) {
+            return new QSTileRevealController(mContext, mQsPanel, pagedTileLayout,
+                    mQsCustomizerController);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index ed0900d..9c421b0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -46,7 +46,7 @@
 
     public static final String NUM_QUICK_TILES = "sysui_qqs_count";
     private static final String TAG = "QuickQSPanel";
-    // Start it at 6 so a non-zero value can be obtained statically.
+    // A default value so that we never return 0.
     private static int sDefaultMaxTiles = 6;
 
     private boolean mDisabledByPolicy;
@@ -63,6 +63,7 @@
             UiEventLogger uiEventLogger) {
         super(context, attrs, qsLogger, mediaHost, uiEventLogger);
         sDefaultMaxTiles = getResources().getInteger(R.integer.quick_qs_panel_max_columns);
+        mMaxTiles = sDefaultMaxTiles;
         applyBottomMargin((View) mRegularTileLayout);
     }
 
@@ -170,10 +171,6 @@
         }
     }
 
-    public static int getDefaultMaxTiles() {
-        return sDefaultMaxTiles;
-    }
-
     void setDisabledByPolicy(boolean disabled) {
         if (disabled != mDisabledByPolicy) {
             mDisabledByPolicy = disabled;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
index 97b6e99..fa6289f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -23,6 +23,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
@@ -41,9 +42,12 @@
 
     @Inject
     QuickQSPanelController(QuickQSPanel view, TunerService tunerService, QSTileHost qsTileHost,
+            QSCustomizerController qsCustomizerController,
+            QSTileRevealController.Factory qsTileRevealControllerFactory,
             MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
             DumpManager dumpManager) {
-        super(view, qsTileHost, metricsLogger, uiEventLogger, dumpManager);
+        super(view, qsTileHost, qsCustomizerController, qsTileRevealControllerFactory,
+                metricsLogger, uiEventLogger, dumpManager);
         mTunerService = tunerService;
     }
 
@@ -80,4 +84,8 @@
         }
         super.setTiles(quickTiles, true);
     }
+
+    public int getNumQuickTiles() {
+        return mView.getNumQuickTiles();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java b/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
index 3ee3e11..994da9a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SecureSetting.java
@@ -16,18 +16,17 @@
 
 package com.android.systemui.qs;
 
-import android.content.Context;
 import android.database.ContentObserver;
 import android.os.Handler;
-import android.provider.Settings.Secure;
 
 import com.android.systemui.statusbar.policy.Listenable;
+import com.android.systemui.util.settings.SecureSettings;
 
 /** Helper for managing a secure setting. **/
 public abstract class SecureSetting extends ContentObserver implements Listenable {
     private static final int DEFAULT = 0;
 
-    private final Context mContext;
+    private SecureSettings mSecureSettings;
     private final String mSettingName;
 
     private boolean mListening;
@@ -36,19 +35,20 @@
 
     protected abstract void handleValueChanged(int value, boolean observedChange);
 
-    public SecureSetting(Context context, Handler handler, String settingName, int userId) {
+    public SecureSetting(SecureSettings secureSettings, Handler handler, String settingName,
+            int userId) {
         super(handler);
-        mContext = context;
+        mSecureSettings = secureSettings;
         mSettingName = settingName;
         mUserId = userId;
     }
 
     public int getValue() {
-        return Secure.getIntForUser(mContext.getContentResolver(), mSettingName, DEFAULT, mUserId);
+        return mSecureSettings.getIntForUser(mSettingName, DEFAULT, mUserId);
     }
 
     public void setValue(int value) {
-        Secure.putIntForUser(mContext.getContentResolver(), mSettingName, value, mUserId);
+        mSecureSettings.putIntForUser(mSettingName, value, mUserId);
     }
 
     @Override
@@ -57,10 +57,10 @@
         mListening = listening;
         if (listening) {
             mObservedValue = getValue();
-            mContext.getContentResolver().registerContentObserver(
-                    Secure.getUriFor(mSettingName), false, this, mUserId);
+            mSecureSettings.registerContentObserverForUser(
+                    mSecureSettings.getUriFor(mSettingName), false, this, mUserId);
         } else {
-            mContext.getContentResolver().unregisterContentObserver(this);
+            mSecureSettings.unregisterContentObserver(this);
             mObservedValue = DEFAULT;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 8097958..3291aa0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -20,41 +20,23 @@
 import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.os.Bundle;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.Menu;
-import android.view.MenuItem;
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.Toolbar;
-import android.widget.Toolbar.OnMenuItemClickListener;
 
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 import androidx.recyclerview.widget.DefaultItemAnimator;
-import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.UiEventLoggerImpl;
 import com.android.systemui.R;
-import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.QSDetailClipper;
-import com.android.systemui.qs.QSEditEvent;
-import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.KeyguardStateController.Callback;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
 
 /**
  * Allows full-screen customization of QS, through show() and hide().
@@ -62,24 +44,16 @@
  * This adds itself to the status bar window, so it can appear on top of quick settings and
  * *someday* do fancy animations to get into/out of it.
  */
-public class QSCustomizer extends LinearLayout implements OnMenuItemClickListener {
+public class QSCustomizer extends LinearLayout {
 
-    private static final int MENU_RESET = Menu.FIRST;
-    private static final String EXTRA_QS_CUSTOMIZING = "qs_customizing";
-    private static final String TAG = "QSCustomizer";
+    static final int MENU_RESET = Menu.FIRST;
+    static final String EXTRA_QS_CUSTOMIZING = "qs_customizing";
 
     private final QSDetailClipper mClipper;
-    private final LightBarController mLightBarController;
-    private KeyguardStateController mKeyguardStateController;
-    private final ScreenLifecycle mScreenLifecycle;
-    private final TileQueryHelper mTileQueryHelper;
     private final View mTransparentView;
-    private final QSTileHost mHost;
 
     private boolean isShown;
-    private RecyclerView mRecyclerView;
-    private TileAdapter mTileAdapter;
-    private Toolbar mToolbar;
+    private final RecyclerView mRecyclerView;
     private boolean mCustomizing;
     private NotificationsQuickSettingsContainer mNotifQsContainer;
     private QS mQs;
@@ -87,90 +61,47 @@
     private int mY;
     private boolean mOpening;
     private boolean mIsShowingNavBackdrop;
-    private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
 
-    @Inject
-    public QSCustomizer(Context context, AttributeSet attrs,
-            LightBarController lightBarController,
-            KeyguardStateController keyguardStateController,
-            ScreenLifecycle screenLifecycle,
-            TileQueryHelper tileQueryHelper,
-            QSTileHost qsTileHost,
-            UiEventLogger uiEventLogger) {
+    public QSCustomizer(Context context, AttributeSet attrs) {
         super(new ContextThemeWrapper(context, R.style.edit_theme), attrs);
 
         LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this);
         mClipper = new QSDetailClipper(findViewById(R.id.customize_container));
-        mToolbar = findViewById(com.android.internal.R.id.action_bar);
+        Toolbar toolbar = findViewById(com.android.internal.R.id.action_bar);
         TypedValue value = new TypedValue();
         mContext.getTheme().resolveAttribute(android.R.attr.homeAsUpIndicator, value, true);
-        mToolbar.setNavigationIcon(
+        toolbar.setNavigationIcon(
                 getResources().getDrawable(value.resourceId, mContext.getTheme()));
-        mToolbar.setNavigationOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                hide();
-            }
-        });
-        mToolbar.setOnMenuItemClickListener(this);
-        mToolbar.getMenu().add(Menu.NONE, MENU_RESET, 0,
+
+        toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0,
                 mContext.getString(com.android.internal.R.string.reset));
-        mToolbar.setTitle(R.string.qs_edit);
+        toolbar.setTitle(R.string.qs_edit);
         mRecyclerView = findViewById(android.R.id.list);
         mTransparentView = findViewById(R.id.customizer_transparent_view);
-        mTileAdapter = new TileAdapter(getContext(), uiEventLogger);
-        mTileQueryHelper = tileQueryHelper;
-        mTileQueryHelper.setListener(mTileAdapter);
-        mRecyclerView.setAdapter(mTileAdapter);
-        mTileAdapter.getItemTouchHelper().attachToRecyclerView(mRecyclerView);
-        GridLayoutManager layout = new GridLayoutManager(getContext(), 3) {
-            @Override
-            public void onInitializeAccessibilityNodeInfoForItem(RecyclerView.Recycler recycler,
-                    RecyclerView.State state, View host, AccessibilityNodeInfoCompat info) {
-                // Do not read row and column every time it changes.
-            }
-        };
-        layout.setSpanSizeLookup(mTileAdapter.getSizeLookup());
-        mRecyclerView.setLayoutManager(layout);
-        mRecyclerView.addItemDecoration(mTileAdapter.getItemDecoration());
-        mRecyclerView.addItemDecoration(mTileAdapter.getMarginItemDecoration());
         DefaultItemAnimator animator = new DefaultItemAnimator();
         animator.setMoveDuration(TileAdapter.MOVE_DURATION);
         mRecyclerView.setItemAnimator(animator);
-        mLightBarController = lightBarController;
-        mKeyguardStateController = keyguardStateController;
-        mScreenLifecycle = screenLifecycle;
-        mHost = qsTileHost;
-        mTileAdapter.setHost(mHost);
-        updateNavBackDrop(getResources().getConfiguration());
     }
 
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        updateNavBackDrop(newConfig);
-        updateResources();
-    }
-
-    private void updateResources() {
+    void updateResources() {
         LayoutParams lp = (LayoutParams) mTransparentView.getLayoutParams();
         lp.height = mContext.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.quick_qs_offset_height);
         mTransparentView.setLayoutParams(lp);
     }
 
-    private void updateNavBackDrop(Configuration newConfig) {
+    void updateNavBackDrop(Configuration newConfig, LightBarController lightBarController) {
         View navBackdrop = findViewById(R.id.nav_bar_background);
         mIsShowingNavBackdrop = newConfig.smallestScreenWidthDp >= 600
                 || newConfig.orientation != Configuration.ORIENTATION_LANDSCAPE;
         if (navBackdrop != null) {
             navBackdrop.setVisibility(mIsShowingNavBackdrop ? View.VISIBLE : View.GONE);
         }
-        updateNavColors();
+        updateNavColors(lightBarController);
     }
 
-    private void updateNavColors() {
-        mLightBarController.setQsCustomizing(mIsShowingNavBackdrop && isShown);
+    void updateNavColors(LightBarController lightBarController) {
+        lightBarController.setQsCustomizing(mIsShowingNavBackdrop && isShown);
     }
 
     public void setContainer(NotificationsQuickSettingsContainer notificationsQsContainer) {
@@ -184,39 +115,30 @@
     /** Animate and show QSCustomizer panel.
      * @param x,y Location on screen of {@code edit} button to determine center of animation.
      */
-    public void show(int x, int y) {
+    void show(int x, int y, TileAdapter tileAdapter) {
         if (!isShown) {
-            int containerLocation[] = findViewById(R.id.customize_container).getLocationOnScreen();
+            int[] containerLocation = findViewById(R.id.customize_container).getLocationOnScreen();
             mX = x - containerLocation[0];
             mY = y - containerLocation[1];
-            mUiEventLogger.log(QSEditEvent.QS_EDIT_OPEN);
             isShown = true;
             mOpening = true;
-            setTileSpecs();
             setVisibility(View.VISIBLE);
-            mClipper.animateCircularClip(mX, mY, true, mExpandAnimationListener);
-            queryTiles();
+            mClipper.animateCircularClip(mX, mY, true, new ExpandAnimatorListener(tileAdapter));
             mNotifQsContainer.setCustomizerAnimating(true);
             mNotifQsContainer.setCustomizerShowing(true);
-            mKeyguardStateController.addCallback(mKeyguardCallback);
-            updateNavColors();
         }
     }
 
 
-    public void showImmediately() {
+    void showImmediately() {
         if (!isShown) {
             setVisibility(VISIBLE);
             mClipper.cancelAnimator();
             mClipper.showBackground();
             isShown = true;
-            setTileSpecs();
             setCustomizing(true);
-            queryTiles();
             mNotifQsContainer.setCustomizerAnimating(false);
             mNotifQsContainer.setCustomizerShowing(true);
-            mKeyguardStateController.addCallback(mKeyguardCallback);
-            updateNavColors();
         }
     }
 
@@ -225,9 +147,6 @@
      * {@link TileAdapter}.
      */
     public void setContentPaddings(int paddingStart, int paddingEnd) {
-        int halfMargin = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal) / 2;
-        mTileAdapter.changeHalfMargin(halfMargin);
         mRecyclerView.setPaddingRelative(
                 paddingStart,
                 mRecyclerView.getPaddingTop(),
@@ -236,22 +155,14 @@
         );
     }
 
-    private void queryTiles() {
-        mTileQueryHelper.queryTiles(mHost);
-    }
-
-    public void hide() {
-        final boolean animate = mScreenLifecycle.getScreenState() != ScreenLifecycle.SCREEN_OFF;
+    /** Hide the customizer. */
+    public void hide(boolean animate) {
         if (isShown) {
-            mUiEventLogger.log(QSEditEvent.QS_EDIT_CLOSED);
             isShown = false;
-            mToolbar.dismissPopupMenus();
             mClipper.cancelAnimator();
             // Make sure we're not opening (because we're closing). Nobody can think we are
             // customizing after the next two lines.
             mOpening = false;
-            setCustomizing(false);
-            save();
             if (animate) {
                 mClipper.animateCircularClip(mX, mY, false, mCollapseAnimationListener);
             } else {
@@ -259,8 +170,6 @@
             }
             mNotifQsContainer.setCustomizerAnimating(animate);
             mNotifQsContainer.setCustomizerShowing(false);
-            mKeyguardStateController.removeCallback(mKeyguardCallback);
-            updateNavColors();
         }
     }
 
@@ -268,7 +177,7 @@
         return isShown;
     }
 
-    private void setCustomizing(boolean customizing) {
+    void setCustomizing(boolean customizing) {
         mCustomizing = customizing;
         mQs.notifyCustomizeChanged();
     }
@@ -277,78 +186,21 @@
         return mCustomizing || mOpening;
     }
 
-    @Override
-    public boolean onMenuItemClick(MenuItem item) {
-        switch (item.getItemId()) {
-            case MENU_RESET:
-                mUiEventLogger.log(QSEditEvent.QS_EDIT_RESET);
-                reset();
-                break;
-        }
-        return false;
-    }
-
-    private void reset() {
-        mTileAdapter.resetTileSpecs(mHost, QSTileHost.getDefaultSpecs(mContext));
-    }
-
-    private void setTileSpecs() {
-        List<String> specs = new ArrayList<>();
-        for (QSTile tile : mHost.getTiles()) {
-            specs.add(tile.getTileSpec());
-        }
-        mTileAdapter.setTileSpecs(specs);
-        mRecyclerView.setAdapter(mTileAdapter);
-    }
-
-    private void save() {
-        if (mTileQueryHelper.isFinished()) {
-            mTileAdapter.saveSpecs(mHost);
-        }
-    }
-
-
-    public void saveInstanceState(Bundle outState) {
-        if (isShown) {
-            mKeyguardStateController.removeCallback(mKeyguardCallback);
-        }
-        outState.putBoolean(EXTRA_QS_CUSTOMIZING, mCustomizing);
-    }
-
-    public void restoreInstanceState(Bundle savedInstanceState) {
-        boolean customizing = savedInstanceState.getBoolean(EXTRA_QS_CUSTOMIZING);
-        if (customizing) {
-            setVisibility(VISIBLE);
-            addOnLayoutChangeListener(new OnLayoutChangeListener() {
-                @Override
-                public void onLayoutChange(View v, int left, int top, int right, int bottom,
-                        int oldLeft,
-                        int oldTop, int oldRight, int oldBottom) {
-                    removeOnLayoutChangeListener(this);
-                    showImmediately();
-                }
-            });
-        }
-    }
     /** @param x,y Location on screen of animation center.
      */
     public void setEditLocation(int x, int y) {
-        int containerLocation[] = findViewById(R.id.customize_container).getLocationOnScreen();
+        int[] containerLocation = findViewById(R.id.customize_container).getLocationOnScreen();
         mX = x - containerLocation[0];
         mY = y - containerLocation[1];
     }
 
-    private final Callback mKeyguardCallback = new Callback() {
-        @Override
-        public void onKeyguardShowingChanged() {
-            if (!isAttachedToWindow()) return;
-            if (mKeyguardStateController.isShowing() && !mOpening) {
-                hide();
-            }
-        }
-    };
+    class ExpandAnimatorListener extends AnimatorListenerAdapter {
+        private final TileAdapter mTileAdapter;
 
-    private final AnimatorListener mExpandAnimationListener = new AnimatorListenerAdapter() {
+        ExpandAnimatorListener(TileAdapter tileAdapter) {
+            mTileAdapter = tileAdapter;
+        }
+
         @Override
         public void onAnimationEnd(Animator animation) {
             if (isShown) {
@@ -356,6 +208,7 @@
             }
             mOpening = false;
             mNotifQsContainer.setCustomizerAnimating(false);
+            mRecyclerView.setAdapter(mTileAdapter);
         }
 
         @Override
@@ -363,7 +216,7 @@
             mOpening = false;
             mNotifQsContainer.setCustomizerAnimating(false);
         }
-    };
+    }
 
     private final AnimatorListener mCollapseAnimationListener = new AnimatorListenerAdapter() {
         @Override
@@ -372,7 +225,6 @@
                 setVisibility(View.GONE);
             }
             mNotifQsContainer.setCustomizerAnimating(false);
-            mRecyclerView.setAdapter(mTileAdapter);
         }
 
         @Override
@@ -383,4 +235,12 @@
             mNotifQsContainer.setCustomizerAnimating(false);
         }
     };
-}
+
+    public RecyclerView getRecyclerView() {
+        return mRecyclerView;
+    }
+
+    public boolean isOpening() {
+        return mOpening;
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
new file mode 100644
index 0000000..9f4c58b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
@@ -0,0 +1,247 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.qs.customize;
+
+import static com.android.systemui.qs.customize.QSCustomizer.EXTRA_QS_CUSTOMIZING;
+import static com.android.systemui.qs.customize.QSCustomizer.MENU_RESET;
+
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Toolbar;
+import android.widget.Toolbar.OnMenuItemClickListener;
+
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.R;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.QSEditEvent;
+import com.android.systemui.qs.QSFragment;
+import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.dagger.QSScope;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.ViewController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+/** {@link ViewController} for {@link QSCustomizer}. */
+@QSScope
+public class QSCustomizerController extends ViewController<QSCustomizer> {
+    private final TileQueryHelper mTileQueryHelper;
+    private final QSTileHost mQsTileHost;
+    private final TileAdapter mTileAdapter;
+    private final ScreenLifecycle mScreenLifecycle;
+    private final KeyguardStateController mKeyguardStateController;
+    private final LightBarController mLightBarController;
+    private final ConfigurationController mConfigurationController;
+    private final UiEventLogger mUiEventLogger;
+    private final Toolbar mToolbar;
+
+    private final OnMenuItemClickListener mOnMenuItemClickListener = new OnMenuItemClickListener() {
+        @Override
+        public boolean onMenuItemClick(MenuItem item) {
+            if (item.getItemId() == MENU_RESET) {
+                mUiEventLogger.log(QSEditEvent.QS_EDIT_RESET);
+                reset();
+            }
+            return false;
+        }
+    };
+
+    private final KeyguardStateController.Callback mKeyguardCallback =
+            new KeyguardStateController.Callback() {
+        @Override
+        public void onKeyguardShowingChanged() {
+            if (!mView.isAttachedToWindow()) return;
+            if (mKeyguardStateController.isShowing() && !mView.isOpening()) {
+                hide();
+            }
+        }
+    };
+
+    private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+        @Override
+        public void onConfigChanged(Configuration newConfig) {
+            mView.updateNavBackDrop(newConfig, mLightBarController);
+            mView.updateResources();
+        }
+    };
+
+    @Inject
+    protected QSCustomizerController(QSCustomizer view, TileQueryHelper tileQueryHelper,
+            QSTileHost qsTileHost, TileAdapter tileAdapter, ScreenLifecycle screenLifecycle,
+            KeyguardStateController keyguardStateController, LightBarController lightBarController,
+            ConfigurationController configurationController, UiEventLogger uiEventLogger) {
+        super(view);
+        mTileQueryHelper = tileQueryHelper;
+        mQsTileHost = qsTileHost;
+        mTileAdapter = tileAdapter;
+        mScreenLifecycle = screenLifecycle;
+        mKeyguardStateController = keyguardStateController;
+        mLightBarController = lightBarController;
+        mConfigurationController = configurationController;
+        mUiEventLogger = uiEventLogger;
+
+        mToolbar = mView.findViewById(com.android.internal.R.id.action_bar);
+    }
+
+    @Override
+    protected void onViewAttached() {
+        mView.updateNavBackDrop(getResources().getConfiguration(), mLightBarController);
+
+        mConfigurationController.addCallback(mConfigurationListener);
+
+        mTileQueryHelper.setListener(mTileAdapter);
+        int halfMargin =
+                getResources().getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal) / 2;
+        mTileAdapter.changeHalfMargin(halfMargin);
+
+        RecyclerView recyclerView = mView.getRecyclerView();
+        recyclerView.setAdapter(mTileAdapter);
+        mTileAdapter.getItemTouchHelper().attachToRecyclerView(recyclerView);
+        GridLayoutManager layout = new GridLayoutManager(getContext(), 3) {
+            @Override
+            public void onInitializeAccessibilityNodeInfoForItem(RecyclerView.Recycler recycler,
+                    RecyclerView.State state, View host, AccessibilityNodeInfoCompat info) {
+                // Do not read row and column every time it changes.
+            }
+        };
+        layout.setSpanSizeLookup(mTileAdapter.getSizeLookup());
+        recyclerView.setLayoutManager(layout);
+        recyclerView.addItemDecoration(mTileAdapter.getItemDecoration());
+        recyclerView.addItemDecoration(mTileAdapter.getMarginItemDecoration());
+
+        mToolbar.setOnMenuItemClickListener(mOnMenuItemClickListener);
+        mToolbar.setNavigationOnClickListener(v -> hide());
+    }
+
+    @Override
+    protected void onViewDetached() {
+        mTileQueryHelper.setListener(null);
+        mToolbar.setOnMenuItemClickListener(null);
+        mConfigurationController.removeCallback(mConfigurationListener);
+    }
+
+
+    private void reset() {
+        mTileAdapter.resetTileSpecs(QSTileHost.getDefaultSpecs(getContext()));
+    }
+
+    public boolean isCustomizing() {
+        return mView.isCustomizing();
+    }
+
+    /** */
+    public void show(int x, int y, boolean immediate) {
+        if (!mView.isShown()) {
+            setTileSpecs();
+            if (immediate) {
+                mView.showImmediately();
+            } else {
+                mView.show(x, y, mTileAdapter);
+                mUiEventLogger.log(QSEditEvent.QS_EDIT_OPEN);
+            }
+            mTileQueryHelper.queryTiles(mQsTileHost);
+            mKeyguardStateController.addCallback(mKeyguardCallback);
+            mView.updateNavColors(mLightBarController);
+        }
+    }
+
+    /** */
+    public void setQs(QSFragment qsFragment) {
+        mView.setQs(qsFragment);
+    }
+
+    /** */
+    public void restoreInstanceState(Bundle savedInstanceState) {
+        boolean customizing = savedInstanceState.getBoolean(EXTRA_QS_CUSTOMIZING);
+        if (customizing) {
+            mView.setVisibility(View.VISIBLE);
+            mView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft,
+                        int oldTop, int oldRight, int oldBottom) {
+                    mView.removeOnLayoutChangeListener(this);
+                    show(0, 0, true);
+                }
+            });
+        }
+    }
+
+    /** */
+    public void saveInstanceState(Bundle outState) {
+        if (mView.isShown()) {
+            mKeyguardStateController.removeCallback(mKeyguardCallback);
+        }
+        outState.putBoolean(EXTRA_QS_CUSTOMIZING, mView.isCustomizing());
+    }
+
+    /** */
+    public void setEditLocation(int x, int y) {
+        mView.setEditLocation(x, y);
+    }
+
+    /** */
+    public void setContainer(NotificationsQuickSettingsContainer container) {
+        mView.setContainer(container);
+    }
+
+    public boolean isShown() {
+        return mView.isShown();
+    }
+
+    /** Hice the customizer. */
+    public void hide() {
+        final boolean animate = mScreenLifecycle.getScreenState() != ScreenLifecycle.SCREEN_OFF;
+        if (mView.isShown()) {
+            mUiEventLogger.log(QSEditEvent.QS_EDIT_CLOSED);
+            mToolbar.dismissPopupMenus();
+            mView.setCustomizing(false);
+            save();
+            mView.hide(animate);
+            mView.updateNavColors(mLightBarController);
+            mKeyguardStateController.removeCallback(mKeyguardCallback);
+        }
+    }
+
+    private void save() {
+        if (mTileQueryHelper.isFinished()) {
+            mTileAdapter.saveSpecs(mQsTileHost);
+        }
+    }
+
+    private void setTileSpecs() {
+        List<String> specs = new ArrayList<>();
+        for (QSTile tile : mQsTileHost.getTiles()) {
+            specs.add(tile.getTileSpec());
+        }
+        mTileAdapter.setTileSpecs(specs);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index b471dfa..dfc771b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -46,12 +46,17 @@
 import com.android.systemui.qs.customize.TileAdapter.Holder;
 import com.android.systemui.qs.customize.TileQueryHelper.TileInfo;
 import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener;
+import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.qs.tileimpl.QSIconViewImpl;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+
+/** */
+@QSScope
 public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileStateListener {
     private static final long DRAG_LENGTH = 100;
     private static final float DRAG_SCALE = 1.2f;
@@ -78,6 +83,7 @@
     private final ItemDecoration mDecoration;
     private final MarginTileDecoration mMarginDecoration;
     private final int mMinNumTiles;
+    private final QSTileHost mHost;
     private int mEditIndex;
     private int mTileDividerIndex;
     private int mFocusIndex;
@@ -89,13 +95,14 @@
     private Holder mCurrentDrag;
     private int mAccessibilityAction = ACTION_NONE;
     private int mAccessibilityFromIndex;
-    private QSTileHost mHost;
     private final UiEventLogger mUiEventLogger;
     private final AccessibilityDelegateCompat mAccessibilityDelegate;
     private RecyclerView mRecyclerView;
 
-    public TileAdapter(Context context, UiEventLogger uiEventLogger) {
+    @Inject
+    public TileAdapter(Context context, QSTileHost qsHost, UiEventLogger uiEventLogger) {
         mContext = context;
+        mHost = qsHost;
         mUiEventLogger = uiEventLogger;
         mItemTouchHelper = new ItemTouchHelper(mCallbacks);
         mDecoration = new TileItemDecoration(context);
@@ -114,10 +121,6 @@
         mRecyclerView = null;
     }
 
-    public void setHost(QSTileHost host) {
-        mHost = host;
-    }
-
     public ItemTouchHelper getItemTouchHelper() {
         return mItemTouchHelper;
     }
@@ -154,9 +157,10 @@
         mAccessibilityAction = ACTION_NONE;
     }
 
-    public void resetTileSpecs(QSTileHost host, List<String> specs) {
+    /** */
+    public void resetTileSpecs(List<String> specs) {
         // Notify the host so the tiles get removed callbacks.
-        host.changeTiles(mCurrentSpecs, specs);
+        mHost.changeTiles(mCurrentSpecs, specs);
         setTileSpecs(specs);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index b795a5f..59490c6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -37,6 +37,7 @@
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTile.State;
 import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon;
 import com.android.systemui.settings.UserTracker;
@@ -50,6 +51,8 @@
 
 import javax.inject.Inject;
 
+/** */
+@QSScope
 public class TileQueryHelper {
     private static final String TAG = "TileQueryHelper";
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
index 51b2c8d..8cc0502 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
@@ -22,6 +22,7 @@
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.qs.QSPanelController;
 import com.android.systemui.qs.QuickQSPanelController;
+import com.android.systemui.qs.customize.QSCustomizerController;
 
 import dagger.BindsInstance;
 import dagger.Subcomponent;
@@ -32,6 +33,7 @@
 @Subcomponent(modules = {QSFragmentModule.class})
 @QSScope
 public interface QSFragmentComponent {
+
     /** Factory for building a {@link QSFragmentComponent}. */
     @Subcomponent.Factory
     interface Factory {
@@ -52,4 +54,7 @@
 
     /** Construct a {@link QSFooter} */
     QSFooter getQSFooter();
+
+    /** Construct a {@link QSCustomizerController}. */
+    QSCustomizerController getQSCustomizerController();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
index 4bf4eff..354b2c9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -29,6 +29,7 @@
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QuickQSPanel;
 import com.android.systemui.qs.QuickStatusBarHeader;
+import com.android.systemui.qs.customize.QSCustomizer;
 
 import dagger.Binds;
 import dagger.Module;
@@ -87,4 +88,11 @@
         qsFooterViewController.init();
         return qsFooterViewController;
     }
+
+    /** */
+    @Provides
+    @QSScope
+    static QSCustomizer providesQSCutomizer(@RootView View view) {
+        return view.findViewById(R.id.qs_customize);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 7c799ae..cfc81ee 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -30,6 +30,7 @@
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.util.settings.SecureSettings;
 
 import dagger.Binds;
 import dagger.Module;
@@ -48,14 +49,24 @@
             AutoAddTracker.Builder autoAddTrackerBuilder,
             QSTileHost host,
             @Background Handler handler,
+            SecureSettings secureSettings,
             HotspotController hotspotController,
             DataSaverController dataSaverController,
             ManagedProfileController managedProfileController,
             NightDisplayListener nightDisplayListener,
             CastController castController) {
-        AutoTileManager manager = new AutoTileManager(context, autoAddTrackerBuilder,
-                host, handler, hotspotController, dataSaverController, managedProfileController,
-                nightDisplayListener, castController);
+        AutoTileManager manager = new AutoTileManager(
+                context,
+                autoAddTrackerBuilder,
+                host,
+                handler,
+                secureSettings,
+                hotspotController,
+                dataSaverController,
+                managedProfileController,
+                nightDisplayListener,
+                castController
+        );
         manager.init();
         return manager;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index c64fc50..bf3e4be 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -36,6 +36,7 @@
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.util.settings.SecureSettings;
 
 import javax.inject.Inject;
 
@@ -62,15 +63,20 @@
             StatusBarStateController statusBarStateController,
             ActivityStarter activityStarter,
             QSLogger qsLogger,
-            BatteryController batteryController
+            BatteryController batteryController,
+            SecureSettings secureSettings
     ) {
         super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
                 activityStarter, qsLogger);
         mBatteryController = batteryController;
         mBatteryController.observe(getLifecycle(), this);
         int currentUser = host.getUserContext().getUserId();
-        mSetting = new SecureSetting(mContext, mHandler, Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
-                currentUser) {
+        mSetting = new SecureSetting(
+                secureSettings,
+                mHandler,
+                Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
+                currentUser
+        ) {
             @Override
             protected void handleValueChanged(int value, boolean observedChange) {
                 // mHandler is the background handler so calling this is OK
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 5e6a6ce..f742752 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -25,6 +25,7 @@
 import android.content.res.Resources;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.telephony.SubscriptionManager;
@@ -244,7 +245,8 @@
 
     @Override
     public boolean isAvailable() {
-        return mController.hasMobileDataFeature();
+        return mController.hasMobileDataFeature()
+            && mHost.getUserContext().getUserId() == UserHandle.USER_SYSTEM;
     }
 
     private static final class CallbackInfo {
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 98782f7..3995248 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -39,6 +39,7 @@
 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.SecureSettings;
 
 import javax.inject.Inject;
 
@@ -63,12 +64,13 @@
             StatusBarStateController statusBarStateController,
             ActivityStarter activityStarter,
             QSLogger qsLogger,
-            UserTracker userTracker
+            UserTracker userTracker,
+            SecureSettings secureSettings
     ) {
         super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
                 activityStarter, qsLogger);
 
-        mSetting = new SecureSetting(mContext, mainHandler,
+        mSetting = new SecureSetting(secureSettings, mainHandler,
                 Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, userTracker.getUserId()) {
             @Override
             protected void handleValueChanged(int value, boolean observedChange) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index ddf30ad..c27b047 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -207,8 +207,9 @@
             try {
                 // TODO move this logic to message queue
                 mStatusBarOptionalLazy.ifPresent(statusBarLazy -> {
+                    StatusBar statusBar = statusBarLazy.get();
+                    statusBar.getPanelController().startExpandLatencyTracking();
                     mHandler.post(()-> {
-                        StatusBar statusBar = statusBarLazy.get();
                         int action = event.getActionMasked();
                         if (action == ACTION_DOWN) {
                             mInputFocusTransferStarted = true;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
index 5c26d94..df9fc63 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
@@ -35,9 +35,6 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 
 import java.util.Optional;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 
 import javax.inject.Inject;
 
@@ -48,7 +45,6 @@
 public class ActionProxyReceiver extends BroadcastReceiver {
     private static final String TAG = "ActionProxyReceiver";
 
-    private static final int CLOSE_WINDOWS_TIMEOUT_MILLIS = 3000;
     private final StatusBar mStatusBar;
     private final ActivityManagerWrapper mActivityManagerWrapper;
     private final ScreenshotSmartActions mScreenshotSmartActions;
@@ -65,14 +61,7 @@
     @Override
     public void onReceive(Context context, final Intent intent) {
         Runnable startActivityRunnable = () -> {
-            try {
-                mActivityManagerWrapper.closeSystemWindows(
-                        SYSTEM_DIALOG_REASON_SCREENSHOT).get(
-                        CLOSE_WINDOWS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
-            } catch (TimeoutException | InterruptedException | ExecutionException e) {
-                Log.e(TAG, "Unable to share screenshot", e);
-                return;
-            }
+            mActivityManagerWrapper.closeSystemWindows(SYSTEM_DIALOG_REASON_SCREENSHOT);
 
             PendingIntent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
             ActivityOptions opts = ActivityOptions.makeBasic();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 260f557..7fe88b9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -27,7 +27,6 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.Notification;
-import android.app.WindowContext;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -43,6 +42,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -58,8 +58,10 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.Toast;
 
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.R;
+import com.android.systemui.util.DeviceConfigProxy;
 
 import java.util.List;
 import java.util.function.Consumer;
@@ -143,6 +145,8 @@
     private final DisplayMetrics mDisplayMetrics;
     private final AccessibilityManager mAccessibilityManager;
     private final MediaActionSound mCameraSound;
+    private final ScrollCaptureClient mScrollCaptureClient;
+    private final DeviceConfigProxy mConfigProxy;
 
     private final Binder mWindowToken;
     private ScreenshotView mScreenshotView;
@@ -173,11 +177,16 @@
     };
 
     @Inject
-    ScreenshotController(Context context, ScreenshotSmartActions screenshotSmartActions,
+    ScreenshotController(
+            Context context,
+            ScreenshotSmartActions screenshotSmartActions,
             ScreenshotNotificationsController screenshotNotificationsController,
-            UiEventLogger uiEventLogger) {
+            ScrollCaptureClient scrollCaptureClient,
+            UiEventLogger uiEventLogger,
+            DeviceConfigProxy configProxy) {
         mScreenshotSmartActions = screenshotSmartActions;
         mNotificationsController = screenshotNotificationsController;
+        mScrollCaptureClient = scrollCaptureClient;
         mUiEventLogger = uiEventLogger;
 
         final DisplayManager dm = requireNonNull(context.getSystemService(DisplayManager.class));
@@ -186,6 +195,7 @@
         mWindowManager = mContext.getSystemService(WindowManager.class);
 
         mAccessibilityManager = AccessibilityManager.getInstance(mContext);
+        mConfigProxy = configProxy;
 
         reloadAssets();
         Configuration config = mContext.getResources().getConfiguration();
@@ -193,6 +203,7 @@
         mDirectionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
         mOrientationPortrait = config.orientation == ORIENTATION_PORTRAIT;
         mWindowToken = new Binder("ScreenshotController");
+        mScrollCaptureClient.setHostWindowToken(mWindowToken);
 
         // Setup the window that we are going to use
         mWindowLayoutParams = new WindowManager.LayoutParams(
@@ -455,6 +466,19 @@
 
         // Start the post-screenshot animation
         startAnimation(finisher, screenRect, screenInsets, showFlash);
+
+        if (mConfigProxy.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.SCREENSHOT_SCROLLING_ENABLED, false)) {
+            mScrollCaptureClient.request(DEFAULT_DISPLAY, (connection) ->
+                    mScreenshotView.showScrollChip(() ->
+                            runScrollCapture(connection,
+                                    () -> dismissScreenshot(true))));
+        }
+    }
+
+    private void runScrollCapture(ScrollCaptureClient.Connection connection,
+            Runnable after) {
+        new ScrollCaptureController(mContext, connection).run(after);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 29f6e8b..3383f80 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -113,6 +113,7 @@
     private FrameLayout mDismissButton;
     private ScreenshotActionChip mShareChip;
     private ScreenshotActionChip mEditChip;
+    private ScreenshotActionChip mScrollChip;
 
     private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>();
     private PendingInteraction mPendingInteraction;
@@ -152,6 +153,20 @@
         mContext.getDisplay().getRealMetrics(mDisplayMetrics);
     }
 
+    /**
+     * Called to display the scroll action chip when support is detected.
+     *
+     * @param onClick the action to take when the chip is clicked.
+     */
+    public void showScrollChip(Runnable onClick) {
+        mScrollChip.setVisibility(VISIBLE);
+        mScrollChip.setOnClickListener((v) ->
+                onClick.run()
+                // TODO Logging, store event consumer to a field
+                //onElementTapped.accept(ScreenshotEvent.SCREENSHOT_SCROLL_TAPPED);
+        );
+    }
+
     @Override // ViewTreeObserver.OnComputeInternalInsetsListener
     public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
         inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
@@ -193,6 +208,7 @@
         mScreenshotSelectorView = requireNonNull(findViewById(R.id.global_screenshot_selector));
         mShareChip = requireNonNull(mActionsContainer.findViewById(R.id.screenshot_share_chip));
         mEditChip = requireNonNull(mActionsContainer.findViewById(R.id.screenshot_edit_chip));
+        mScrollChip = requireNonNull(mActionsContainer.findViewById(R.id.screenshot_scroll_chip));
 
         mScreenshotPreview.setClipToOutline(true);
         mScreenshotPreview.setOutlineProvider(new ViewOutlineProvider() {
@@ -387,7 +403,7 @@
         });
         chips.add(mShareChip);
 
-        mEditChip.setText(mContext.getString(com.android.internal.R.string.screenshot_edit));
+        mEditChip.setText(mContext.getString(R.string.screenshot_edit_label));
         mEditChip.setIcon(Icon.createWithResource(mContext, R.drawable.ic_screenshot_edit), true);
         mEditChip.setOnClickListener(v -> {
             mEditChip.setIsPending(true);
@@ -402,6 +418,11 @@
             mPendingInteraction = PendingInteraction.PREVIEW;
         });
 
+        mScrollChip.setText(mContext.getString(R.string.screenshot_scroll_label));
+        mScrollChip.setIcon(Icon.createWithResource(mContext,
+                R.drawable.ic_screenshot_scroll), true);
+        chips.add(mScrollChip);
+
         // remove the margin from the last chip so that it's correctly aligned with the end
         LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
                 mActionsView.getChildAt(0).getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java
new file mode 100644
index 0000000..ea835fa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java
@@ -0,0 +1,346 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.screenshot;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.UiContext;
+import android.app.ActivityTaskManager;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+import android.media.Image;
+import android.media.ImageReader;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.IScrollCaptureCallbacks;
+import android.view.IScrollCaptureConnection;
+import android.view.IWindowManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.view.ScrollCaptureViewSupport;
+
+import java.util.function.Consumer;
+
+import javax.inject.Inject;
+
+/**
+ * High level interface to scroll capture API.
+ */
+public class ScrollCaptureClient {
+
+    @VisibleForTesting
+    static final int MATCH_ANY_TASK = ActivityTaskManager.INVALID_TASK_ID;
+
+    private static final String TAG = "ScrollCaptureClient";
+
+    /** Whether to log method names and arguments for most calls */
+    private static final boolean DEBUG_TRACE = false;
+
+    /**
+     * A connection to a remote window. Starts a capture session.
+     */
+    public interface Connection {
+        /**
+         * Session start should be deferred until UI is active because of resource allocation and
+         * potential visible side effects in the target window.
+         *
+         * @param maxBuffers the maximum number of buffers (tiles) that may be in use at one
+         *                   time, tiles are not cached anywhere so set this to a large enough
+         *                   number to retain offscreen content until it is no longer needed
+         * @param sessionConsumer listener to receive the session once active
+         */
+        void start(int maxBuffers, Consumer<Session> sessionConsumer);
+
+        /**
+         * Close the connection.
+         */
+        void close();
+    }
+
+    static class CaptureResult {
+        public final Image image;
+        /**
+         * The area requested, in content rect space, relative to scroll-bounds.
+         */
+        public final Rect requested;
+        /**
+         * The actual area captured, in content rect space, relative to scroll-bounds. This may be
+         * cropped or empty depending on available content.
+         */
+        public final Rect captured;
+
+        // Error?
+
+        private CaptureResult(Image image, Rect request, Rect captured) {
+            this.image =  image;
+            this.requested = request;
+            this.captured = captured;
+        }
+    }
+
+    /**
+     * Represents the connection to a target window and provides a mechanism for requesting tiles.
+     */
+    interface Session {
+        /**
+         * Request the given horizontal strip. Values are y-coordinates in captured space, relative
+         * to start position.
+         *
+         * @param contentRect the area to capture, in content rect space, relative to scroll-bounds
+         * @param consumer listener to be informed of the result
+         */
+        void requestTile(Rect contentRect, Consumer<CaptureResult> consumer);
+
+        /**
+         * End the capture session, return the target app to original state. The returned
+         * stage must be waited for to complete to allow the target app a chance to restore to
+         * original state before becoming visible.
+         *
+         * @return a stage presenting the session shutdown
+         */
+        void end(Runnable listener);
+
+        int getMaxTileHeight();
+
+        int getMaxTileWidth();
+    }
+
+    private final IWindowManager mWindowManagerService;
+    private IBinder mHostWindowToken;
+
+    @Inject
+    public ScrollCaptureClient(@UiContext Context context, IWindowManager windowManagerService) {
+        requireNonNull(context.getDisplay(), "context must be associated with a Display!");
+        mWindowManagerService = windowManagerService;
+    }
+
+    public void setHostWindowToken(IBinder token) {
+        mHostWindowToken = token;
+    }
+
+    /**
+     * Check for scroll capture support.
+     *
+     * @param displayId id for the display containing the target window
+     * @param consumer receives a connection when available
+     */
+    public void request(int displayId, Consumer<Connection> consumer) {
+        request(displayId, MATCH_ANY_TASK, consumer);
+    }
+
+    /**
+     * Check for scroll capture support.
+     *
+     * @param displayId id for the display containing the target window
+     * @param taskId id for the task containing the target window or {@link #MATCH_ANY_TASK}.
+     * @param consumer receives a connection when available
+     */
+    public void request(int displayId, int taskId, Consumer<Connection> consumer) {
+        try {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "requestScrollCapture(displayId=" + displayId + ", " + mHostWindowToken
+                        + ", taskId=" + taskId + ", consumer=" + consumer + ")");
+            }
+            mWindowManagerService.requestScrollCapture(displayId, mHostWindowToken, taskId,
+                    new ControllerCallbacks(consumer));
+        } catch (RemoteException e) {
+            Log.e(TAG, "Ignored remote exception", e);
+        }
+    }
+
+    private static class ControllerCallbacks extends IScrollCaptureCallbacks.Stub implements
+            Connection, Session, IBinder.DeathRecipient {
+
+        private IScrollCaptureConnection mConnection;
+        private Consumer<Connection> mConnectionConsumer;
+        private Consumer<Session> mSessionConsumer;
+        private Consumer<CaptureResult> mResultConsumer;
+        private Runnable mShutdownListener;
+
+        private ImageReader mReader;
+        private Rect mScrollBounds;
+        private Rect mRequestRect;
+        private boolean mStarted;
+
+        private ControllerCallbacks(Consumer<Connection> connectionConsumer) {
+            mConnectionConsumer = connectionConsumer;
+        }
+
+        // IScrollCaptureCallbacks
+
+        @Override
+        public void onConnected(IScrollCaptureConnection connection, Rect scrollBounds,
+                Point positionInWindow) throws RemoteException {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "onConnected(connection=" + connection + ", scrollBounds=" + scrollBounds
+                        + ", positionInWindow=" + positionInWindow + ")");
+            }
+            mConnection = connection;
+            mConnection.asBinder().linkToDeath(this, 0);
+            mScrollBounds = scrollBounds;
+            mConnectionConsumer.accept(this);
+            mConnectionConsumer = null;
+        }
+
+        @Override
+        public void onUnavailable() throws RemoteException {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "onUnavailable");
+            }
+            // The targeted app does not support scroll capture
+            // or the window could not be found... etc etc.
+        }
+
+        @Override
+        public void onCaptureStarted() {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "onCaptureStarted()");
+            }
+            mSessionConsumer.accept(this);
+            mSessionConsumer = null;
+        }
+
+        @Override
+        public void onCaptureBufferSent(long frameNumber, Rect contentArea) {
+            Image image = null;
+            if (frameNumber != ScrollCaptureViewSupport.NO_FRAME_PRODUCED) {
+                image = mReader.acquireNextImage();
+            }
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "onCaptureBufferSent(frameNumber=" + frameNumber
+                        + ", contentArea=" + contentArea + ") image=" + image);
+            }
+            // Save and clear first, since the consumer will likely request the next
+            // tile, otherwise the new consumer will be wiped out.
+            Consumer<CaptureResult> consumer = mResultConsumer;
+            mResultConsumer = null;
+            consumer.accept(new CaptureResult(image, mRequestRect, contentArea));
+        }
+
+        @Override
+        public void onConnectionClosed() {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "onConnectionClosed()");
+            }
+            disconnect();
+            if (mShutdownListener != null) {
+                mShutdownListener.run();
+                mShutdownListener = null;
+            }
+        }
+
+        // Misc
+
+        private void disconnect() {
+            if (mConnection != null) {
+                mConnection.asBinder().unlinkToDeath(this, 0);
+            }
+            mConnection = null;
+        }
+
+        // ScrollCaptureController.Connection
+
+        // -> Error handling: BiConsumer<Session, Throwable> ?
+        @Override
+        public void start(int maxBufferCount, Consumer<Session> sessionConsumer) {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "start(maxBufferCount=" + maxBufferCount
+                        + ", sessionConsumer=" + sessionConsumer + ")");
+            }
+            mReader = ImageReader.newInstance(mScrollBounds.width(), mScrollBounds.height(),
+                    PixelFormat.RGBA_8888, maxBufferCount, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
+            mSessionConsumer = sessionConsumer;
+            try {
+                mConnection.startCapture(mReader.getSurface());
+                mStarted = true;
+            } catch (RemoteException e) {
+                Log.w(TAG, "should not be happening :-(");
+                // ?
+                //mSessionListener.onError(e);
+                //mSessionListener = null;
+            }
+        }
+
+        @Override
+        public void close() {
+            end(null);
+        }
+
+        // ScrollCaptureController.Session
+
+        @Override
+        public void end(Runnable listener) {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "end(listener=" + listener + ")");
+            }
+            if (mStarted) {
+                mShutdownListener = listener;
+                try {
+                    // listener called from onConnectionClosed callback
+                    mConnection.endCapture();
+                } catch (RemoteException e) {
+                    Log.d(TAG, "Ignored exception from endCapture()", e);
+                    disconnect();
+                    listener.run();
+                }
+            } else {
+                disconnect();
+                listener.run();
+            }
+        }
+
+        @Override
+        public int getMaxTileHeight() {
+            return mScrollBounds.height();
+        }
+
+        @Override
+        public int getMaxTileWidth() {
+            return mScrollBounds.width();
+        }
+
+        @Override
+        public void requestTile(Rect contentRect, Consumer<CaptureResult> consumer) {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "requestTile(contentRect=" + contentRect + "consumer=" + consumer + ")");
+            }
+            mRequestRect = new Rect(contentRect);
+            mResultConsumer = consumer;
+            try {
+                mConnection.requestImage(mRequestRect);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Caught remote exception from requestImage", e);
+                // ?
+            }
+        }
+
+        /**
+         * The process hosting the window went away abruptly!
+         */
+        @Override
+        public void binderDied() {
+            if (DEBUG_TRACE) {
+                Log.d(TAG, "binderDied()");
+            }
+            disconnect();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
index 5ced40c..800d679 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
@@ -16,46 +16,231 @@
 
 package com.android.systemui.screenshot;
 
-import android.os.IBinder;
-import android.view.IWindowManager;
+import static android.graphics.ColorSpace.Named.SRGB;
 
-import javax.inject.Inject;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorSpace;
+import android.graphics.Picture;
+import android.graphics.Rect;
+import android.media.ExifInterface;
+import android.media.Image;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
+import android.provider.MediaStore;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.systemui.screenshot.ScrollCaptureClient.Connection;
+import com.android.systemui.screenshot.ScrollCaptureClient.Session;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.sql.Date;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.function.Consumer;
 
 /**
- * Stub
+ * Interaction controller between the UI and ScrollCaptureClient.
  */
 public class ScrollCaptureController {
+    private static final String TAG = "ScrollCaptureController";
 
-    public static final int STATUS_A = 0;
-    public static final int STATUS_B = 1;
+    public static final int MAX_PAGES = 5;
+    public static final int MAX_HEIGHT = 12000;
 
-    private final IWindowManager mWindowManagerService;
-    private StatusListener mListener;
+    private final Connection mConnection;
+    private final Context mContext;
+    private Picture mPicture;
 
-    /**
-     *
-     * @param windowManagerService
-     */
-    @Inject
-    public ScrollCaptureController(IWindowManager windowManagerService) {
-        mWindowManagerService = windowManagerService;
-    }
-
-    interface StatusListener {
-        void onScrollCaptureStatus(boolean available);
+    public ScrollCaptureController(Context context, Connection connection) {
+        mContext = context;
+        mConnection = connection;
     }
 
     /**
+     * Run scroll capture!
      *
-     * @param window
-     * @param listener
+     * @param after action to take after the flow is complete
      */
-    public void getStatus(IBinder window, StatusListener listener) {
-        mListener = listener;
-//        try {
-//           mWindowManagerService.requestScrollCapture(window, new ClientCallbacks());
-//        } catch (RemoteException e) {
-//        }
+    public void run(final Runnable after) {
+        mConnection.start(MAX_PAGES, (session) -> startCapture(session, after));
     }
 
+    private void startCapture(Session session, final Runnable after) {
+        Rect requestRect = new Rect(0, 0,
+                session.getMaxTileWidth(), session.getMaxTileHeight());
+        Consumer<ScrollCaptureClient.CaptureResult> consumer =
+                new Consumer<ScrollCaptureClient.CaptureResult>() {
+
+                    int mFrameCount = 0;
+
+                    @Override
+                    public void accept(ScrollCaptureClient.CaptureResult result) {
+                        mFrameCount++;
+                        boolean emptyFrame = result.captured.height() == 0;
+                        if (!emptyFrame) {
+                            mPicture = stackBelow(mPicture, result.image, result.captured.width(),
+                                    result.captured.height());
+                        }
+                        if (emptyFrame || mFrameCount > MAX_PAGES
+                                || requestRect.bottom > MAX_HEIGHT) {
+                            Uri uri = null;
+                            if (mPicture != null) {
+                                // This is probably on a binder thread right now ¯\_(ツ)_/¯
+                                uri = writeImage(Bitmap.createBitmap(mPicture));
+                                // Release those buffers!
+                                mPicture.close();
+                            }
+                            if (uri != null) {
+                                launchViewer(uri);
+                            } else {
+                                Toast.makeText(mContext, "Failed to create tall screenshot",
+                                        Toast.LENGTH_SHORT).show();
+                            }
+                            session.end(after); // end session, close connection, after.run()
+                            return;
+                        }
+                        requestRect.offset(0, session.getMaxTileHeight());
+                        session.requestTile(requestRect, /* consumer */ this);
+                    }
+                };
+
+        // fire it up!
+        session.requestTile(requestRect, consumer);
+    };
+
+
+    /**
+     * Combine the top {@link Picture} with an {@link Image} by appending the image directly
+     * below, creating a result that is the combined height of both.
+     * <p>
+     * Note: no pixel data is transferred here, only a record of drawing commands. Backing
+     * hardware buffers must not be modified/recycled until the picture is
+     * {@link Picture#close closed}.
+     *
+     * @param top the existing picture
+     * @param below the image to append below
+     * @param cropWidth the width of the pixel data to use from the image
+     * @param cropHeight the height of the pixel data to use from the image
+     *
+     * @return a new Picture which draws the previous picture with the image below it
+     */
+    private static Picture stackBelow(Picture top, Image below, int cropWidth, int cropHeight) {
+        int width = cropWidth;
+        int height = cropHeight;
+        if (top != null) {
+            height += top.getHeight();
+            width = Math.max(width, top.getWidth());
+        }
+        Picture combined = new Picture();
+        Canvas canvas = combined.beginRecording(width, height);
+        int y = 0;
+        if (top != null) {
+            canvas.drawPicture(top, new Rect(0, 0, top.getWidth(), top.getHeight()));
+            y += top.getHeight();
+        }
+        canvas.drawBitmap(Bitmap.wrapHardwareBuffer(
+                below.getHardwareBuffer(), ColorSpace.get(SRGB)), 0, y, null);
+        combined.endRecording();
+        return combined;
+    }
+
+    Uri writeImage(Bitmap image) {
+        ContentResolver resolver = mContext.getContentResolver();
+        long mImageTime = System.currentTimeMillis();
+        String imageDate = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(mImageTime));
+        String mImageFileName = String.format("tall_Screenshot_%s.png", imageDate);
+        String mScreenshotId = String.format("Screenshot_%s", UUID.randomUUID());
+        try {
+            // Save the screenshot to the MediaStore
+            final ContentValues values = new ContentValues();
+            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES
+                    + File.separator + Environment.DIRECTORY_SCREENSHOTS);
+            values.put(MediaStore.MediaColumns.DISPLAY_NAME, mImageFileName);
+            values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
+            values.put(MediaStore.MediaColumns.DATE_ADDED, mImageTime / 1000);
+            values.put(MediaStore.MediaColumns.DATE_MODIFIED, mImageTime / 1000);
+            values.put(
+                    MediaStore.MediaColumns.DATE_EXPIRES,
+                    (mImageTime + DateUtils.DAY_IN_MILLIS) / 1000);
+            values.put(MediaStore.MediaColumns.IS_PENDING, 1);
+
+            final Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+                    values);
+            try {
+                try (OutputStream out = resolver.openOutputStream(uri)) {
+                    if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
+                        throw new IOException("Failed to compress");
+                    }
+                }
+
+                // Next, write metadata to help index the screenshot
+                try (ParcelFileDescriptor pfd = resolver.openFile(uri, "rw", null)) {
+                    final ExifInterface exif = new ExifInterface(pfd.getFileDescriptor());
+
+                    exif.setAttribute(ExifInterface.TAG_SOFTWARE,
+                            "Android " + Build.DISPLAY);
+
+                    exif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH,
+                            Integer.toString(image.getWidth()));
+                    exif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH,
+                            Integer.toString(image.getHeight()));
+
+                    final ZonedDateTime time = ZonedDateTime.ofInstant(
+                            Instant.ofEpochMilli(mImageTime), ZoneId.systemDefault());
+                    exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL,
+                            DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss").format(time));
+                    exif.setAttribute(ExifInterface.TAG_SUBSEC_TIME_ORIGINAL,
+                            DateTimeFormatter.ofPattern("SSS").format(time));
+
+                    if (Objects.equals(time.getOffset(), ZoneOffset.UTC)) {
+                        exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL, "+00:00");
+                    } else {
+                        exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL,
+                                DateTimeFormatter.ofPattern("XXX").format(time));
+                    }
+                    exif.saveAttributes();
+                }
+
+                // Everything went well above, publish it!
+                values.clear();
+                values.put(MediaStore.MediaColumns.IS_PENDING, 0);
+                values.putNull(MediaStore.MediaColumns.DATE_EXPIRES);
+                resolver.update(uri, values, null, null);
+                return uri;
+            } catch (Exception e) {
+                resolver.delete(uri, null);
+                throw e;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "unable to save screenshot", e);
+        }
+        return null;
+    }
+
+    void launchViewer(Uri uri) {
+        Intent editIntent = new Intent(Intent.ACTION_VIEW);
+        editIntent.setType("image/png");
+        editIntent.setData(uri);
+        editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        mContext.startActivityAsUser(editIntent, UserHandle.CURRENT);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index a92b9e4..9bd34ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -26,7 +26,6 @@
 import android.view.ViewGroup;
 
 import com.android.systemui.R;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.dagger.StatusBarModule;
@@ -43,6 +42,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.util.Assert;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.ArrayList;
 import java.util.HashMap;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
index cee9c70..efd0519 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
@@ -21,7 +21,6 @@
 import android.os.Handler;
 
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.media.MediaDataManager;
@@ -62,6 +61,7 @@
 import com.android.systemui.tracing.ProtoTracer;
 import com.android.systemui.util.DeviceConfigProxy;
 import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.Optional;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 382715a..45e8098 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification;
 
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_APP_START;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
@@ -32,6 +34,7 @@
 import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
 import android.view.View;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -226,10 +229,27 @@
                     }
                 });
                 anim.addListener(new AnimatorListenerAdapter() {
+                    private boolean mWasCancelled;
+
+                    @Override
+                    public void onAnimationStart(Animator animation) {
+                        InteractionJankMonitor.getInstance().begin(CUJ_NOTIFICATION_APP_START);
+                    }
+
+                    @Override
+                    public void onAnimationCancel(Animator animation) {
+                        mWasCancelled = true;
+                    }
+
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         setExpandAnimationRunning(false);
                         invokeCallback(iRemoteAnimationFinishedCallback);
+                        if (!mWasCancelled) {
+                            InteractionJankMonitor.getInstance().end(CUJ_NOTIFICATION_APP_START);
+                        } else {
+                            InteractionJankMonitor.getInstance().cancel(CUJ_NOTIFICATION_APP_START);
+                        }
                     }
                 });
                 anim.start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java
index eee9cc6..967524c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java
@@ -16,9 +16,7 @@
 
 package com.android.systemui.statusbar.notification;
 
-import android.graphics.drawable.Drawable;
 import android.util.FloatProperty;
-import android.util.Log;
 import android.util.Property;
 import android.view.View;
 
@@ -34,9 +32,14 @@
 
     public static final AnimatableProperty X = AnimatableProperty.from(View.X,
             R.id.x_animator_tag, R.id.x_animator_tag_start_value, R.id.x_animator_tag_end_value);
+
     public static final AnimatableProperty Y = AnimatableProperty.from(View.Y,
             R.id.y_animator_tag, R.id.y_animator_tag_start_value, R.id.y_animator_tag_end_value);
 
+    public static final AnimatableProperty TRANSLATION_X = AnimatableProperty.from(
+            View.TRANSLATION_X, R.id.x_animator_tag, R.id.x_animator_tag_start_value,
+            R.id.x_animator_tag_end_value);
+
     /**
      * Similar to X, however this doesn't allow for any other modifications other than from this
      * property. When using X, it's possible that the view is laid out during the animation,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index 7d8979c..aef01e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -22,10 +22,10 @@
 import android.view.View;
 
 import com.android.systemui.DejankUtils;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.Optional;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
index 83a569b..29a030f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator;
 
-import com.android.systemui.bubbles.BubbleController;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -26,6 +24,8 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
 import com.android.systemui.wmshell.BubblesManager;
+import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.HashSet;
 import java.util.Optional;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
index 36adfac..3db5440 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
@@ -22,7 +22,6 @@
 import android.util.Log;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
@@ -34,6 +33,7 @@
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
index 049b471..52b9b06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
@@ -17,13 +17,13 @@
 package com.android.systemui.statusbar.notification.init
 
 import android.service.notification.StatusBarNotification
-import com.android.systemui.bubbles.Bubbles
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption
 import com.android.systemui.statusbar.NotificationPresenter
 import com.android.systemui.statusbar.notification.NotificationActivityStarter
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.phone.StatusBar
+import com.android.wm.shell.bubbles.Bubbles
 import java.io.FileDescriptor
 import java.io.PrintWriter
 import java.util.Optional
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 45a5d10..8f352ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification.init
 
 import android.service.notification.StatusBarNotification
-import com.android.systemui.bubbles.Bubbles
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption
 import com.android.systemui.statusbar.FeatureFlags
@@ -41,6 +40,7 @@
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.RemoteInputUriController
+import com.android.wm.shell.bubbles.Bubbles
 import dagger.Lazy
 import java.io.FileDescriptor
 import java.io.PrintWriter
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
index 7569c1b..d0e68bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification.init
 
 import android.service.notification.StatusBarNotification
-import com.android.systemui.bubbles.Bubbles
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption
 import com.android.systemui.statusbar.NotificationListener
 import com.android.systemui.statusbar.NotificationPresenter
@@ -25,6 +24,7 @@
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.phone.StatusBar
+import com.android.wm.shell.bubbles.Bubbles
 import java.io.FileDescriptor
 import java.io.PrintWriter
 import java.util.Optional
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 094e866..10273cbb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -33,6 +33,7 @@
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -750,12 +751,16 @@
                 if (!mWasCancelled) {
                     enableAppearDrawing(false);
                     onAppearAnimationFinished(isAppearing);
+                    InteractionJankMonitor.getInstance().end(getCujType(isAppearing));
+                } else {
+                    InteractionJankMonitor.getInstance().cancel(getCujType(isAppearing));
                 }
             }
 
             @Override
             public void onAnimationStart(Animator animation) {
                 mWasCancelled = false;
+                InteractionJankMonitor.getInstance().begin(getCujType(isAppearing));
             }
 
             @Override
@@ -766,6 +771,18 @@
         mAppearAnimator.start();
     }
 
+    private int getCujType(boolean isAppearing) {
+        if (mIsHeadsUpAnimation) {
+            return isAppearing
+                    ? InteractionJankMonitor.CUJ_NOTIFICATION_HEADS_UP_APPEAR
+                    : InteractionJankMonitor.CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR;
+        } else {
+            return isAppearing
+                    ? InteractionJankMonitor.CUJ_NOTIFICATION_ADD
+                    : InteractionJankMonitor.CUJ_NOTIFICATION_REMOVE;
+        }
+    }
+
     protected void onAppearAnimationFinished(boolean wasAppearing) {
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 280c525..a011d36 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -35,6 +35,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.graphics.Path;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.AnimationDrawable;
@@ -43,6 +44,7 @@
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.util.AttributeSet;
@@ -327,6 +329,7 @@
     private boolean mShelfIconVisible;
     private boolean mAboveShelf;
     private OnUserInteractionCallback mOnUserInteractionCallback;
+    private NotificationGutsManager mNotificationGutsManager;
     private boolean mIsLowPriority;
     private boolean mIsColorized;
     private boolean mUseIncreasedCollapsedHeight;
@@ -1089,6 +1092,13 @@
         };
     }
 
+    /** The click listener for the snooze button. */
+    public View.OnClickListener getSnoozeClickListener(MenuItem item) {
+        return v -> {
+            mNotificationGutsManager.openGuts(this, 0, 0, item);
+        };
+    }
+
     private void updateClickAndFocus() {
         boolean normalChild = !isChildInGroup() || isGroupExpanded();
         boolean clickable = mOnClickListener != null && normalChild;
@@ -1155,10 +1165,11 @@
      */
     @Nullable
     public NotificationMenuRowPlugin createMenu() {
-        if (mMenuRow == null) {
+        final boolean removeShelf = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.SHOW_NEW_NOTIF_DISMISS, 0 /* show shelf by default */) == 1;
+        if (mMenuRow == null || removeShelf) {
             return null;
         }
-
         if (mMenuRow.getMenuView() == null) {
             mMenuRow.createMenu(this, mEntry.getSbn());
             mMenuRow.setAppName(mAppName);
@@ -1555,7 +1566,8 @@
             StatusBarStateController statusBarStateController,
             PeopleNotificationIdentifier peopleNotificationIdentifier,
             OnUserInteractionCallback onUserInteractionCallback,
-            Optional<BubblesManager> bubblesManagerOptional) {
+            Optional<BubblesManager> bubblesManagerOptional,
+            NotificationGutsManager gutsManager) {
         mEntry = entry;
         mAppName = appName;
         if (mMenuRow == null) {
@@ -1584,6 +1596,7 @@
         }
         mOnUserInteractionCallback = onUserInteractionCallback;
         mBubblesManagerOptional = bubblesManagerOptional;
+        mNotificationGutsManager = gutsManager;
 
         cacheIsSystemNotification();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 05b1dba..cb2af54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -154,7 +154,8 @@
                 mStatusBarStateController,
                 mPeopleNotificationIdentifier,
                 mOnUserInteractionCallback,
-                mBubblesManagerOptional
+                mBubblesManagerOptional,
+                mNotificationGutsManager
         );
         mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
         if (mAllowLongPress) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 71e1d12..79c3007 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -18,12 +18,14 @@
 
 
 import static android.provider.Settings.Global.NOTIFICATION_BUBBLES;
+import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
@@ -31,6 +33,7 @@
 import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -44,6 +47,7 @@
 import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.TransformableView;
@@ -458,7 +462,7 @@
         mExpandedWrapper = NotificationViewWrapper.wrap(getContext(), child,
                 mContainingNotification);
         if (mContainingNotification != null) {
-            applyBubbleAction(mExpandedChild, mContainingNotification.getEntry());
+            applySystemActions(mExpandedChild, mContainingNotification.getEntry());
         }
     }
 
@@ -500,7 +504,7 @@
         mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child,
                 mContainingNotification);
         if (mContainingNotification != null) {
-            applyBubbleAction(mHeadsUpChild, mContainingNotification.getEntry());
+            applySystemActions(mHeadsUpChild, mContainingNotification.getEntry());
         }
     }
 
@@ -1161,8 +1165,8 @@
         mForceSelectNextLayout = true;
         mPreviousExpandedRemoteInputIntent = null;
         mPreviousHeadsUpRemoteInputIntent = null;
-        applyBubbleAction(mExpandedChild, entry);
-        applyBubbleAction(mHeadsUpChild, entry);
+        applySystemActions(mExpandedChild, entry);
+        applySystemActions(mHeadsUpChild, entry);
     }
 
     private void updateAllSingleLineViews() {
@@ -1340,6 +1344,14 @@
                 NOTIFICATION_BUBBLES, 0) == 1;
     }
 
+    /**
+     * Setup icon buttons provided by System UI.
+     */
+    private void applySystemActions(View layout, NotificationEntry entry) {
+        applySnoozeAction(layout);
+        applyBubbleAction(layout, entry);
+    }
+
     private void applyBubbleAction(View layout, NotificationEntry entry) {
         if (layout == null || mContainingNotification == null || mPeopleIdentifier == null) {
             return;
@@ -1359,8 +1371,8 @@
                 && entry.getBubbleMetadata() != null;
         if (showButton) {
             Drawable d = mContext.getResources().getDrawable(entry.isBubble()
-                    ? R.drawable.ic_stop_bubble
-                    : R.drawable.ic_create_bubble);
+                    ? R.drawable.bubble_ic_stop_bubble
+                    : R.drawable.bubble_ic_create_bubble);
             mContainingNotification.updateNotificationColor();
             final int tint = mContainingNotification.getNotificationColor();
             d.setTint(tint);
@@ -1387,6 +1399,45 @@
         }
     }
 
+    private void applySnoozeAction(View layout) {
+        if (layout == null || mContainingNotification == null) {
+            return;
+        }
+        ImageView snoozeButton = layout.findViewById(com.android.internal.R.id.snooze_button);
+        View actionContainer = layout.findViewById(com.android.internal.R.id.actions_container);
+        LinearLayout actionContainerLayout =
+                layout.findViewById(com.android.internal.R.id.actions_container_layout);
+        if (snoozeButton == null || actionContainer == null || actionContainerLayout == null) {
+            return;
+        }
+        final boolean showSnooze = Settings.Secure.getInt(mContext.getContentResolver(),
+                SHOW_NOTIFICATION_SNOOZE, 0) == 1;
+        if (!showSnooze) {
+            snoozeButton.setVisibility(GONE);
+            return;
+        }
+
+        Resources res = mContext.getResources();
+        Drawable snoozeDrawable = res.getDrawable(R.drawable.ic_snooze);
+        mContainingNotification.updateNotificationColor();
+        snoozeDrawable.setTint(mContainingNotification.getNotificationColor());
+        snoozeButton.setImageDrawable(snoozeDrawable);
+
+        final NotificationSnooze snoozeGuts = (NotificationSnooze) LayoutInflater.from(mContext)
+                .inflate(R.layout.notification_snooze, null, false);
+        final String snoozeDescription = res.getString(
+                R.string.notification_menu_snooze_description);
+        final NotificationMenuRowPlugin.MenuItem snoozeMenuItem =
+                new NotificationMenuRow.NotificationMenuItem(
+                        mContext, snoozeDescription, snoozeGuts, R.drawable.ic_snooze);
+        snoozeButton.setContentDescription(
+                mContext.getResources().getString(R.string.notification_menu_snooze_description));
+        snoozeButton.setOnClickListener(
+                mContainingNotification.getSnoozeClickListener(snoozeMenuItem));
+        snoozeButton.setVisibility(VISIBLE);
+        actionContainer.setVisibility(VISIBLE);
+    }
+
     private void applySmartReplyView(
             SmartRepliesAndActions smartRepliesAndActions,
             NotificationEntry entry) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 7a976ac..6ff5ed1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -236,6 +236,7 @@
                             NotificationChannel.DEFAULT_CHANNEL_ID)
                     && numTotalChannels == 1;
         }
+        mIsAutomaticChosen = getAlertingBehavior() == BEHAVIOR_AUTOMATIC;
 
         bindHeader();
         bindChannelDetails();
@@ -658,13 +659,14 @@
             try {
                 if (mChannelToUpdate != null) {
                     if (mUnlockImportance) {
-                        mChannelToUpdate.unlockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+                        mINotificationManager.unlockNotificationChannel(
+                                mPackageName, mAppUid, mChannelToUpdate.getId());
                     } else {
                         mChannelToUpdate.setImportance(mNewImportance);
                         mChannelToUpdate.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+                        mINotificationManager.updateNotificationChannelForPackage(
+                                mPackageName, mAppUid, mChannelToUpdate);
                     }
-                    mINotificationManager.updateNotificationChannelForPackage(
-                            mPackageName, mAppUid, mChannelToUpdate);
                 } else {
                     // For notifications with more than one channel, update notification enabled
                     // state. If the importance was lowered, we disable notifications.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 76c5baf..3622f1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -36,6 +36,7 @@
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.HotspotController.Callback;
 import com.android.systemui.util.UserAwareController;
+import com.android.systemui.util.settings.SecureSettings;
 
 import java.util.ArrayList;
 import java.util.Objects;
@@ -60,6 +61,7 @@
     protected final Context mContext;
     protected final QSTileHost mHost;
     protected final Handler mHandler;
+    protected final SecureSettings mSecureSettings;
     protected final AutoAddTracker mAutoTracker;
     private final HotspotController mHotspotController;
     private final DataSaverController mDataSaverController;
@@ -71,6 +73,7 @@
     public AutoTileManager(Context context, AutoAddTracker.Builder autoAddTrackerBuilder,
             QSTileHost host,
             @Background Handler handler,
+            SecureSettings secureSettings,
             HotspotController hotspotController,
             DataSaverController dataSaverController,
             ManagedProfileController managedProfileController,
@@ -78,6 +81,7 @@
             CastController castController) {
         mContext = context;
         mHost = host;
+        mSecureSettings = secureSettings;
         mCurrentUser = mHost.getUserContext().getUser();
         mAutoTracker = autoAddTrackerBuilder.setUserId(mCurrentUser.getIdentifier()).build();
         mHandler = handler;
@@ -170,7 +174,7 @@
                 String spec = split[1];
                 // Populate all the settings. As they may not have been added in other users
                 AutoAddSetting s = new AutoAddSetting(
-                        mContext, mHandler, setting, mCurrentUser.getIdentifier(), spec);
+                        mSecureSettings, mHandler, setting, mCurrentUser.getIdentifier(), spec);
                 mAutoAddSettingList.add(s);
             } else {
                 Log.w(TAG, "Malformed item in array: " + tile);
@@ -321,13 +325,13 @@
         private final String mSpec;
 
         AutoAddSetting(
-                Context context,
+                SecureSettings secureSettings,
                 Handler handler,
                 String setting,
                 int userId,
                 String tileSpec
         ) {
-            super(context, handler, setting, userId);
+            super(secureSettings, handler, setting, userId);
             mSpec = tileSpec;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index bd22893..5c225e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -257,7 +257,7 @@
         // TODO(b/12836565) - prototyping only adjustment
         if (mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL) {
             // This will keep the clock at the top for AOD
-            darkAmount = 0f;
+            return (int) (clockY + burnInPreventionOffsetY() + mEmptyDragAmount);
         }
 
         return (int) (MathUtils.lerp(clockY, clockYDark, darkAmount) + mEmptyDragAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 8636cb2..5f547b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -45,7 +45,7 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
-import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QSDetailDisplayer;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -369,8 +369,9 @@
         mMultiUserAvatar.setImageDrawable(picture);
     }
 
-    public void setQSPanel(QSPanel qsp) {
-        mMultiUserSwitch.setQsPanel(qsp);
+    /** */
+    public void setQSDetailDisplayer(QSDetailDisplayer detailDisplayer) {
+        mMultiUserSwitch.setQSDetailDisplayer(detailDisplayer);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
index 5e883be..289ff71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -39,7 +39,6 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.R;
-import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dock.DockManager;
@@ -77,7 +76,6 @@
     private final KeyguardStateController mKeyguardStateController;
     private final Resources mResources;
     private final HeadsUpManagerPhone mHeadsUpManagerPhone;
-    private final AuthController mAuthController;
     private boolean mKeyguardShowing;
     private boolean mKeyguardJustShown;
     private boolean mBlockUpdates;
@@ -326,8 +324,7 @@
             @Nullable DockManager dockManager,
             KeyguardStateController keyguardStateController,
             @Main Resources resources,
-            HeadsUpManagerPhone headsUpManagerPhone,
-            AuthController authController) {
+            HeadsUpManagerPhone headsUpManagerPhone) {
         mLockscreenGestureLogger = lockscreenGestureLogger;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mLockPatternUtils = lockPatternUtils;
@@ -342,7 +339,6 @@
         mKeyguardStateController = keyguardStateController;
         mResources = resources;
         mHeadsUpManagerPhone = headsUpManagerPhone;
-        mAuthController = authController;
 
         mKeyguardIndicationController.setLockIconController(this);
     }
@@ -508,7 +504,7 @@
      * @return true if the visibility changed
      */
     private boolean updateIconVisibility() {
-        if (mAuthController.isUdfpsEnrolled()) {
+        if (mKeyguardUpdateMonitor.isUdfpsEnrolled()) {
             boolean changed = mLockIcon.getVisibility() == GONE;
             mLockIcon.setVisibility(GONE);
             return changed;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 67b7e97..480d3f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -34,7 +34,7 @@
 import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.DetailAdapter;
-import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QSDetailDisplayer;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 
@@ -43,14 +43,13 @@
  */
 public class MultiUserSwitch extends FrameLayout implements View.OnClickListener {
 
-    protected QSPanel mQsPanel;
+    protected QSDetailDisplayer mQSDetailDisplayer;
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
     private boolean mKeyguardMode;
     private UserSwitcherController.BaseUserAdapter mUserListener;
 
     final UserManager mUserManager;
 
-    private final int[] mTmpInt2 = new int[2];
 
     protected UserSwitcherController mUserSwitcherController;
 
@@ -66,8 +65,9 @@
         refreshContentDescription();
     }
 
-    public void setQsPanel(QSPanel qsPanel) {
-        mQsPanel = qsPanel;
+    /** */
+    public void setQSDetailDisplayer(QSDetailDisplayer detailDisplayer) {
+        mQSDetailDisplayer = detailDisplayer;
         setUserSwitcherController(Dependency.get(UserSwitcherController.class));
     }
 
@@ -127,16 +127,15 @@
             if (mKeyguardUserSwitcher != null) {
                 mKeyguardUserSwitcher.show(true /* animate */);
             }
-        } else if (mQsPanel != null && mUserSwitcherController != null) {
+        } else if (mQSDetailDisplayer != null && mUserSwitcherController != null) {
             View center = getChildCount() > 0 ? getChildAt(0) : this;
 
-            center.getLocationInWindow(mTmpInt2);
-            mTmpInt2[0] += center.getWidth() / 2;
-            mTmpInt2[1] += center.getHeight() / 2;
+            int[] tmpInt = new int[2];
+            center.getLocationInWindow(tmpInt);
+            tmpInt[0] += center.getWidth() / 2;
+            tmpInt[1] += center.getHeight() / 2;
 
-            mQsPanel.showDetailAdapter(true,
-                    getUserDetailAdapter(),
-                    mTmpInt2);
+            mQSDetailDisplayer.showDetailAdapter(getUserDetailAdapter(), tmpInt[0], tmpInt[1]);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index f2ae3da7..ac91b70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -19,7 +19,6 @@
 import com.android.settingslib.Utils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.demomode.DemoModeController;
@@ -32,10 +31,14 @@
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.PropertyAnimator;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.stack.AnimationProperties;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -175,6 +178,16 @@
         updateIconLayoutParams(mContext);
     }
 
+    /**
+     * Update position of the view, with optional animation
+     */
+    public void updatePosition(int x, AnimationProperties props, boolean animate) {
+        if (mAodIcons != null) {
+            PropertyAnimator.setProperty(mAodIcons, AnimatableProperty.TRANSLATION_X, x, props,
+                    animate);
+        }
+    }
+
     public void setupShelf(NotificationShelfController notificationShelfController) {
         mShelfIcons = notificationShelfController.getShelfIcons();
         notificationShelfController.setCollapsedIcons(mNotificationIcons);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index e9a7132..193c963 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -89,7 +89,7 @@
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.qs.QSFragment;
+import com.android.systemui.qs.QSDetailDisplayer;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -268,6 +268,7 @@
     private final MediaHierarchyManager mMediaHierarchyManager;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
+    private final QSDetailDisplayer mQSDetailDisplayer;
     // Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
     // If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
     private final int mMaxKeyguardNotifications;
@@ -519,7 +520,8 @@
             KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
             NotificationGroupManagerLegacy groupManager,
             NotificationIconAreaController notificationIconAreaController,
-            AuthController authController) {
+            AuthController authController,
+            QSDetailDisplayer qsDetailDisplayer) {
         super(view, falsingManager, dozeLog, keyguardStateController,
                 (SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
                 latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager);
@@ -534,6 +536,7 @@
         mGroupManager = groupManager;
         mNotificationIconAreaController = notificationIconAreaController;
         mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
+        mQSDetailDisplayer = qsDetailDisplayer;
         mView.setWillNotDraw(!DEBUG);
         mInjectionInflationController = injectionInflationController;
         mFalsingManager = falsingManager;
@@ -606,6 +609,7 @@
     private void onFinishInflate() {
         loadDimens();
         mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header);
+        mKeyguardStatusBar.setQSDetailDisplayer(mQSDetailDisplayer);
         mBigClockContainer = mView.findViewById(R.id.big_clock_container);
         updateViewControllers(mView.findViewById(R.id.keyguard_status_view));
         mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
@@ -873,7 +877,7 @@
                     clockPreferredY, hasCustomClock(),
                     hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
                     bypassEnabled, getUnlockedStackScrollerPadding(),
-                    mAuthController.isUdfpsEnrolled());
+                    mUpdateMonitor.isUdfpsEnrolled());
             mClockPositionAlgorithm.run(mClockPositionResult);
             mKeyguardStatusViewController.updatePosition(
                     mClockPositionResult.clockX, mClockPositionResult.clockY, animateClock);
@@ -914,7 +918,7 @@
                         - Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding)
                         - mKeyguardStatusViewController.getLogoutButtonHeight();
 
-        if (mAuthController.isUdfpsEnrolled()) {
+        if (mUpdateMonitor.isUdfpsEnrolled()) {
             availableSpace = mNotificationStackScrollLayoutController.getHeight()
                     - minPadding - shelfSize
                     - (mStatusBar.getDisplayHeight() - mAuthController.getUdfpsRegion().top);
@@ -2867,9 +2871,6 @@
                         }
                     });
             mNotificationStackScrollLayoutController.setQsContainer((ViewGroup) mQs.getView());
-            if (mQs instanceof QSFragment) {
-                mKeyguardStatusBar.setQSPanel(((QSFragment) mQs).getQsPanel());
-            }
             updateQsExpansion();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index a3d3c2b..3db3ab5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -224,9 +224,6 @@
                 if (!isCancel && mService.shouldIgnoreTouch()) {
                     return false;
                 }
-                if (isDown && mNotificationPanelViewController.isFullyCollapsed()) {
-                    mNotificationPanelViewController.startExpandLatencyTracking();
-                }
                 if (isDown) {
                     setTouchActive(true);
                     mTouchCancelled = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
index af2f3e5..a930a89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
@@ -22,13 +22,13 @@
 import android.view.WindowManager;
 
 import com.android.systemui.assist.AssistManager;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.ArrayList;
 import java.util.Optional;
@@ -51,7 +51,7 @@
     private final int mDisplayId;
     protected final Lazy<StatusBar> mStatusBarLazy;
     private final Lazy<AssistManager> mAssistManagerLazy;
-    private final Optional<Lazy<Bubbles>> mBubblesOptional;
+    private final Optional<Bubbles> mBubblesOptional;
 
     private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
 
@@ -64,7 +64,7 @@
             WindowManager windowManager,
             Lazy<StatusBar> statusBarLazy,
             Lazy<AssistManager> assistManagerLazy,
-            Optional<Lazy<Bubbles>> bubblesOptional
+            Optional<Bubbles> bubblesOptional
     ) {
         mCommandQueue = commandQueue;
         mStatusBarStateController = statusBarStateController;
@@ -135,7 +135,7 @@
             getStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper();
             getStatusBarView().collapsePanel(true /* animate */, delayed, speedUpFactor);
         } else if (mBubblesOptional.isPresent()) {
-            mBubblesOptional.get().get().collapseStack();
+            mBubblesOptional.get().collapseStack();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index a8d4104..5c7f54b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -144,7 +144,6 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.charging.WirelessChargingAnimation;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -229,6 +228,7 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.volume.VolumeComponent;
 import com.android.systemui.wmshell.BubblesManager;
+import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.splitscreen.SplitScreen;
 
 import java.io.FileDescriptor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index b69da85..13d5bf5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -31,7 +31,6 @@
 import com.android.systemui.InitController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.UiBackground;
@@ -98,6 +97,7 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.volume.VolumeComponent;
 import com.android.systemui.wmshell.BubblesManager;
+import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.splitscreen.SplitScreen;
 
 import java.util.Optional;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt b/packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
new file mode 100644
index 0000000..7c6f86a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("VpnStatusObserver")
+
+package com.android.systemui.statusbar.tv
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import com.android.internal.messages.nano.SystemMessageProto
+import com.android.internal.net.VpnConfig
+import com.android.systemui.Dependency
+import com.android.systemui.R
+import com.android.systemui.SystemUI
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.policy.SecurityController
+import javax.inject.Inject
+
+/**
+ * Observes if a vpn connection is active and displays a notification to the user
+ */
+@SysUISingleton
+class VpnStatusObserver @Inject constructor(context: Context) : SystemUI(context),
+        SecurityController.SecurityControllerCallback {
+
+    private var vpnConnected = false
+    private val securityController: SecurityController =
+            Dependency.get(SecurityController::class.java)
+    private val notificationManager = NotificationManager.from(context)
+    private val notificationChannel = createNotificationChannel()
+    private val vpnConnectedNotificationBuilder = createVpnConnectedNotificationBuilder()
+    private val vpnDisconnectedNotification = createVpnDisconnectedNotification()
+
+    private val vpnIconId: Int
+        get() = if (securityController.isVpnBranded) {
+            R.drawable.stat_sys_branded_vpn
+        } else {
+            R.drawable.stat_sys_vpn_ic
+        }
+
+    private val vpnName: String?
+        get() = securityController.primaryVpnName ?: securityController.workProfileVpnName
+
+    override fun start() {
+        // register callback to vpn state changes
+        securityController.addCallback(this)
+    }
+
+    override fun onStateChanged() {
+        securityController.isVpnEnabled.let { newVpnConnected ->
+            if (vpnConnected != newVpnConnected) {
+                if (newVpnConnected) {
+                    notifyVpnConnected()
+                } else {
+                    notifyVpnDisconnected()
+                }
+                vpnConnected = newVpnConnected
+            }
+        }
+    }
+
+    private fun notifyVpnConnected() = notificationManager.notify(
+            NOTIFICATION_TAG,
+            SystemMessageProto.SystemMessage.NOTE_VPN_STATUS,
+            createVpnConnectedNotification()
+    )
+
+    private fun notifyVpnDisconnected() = notificationManager.run {
+        // remove existing connected notification
+        cancel(NOTIFICATION_TAG, SystemMessageProto.SystemMessage.NOTE_VPN_STATUS)
+        // show the disconnected notification only for a short while
+        notify(NOTIFICATION_TAG, SystemMessageProto.SystemMessage.NOTE_VPN_DISCONNECTED,
+                vpnDisconnectedNotification)
+    }
+
+    private fun createNotificationChannel() =
+            NotificationChannel(
+                    NOTIFICATION_CHANNEL_TV_VPN,
+                    NOTIFICATION_CHANNEL_TV_VPN,
+                    NotificationManager.IMPORTANCE_HIGH
+            ).also {
+                notificationManager.createNotificationChannel(it)
+            }
+
+    private fun createVpnConnectedNotification() =
+            vpnConnectedNotificationBuilder
+                    .apply {
+                        vpnName?.let {
+                            setContentText(
+                                    mContext.getString(
+                                            R.string.notification_disclosure_vpn_text, it
+                                    )
+                            )
+                        }
+                    }
+                    .build()
+
+    private fun createVpnConnectedNotificationBuilder() =
+            Notification.Builder(mContext, NOTIFICATION_CHANNEL_TV_VPN)
+                    .setSmallIcon(vpnIconId)
+                    .setVisibility(Notification.VISIBILITY_PUBLIC)
+                    .setCategory(Notification.CATEGORY_SYSTEM)
+                    .extend(Notification.TvExtender())
+                    .setOngoing(true)
+                    .setContentTitle(mContext.getString(R.string.notification_vpn_connected))
+                    .setContentIntent(VpnConfig.getIntentForStatusPanel(mContext))
+
+    private fun createVpnDisconnectedNotification() =
+            Notification.Builder(mContext, NOTIFICATION_CHANNEL_TV_VPN)
+                    .setSmallIcon(vpnIconId)
+                    .setVisibility(Notification.VISIBILITY_PUBLIC)
+                    .setCategory(Notification.CATEGORY_SYSTEM)
+                    .extend(Notification.TvExtender())
+                    .setTimeoutAfter(VPN_DISCONNECTED_NOTIFICATION_TIMEOUT_MS)
+                    .setContentTitle(mContext.getString(R.string.notification_vpn_disconnected))
+                    .build()
+
+    companion object {
+        const val NOTIFICATION_CHANNEL_TV_VPN = "VPN Status"
+        val NOTIFICATION_TAG: String = VpnStatusObserver::class.java.simpleName
+
+        private const val TAG = "TvVpnNotification"
+        private const val VPN_DISCONNECTED_NOTIFICATION_TIMEOUT_MS = 5_000L
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index e79d432..4b4e1df 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -26,7 +26,6 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QuickQSPanel;
-import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 
 import java.lang.reflect.InvocationTargetException;
@@ -104,11 +103,6 @@
          * Creates the QuickQSPanel.
          */
         QuickQSPanel createQuickQSPanel();
-
-        /**
-         * Creates the QSCustomizer.
-         */
-        QSCustomizer createQSCustomizer();
     }
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/util/ViewController.java b/packages/SystemUI/src/com/android/systemui/util/ViewController.java
index 880d09a..0dd5788 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/ViewController.java
@@ -76,12 +76,10 @@
         onInit();
         mInited = true;
 
-        if (mView != null) {
-            if (mView.isAttachedToWindow()) {
-                mOnAttachStateListener.onViewAttachedToWindow(mView);
-            }
-            mView.addOnAttachStateChangeListener(mOnAttachStateListener);
+        if (isAttachedToWindow()) {
+            mOnAttachStateListener.onViewAttachedToWindow(mView);
         }
+        addOnAttachStateChangeListener(mOnAttachStateListener);
     }
 
     /**
@@ -100,6 +98,17 @@
         return mView.getResources();
     }
 
+    public boolean isAttachedToWindow() {
+        return mView != null && mView.isAttachedToWindow();
+    }
+
+    /** Add an OnAttachStateListener to the view. Does nothing if the view is null. */
+    public void addOnAttachStateChangeListener(View.OnAttachStateChangeListener listener) {
+        if (mView != null) {
+            mView.addOnAttachStateChangeListener(listener);
+        }
+    }
+
     /**
      * Called when the view is attached and a call to {@link #init()} has been made in either order.
      */
@@ -109,4 +118,5 @@
      * Called when the view is detached.
      */
     protected abstract void onViewDetached();
+
 }
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index ad596c2..844f12e 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -27,10 +27,10 @@
 import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE;
 import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
 
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.app.INotificationManager;
 import android.app.Notification;
@@ -53,8 +53,6 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.Dumpable;
-import com.android.systemui.bubbles.BubbleEntry;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.model.SysUiState;
@@ -80,6 +78,8 @@
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.wm.shell.bubbles.BubbleEntry;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
index a59c876..5caab6a 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
@@ -95,8 +95,8 @@
 
     @WMSingleton
     @Provides
-    static PipBoundsState providePipBoundsState() {
-        return new PipBoundsState();
+    static PipBoundsState providePipBoundsState(Context context) {
+        return new PipBoundsState(context);
     }
 
     @WMSingleton
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index 91ae08e..bdca503 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -18,21 +18,27 @@
 
 import android.app.IActivityManager;
 import android.content.Context;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.view.IWindowManager;
+import android.view.WindowManager;
 
 import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.bubbles.Bubbles;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.dagger.WMSingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.shared.system.InputConsumerController;
 import com.android.wm.shell.ShellDump;
 import com.android.wm.shell.ShellInit;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.common.AnimationThread;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.HandlerExecutor;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
@@ -116,6 +122,18 @@
 
     @WMSingleton
     @Provides
+    static FloatingContentCoordinator provideFloatingContentCoordinator() {
+        return new FloatingContentCoordinator();
+    }
+
+    @WMSingleton
+    @Provides
+    static WindowManagerShellWrapper provideWindowManagerShellWrapper() {
+        return new WindowManagerShellWrapper();
+    }
+
+    @WMSingleton
+    @Provides
     static PipAppOpsListener providePipAppOpsListener(Context context,
             IActivityManager activityManager,
             PipTouchHandler pipTouchHandler) {
@@ -166,8 +184,21 @@
     @BindsOptionalOf
     abstract SplitScreen optionalSplitScreen();
 
-    @BindsOptionalOf
-    abstract Bubbles optionalBubbles();
+    @WMSingleton
+    @Provides
+    static Optional<Bubbles> provideBubbles(Context context,
+            FloatingContentCoordinator floatingContentCoordinator,
+            IStatusBarService statusBarService,
+            WindowManager windowManager,
+            WindowManagerShellWrapper windowManagerShellWrapper,
+            LauncherApps launcherApps,
+            UiEventLogger uiEventLogger,
+            @Main Handler mainHandler,
+            ShellTaskOrganizer organizer) {
+        return Optional.of(BubbleController.create(context, null /* synchronizer */,
+                floatingContentCoordinator, statusBarService, windowManager,
+                windowManagerShellWrapper, launcherApps, uiEventLogger, mainHandler, organizer));
+    }
 
     @WMSingleton
     @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 0f8fb7b..25ca7ad 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -93,8 +93,8 @@
 
     @WMSingleton
     @Provides
-    static PipBoundsState providePipBoundsState() {
-        return new PipBoundsState();
+    static PipBoundsState providePipBoundsState(Context context) {
+        return new PipBoundsState(context);
     }
 
     @WMSingleton
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index e5847b0..f1c687f 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -63,7 +63,7 @@
             </intent-filter>
         </receiver>
 
-        <activity android:name="com.android.systemui.bubbles.BubblesTestActivity"
+        <activity android:name=".wmshell.BubblesTestActivity"
             android:allowEmbedded="true"
             android:documentLaunchMode="always"
             android:excludeFromRecents="true"
diff --git a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
index 594f0b1..cbd6e86 100644
--- a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
+++ b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
@@ -116,6 +116,13 @@
         filter.add(s -> s.startsWith("com.android.systemui")
                 || s.startsWith("com.android.keyguard"));
 
+        // Screenshots run in an isolated process and should not be run
+        // with the main process dependency graph because it will not exist
+        // at runtime and could lead to incorrect tests which assume
+        // the main SystemUI process. Therefore, exclude this package
+        // from the base class whitelist.
+        filter.add(s -> !s.startsWith("com.android.systemui.screenshot"));
+
         try {
             return scanner.getClassPathEntries(filter);
         } catch (IOException e) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index caab2ab..d78090a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -201,7 +201,7 @@
         when(mTelephonyManager.getServiceStateForSubscriber(anyInt()))
                 .thenReturn(new ServiceState());
         when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings);
-        when(mAuthController.isUdfpsEnrolled()).thenReturn(false);
+        when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
         mSpiedContext.addMockSystemService(TrustManager.class, mTrustManager);
         mSpiedContext.addMockSystemService(FingerprintManager.class, mFingerprintManager);
         mSpiedContext.addMockSystemService(BiometricManager.class, mBiometricManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 0c87f59..59262cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -64,6 +64,8 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.settings.FakeSettings;
+import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -84,6 +86,7 @@
     private ScreenDecorations mScreenDecorations;
     private WindowManager mWindowManager;
     private DisplayManager mDisplayManager;
+    private SecureSettings mSecureSettings;
     private Handler mMainHandler;
     @Mock
     private TunerService mTunerService;
@@ -98,6 +101,7 @@
 
         mTestableLooper = TestableLooper.get(this);
         mMainHandler = new Handler(mTestableLooper.getLooper());
+        mSecureSettings = new FakeSettings();
 
         mWindowManager = mock(WindowManager.class);
         WindowMetrics metrics = mContext.getSystemService(WindowManager.class)
@@ -111,7 +115,7 @@
         when(mDisplayManager.getDisplay(anyInt())).thenReturn(display);
         mContext.addMockSystemService(DisplayManager.class, mDisplayManager);
 
-        mScreenDecorations = spy(new ScreenDecorations(mContext, mMainHandler,
+        mScreenDecorations = spy(new ScreenDecorations(mContext, mMainHandler, mSecureSettings,
                 mBroadcastDispatcher, mTunerService, mUserTracker) {
             @Override
             public void start() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index a39bc70..f28322f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -275,6 +275,7 @@
 
     @Test
     public void performA11yActions_visible_expectedResults() {
+        final int displayId = mContext.getDisplayId();
         mInstrumentation.runOnMainSync(() -> {
             mWindowMagnificationController.enableWindowMagnification(2.5f, Float.NaN,
                     Float.NaN);
@@ -284,10 +285,10 @@
         assertTrue(
                 mMirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_out, null));
         // Minimum scale is 2.0.
-        assertEquals(2.0f, mWindowMagnificationController.getScale(), 0f);
+        verify(mWindowMagnifierCallback).onPerformScaleAction(eq(displayId), eq(2.0f));
 
         assertTrue(mMirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_in, null));
-        assertEquals(3.0f, mWindowMagnificationController.getScale(), 0f);
+        verify(mWindowMagnifierCallback).onPerformScaleAction(eq(displayId), eq(3.5f));
 
         // TODO: Verify the final state when the mirror surface is visible.
         assertTrue(mMirrorView.performAccessibilityAction(R.id.accessibility_action_move_up, null));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
index 4a0e216..ad1ce76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
 
@@ -42,7 +43,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
@@ -56,6 +56,8 @@
     private ModeSwitchesController mModeSwitchesController;
     @Mock
     private NavigationModeController mNavigationModeController;
+    @Mock
+    private IWindowMagnificationConnectionCallback mConnectionCallback;
     private CommandQueue mCommandQueue;
     private WindowMagnification mWindowMagnification;
 
@@ -63,6 +65,12 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         getContext().addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
+        doAnswer(invocation -> {
+            IWindowMagnificationConnection connection = invocation.getArgument(0);
+            connection.setConnectionCallback(mConnectionCallback);
+            return null;
+        }).when(mAccessibilityManager).setWindowMagnificationConnection(
+                any(IWindowMagnificationConnection.class));
 
         mCommandQueue = new CommandQueue(getContext());
         mWindowMagnification = new WindowMagnification(getContext(),
@@ -87,25 +95,29 @@
 
     @Test
     public void onWindowMagnifierBoundsChanged() throws RemoteException {
-        final IWindowMagnificationConnectionCallback connectionCallback = Mockito.mock(
-                IWindowMagnificationConnectionCallback.class);
         final Rect testBounds = new Rect(0, 0, 500, 600);
-        doAnswer(invocation -> {
-            IWindowMagnificationConnection connection = invocation.getArgument(0);
-            connection.setConnectionCallback(connectionCallback);
-            return null;
-        }).when(mAccessibilityManager).setWindowMagnificationConnection(
-                any(IWindowMagnificationConnection.class));
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
 
         mWindowMagnification.onWindowMagnifierBoundsChanged(Display.DEFAULT_DISPLAY, testBounds);
 
-        verify(connectionCallback).onWindowMagnifierBoundsChanged(Display.DEFAULT_DISPLAY,
+        verify(mConnectionCallback).onWindowMagnifierBoundsChanged(Display.DEFAULT_DISPLAY,
                 testBounds);
     }
 
     @Test
+    public void onPerformScaleAction_enabled_notifyCallback() throws RemoteException {
+        final float newScale = 4.0f;
+        mCommandQueue.requestWindowMagnificationConnection(true);
+        waitForIdleSync();
+
+        mWindowMagnification.onPerformScaleAction(Display.DEFAULT_DISPLAY, newScale);
+
+        verify(mConnectionCallback).onPerformScaleAction(eq(Display.DEFAULT_DISPLAY),
+                eq(newScale));
+    }
+
+    @Test
     public void onConfigurationChanged_updateModeSwitches() {
         final Configuration config = new Configuration();
         config.densityDpi = Configuration.DENSITY_DPI_ANY;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ToggleRangeTemplateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ToggleRangeTemplateTest.kt
new file mode 100644
index 0000000..31e0954
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ToggleRangeTemplateTest.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.controls.ui
+
+import android.service.controls.templates.RangeTemplate
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ToggleRangeTemplateTest : SysuiTestCase() {
+
+    @Test
+    fun testLargeRangeNearestStep() {
+        val trt = ToggleRangeBehavior()
+        trt.rangeTemplate = RangeTemplate("range", -100000f, 100000f, 0f, 5f, null)
+
+        assertEquals(255f, trt.findNearestStep(253f), 0.1f)
+    }
+
+    @Test
+    fun testLargeRangeNearestStepWithNegativeValues() {
+        val trt = ToggleRangeBehavior()
+        trt.rangeTemplate = RangeTemplate("range", -100000f, 100000f, 0f, 5f, null)
+
+        assertEquals(-7855f, trt.findNearestStep(-7853.2f), 0.1f)
+    }
+
+    @Test
+    fun testFractionalRangeNearestStep() {
+        val trt = ToggleRangeBehavior()
+        trt.rangeTemplate = RangeTemplate("range", 10f, 11f, 10f, .01f, null)
+
+        assertEquals(10.54f, trt.findNearestStep(10.543f), 0.01f)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
index 3494bd6..fa29fd4f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
@@ -49,7 +49,6 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.recents.OverviewProxyService;
 
 import org.junit.Before;
@@ -66,7 +65,6 @@
 
     private KeyButtonView mKeyButtonView;
     private MetricsLogger mMetricsLogger;
-    private Bubbles mBubbles;
     private UiEventLogger mUiEventLogger;
     private InputManager mInputManager = mock(InputManager.class);
     @Captor
@@ -76,7 +74,6 @@
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
         mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
-        mBubbles = mDependency.injectMockDependency(Bubbles.class);
         mDependency.injectMockDependency(OverviewProxyService.class);
         mUiEventLogger = mDependency.injectMockDependency(UiEventLogger.class);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
index 8039192..c050b62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -52,7 +52,7 @@
 
     private MetricsLogger mMetricsLogger;
     private QSDetail mQsDetail;
-    private QSPanel mQsPanel;
+    private QSPanelController mQsPanelController;
     private QuickStatusBarHeader mQuickHeader;
     private ActivityStarter mActivityStarter;
     private DetailAdapter mMockDetailAdapter;
@@ -68,9 +68,9 @@
             mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
             mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
             mQsDetail = (QSDetail) LayoutInflater.from(mContext).inflate(R.layout.qs_detail, null);
-            mQsPanel = mock(QSPanel.class);
+            mQsPanelController = mock(QSPanelController.class);
             mQuickHeader = mock(QuickStatusBarHeader.class);
-            mQsDetail.setQsPanel(mQsPanel, mQuickHeader, mock(QSFooter.class));
+            mQsDetail.setQsPanel(mQsPanelController, mQuickHeader, mock(QSFooter.class));
 
             mMockDetailAdapter = mock(DetailAdapter.class);
             when(mMockDetailAdapter.createDetailView(any(), any(), any()))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
index 065f236..2dfd388 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
@@ -40,6 +40,7 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.phone.MultiUserSwitch;
 import com.android.systemui.statusbar.phone.SettingsButton;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.UserInfoController;
@@ -75,6 +76,8 @@
     private QSPanelController mQSPanelController;
     @Mock
     private ClipboardManager mClipboardManager;
+    @Mock
+    private QuickQSPanelController mQuickQSPanelController;
     private FakeTunerService mFakeTunerService;
     private MetricsLogger mMetricsLogger = new FakeMetricsLogger();
 
@@ -84,6 +87,8 @@
     private TextView mBuildText;
     @Mock
     private View mEdit;
+    @Mock
+    private MultiUserSwitch mMultiUserSwitch;
 
     private QSFooterViewController mController;
 
@@ -105,10 +110,12 @@
         when(mView.findViewById(R.id.settings_button)).thenReturn(mSettingsButton);
         when(mView.findViewById(R.id.build)).thenReturn(mBuildText);
         when(mView.findViewById(android.R.id.edit)).thenReturn(mEdit);
+        when(mView.findViewById(R.id.multi_user_switch)).thenReturn(mMultiUserSwitch);
 
         mController = new QSFooterViewController(mView, mUserManager, mUserInfoController,
                 mActivityStarter, mDeviceProvisionedController, mUserTracker, mQSPanelController,
-                mFakeTunerService, mMetricsLogger);
+                new QSDetailDisplayer(), mQuickQSPanelController, mFakeTunerService,
+                mMetricsLogger);
 
         mController.init();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 90609cc..858ecdc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -167,6 +167,7 @@
                 mock(QSTileHost.class),
                 mock(StatusBarStateController.class),
                 commandQueue,
+                new QSDetailDisplayer(),
                 mQsComponentFactory);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index bf0e084..9421cd0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -19,9 +19,12 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -38,6 +41,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.MediaHost;
 import com.android.systemui.plugins.qs.QSTileView;
+import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
 import org.junit.Before;
@@ -61,6 +65,12 @@
     @Mock
     private QSTileHost mQSTileHost;
     @Mock
+    private QSCustomizerController mQSCustomizerController;
+    @Mock
+    private QSTileRevealController.Factory mQSTileRevealControllerFactory;
+    @Mock
+    private QSTileRevealController mQSTileRevealController;
+    @Mock
     private MediaHost mMediaHost;
     @Mock
     private MetricsLogger mMetricsLogger;
@@ -70,15 +80,19 @@
     QSTileImpl mQSTile;
     @Mock
     QSTileView mQSTileView;
+    @Mock
+    PagedTileLayout mPagedTileLayout;
 
     private QSPanelControllerBase<QSPanel> mController;
 
     /** Implementation needed to ensure we have a reflectively-available class name. */
     private static class TestableQSPanelControllerBase extends QSPanelControllerBase<QSPanel> {
         protected TestableQSPanelControllerBase(QSPanel view, QSTileHost host,
-                MetricsLogger metricsLogger,
-                UiEventLogger uiEventLogger, DumpManager dumpManager) {
-            super(view, host, metricsLogger, uiEventLogger, dumpManager);
+                QSCustomizerController qsCustomizerController,
+                QSTileRevealController.Factory qsTileRevealControllerFactory,
+                MetricsLogger metricsLogger, UiEventLogger uiEventLogger, DumpManager dumpManager) {
+            super(view, host, qsCustomizerController, qsTileRevealControllerFactory, metricsLogger,
+                    uiEventLogger, dumpManager);
         }
     }
 
@@ -91,16 +105,51 @@
         when(mQSPanel.getDumpableTag()).thenReturn("QSPanel");
         when(mQSPanel.openPanelEvent()).thenReturn(QSEvent.QS_PANEL_EXPANDED);
         when(mQSPanel.closePanelEvent()).thenReturn(QSEvent.QS_PANEL_COLLAPSED);
+        when(mQSPanel.createRegularTileLayout()).thenReturn(mPagedTileLayout);
         when(mQSTileHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
         when(mQSTileHost.createTileView(eq(mQSTile), anyBoolean())).thenReturn(mQSTileView);
+        when(mQSTileRevealControllerFactory.create(any())).thenReturn(mQSTileRevealController);
 
         mController = new TestableQSPanelControllerBase(mQSPanel, mQSTileHost,
-                mMetricsLogger, mUiEventLogger, mDumpManager);
+                mQSCustomizerController, mQSTileRevealControllerFactory, mMetricsLogger,
+                mUiEventLogger, mDumpManager);
 
         mController.init();
+        reset(mQSTileRevealController);
     }
 
     @Test
+    public void testSetRevealExpansion_preAttach() {
+        mController.onViewDetached();
+
+        QSPanelControllerBase<QSPanel> controller = new TestableQSPanelControllerBase(mQSPanel,
+                mQSTileHost, mQSCustomizerController, mQSTileRevealControllerFactory,
+                mMetricsLogger, mUiEventLogger, mDumpManager);
+
+        // Nothing happens until attached
+        controller.setRevealExpansion(0);
+        verify(mQSTileRevealController, never()).setExpansion(anyFloat());
+        controller.setRevealExpansion(0.5f);
+        verify(mQSTileRevealController, never()).setExpansion(anyFloat());
+        controller.setRevealExpansion(1);
+        verify(mQSTileRevealController, never()).setExpansion(anyFloat());
+
+        controller.init();
+        verify(mQSTileRevealController).setExpansion(1);
+    }
+
+    @Test
+    public void testSetRevealExpansion_postAttach() {
+        mController.setRevealExpansion(0);
+        verify(mQSTileRevealController).setExpansion(0);
+        mController.setRevealExpansion(0.5f);
+        verify(mQSTileRevealController).setExpansion(0.5f);
+        mController.setRevealExpansion(1);
+        verify(mQSTileRevealController).setExpansion(1);
+    }
+
+
+    @Test
     public void testSetExpanded_Metrics() {
         mController.setExpanded(true);
         verify(mMetricsLogger).visibility(eq(MetricsEvent.QS_PANEL), eq(true));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
index 0ba0214..bce376a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
@@ -35,6 +35,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.MediaHost;
 import com.android.systemui.plugins.qs.QSTileView;
+import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.settings.BrightnessController;
 import com.android.systemui.settings.ToggleSlider;
@@ -58,6 +59,12 @@
     @Mock
     private QSTileHost mQSTileHost;
     @Mock
+    private QSCustomizerController mQSCustomizerController;
+    @Mock
+    private QSTileRevealController.Factory mQSTileRevealControllerFactory;
+    @Mock
+    private QSTileRevealController mQSTileRevealController;
+    @Mock
     private MediaHost mMediaHost;
     @Mock
     private MetricsLogger mMetricsLogger;
@@ -75,6 +82,9 @@
     QSTileImpl mQSTile;
     @Mock
     QSTileView mQSTileView;
+    @Mock
+    PagedTileLayout mPagedTileLayout;
+
 
     private QSPanelController mController;
 
@@ -85,14 +95,16 @@
         when(mQSPanel.getMediaHost()).thenReturn(mMediaHost);
         when(mQSPanel.isAttachedToWindow()).thenReturn(true);
         when(mQSPanel.getDumpableTag()).thenReturn("QSPanel");
+        when(mQSPanel.createRegularTileLayout()).thenReturn(mPagedTileLayout);
         when(mQSTileHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
         when(mQSTileHost.createTileView(eq(mQSTile), anyBoolean())).thenReturn(mQSTileView);
         when(mBrightnessControllerFactory.create(any(ToggleSlider.class)))
                 .thenReturn(mBrightnessController);
+        when(mQSTileRevealControllerFactory.create(any())).thenReturn(mQSTileRevealController);
 
         mController = new QSPanelController(mQSPanel, mQSSecurityFooter, mTunerService,
-                mQSTileHost, mDumpManager, mMetricsLogger, mUiEventLogger,
-                mBrightnessControllerFactory);
+                mQSTileHost, mQSCustomizerController, mQSTileRevealControllerFactory, mDumpManager,
+                mMetricsLogger, mUiEventLogger, mBrightnessControllerFactory);
 
         mController.init();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index e38d54b..450ffac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -39,7 +39,6 @@
 import com.android.systemui.media.MediaHost;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTileView;
-import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.SecurityController;
@@ -65,12 +64,8 @@
     @Mock
     private QSTileHost mHost;
     @Mock
-    private QSCustomizer mCustomizer;
-    @Mock
     private QSTileImpl dndTile;
     @Mock
-    private QSTileImpl mNonTile;
-    @Mock
     private QSPanelControllerBase.TileRecord mDndTileRecord;
     @Mock
     private QSLogger mQSLogger;
@@ -84,7 +79,6 @@
     @Mock
     private ActivityStarter mActivityStarter;
     private UiEventLoggerFake mUiEventLogger;
-    private String mCachedSpecs = "";
 
     @Before
     public void setup() throws Exception {
@@ -113,8 +107,6 @@
             when(dndTile.getTileSpec()).thenReturn("dnd");
             when(mHost.getTiles()).thenReturn(Collections.emptyList());
             when(mHost.createTileView(any(), anyBoolean())).thenReturn(mQSTileView);
-
-            mQsPanel.setCustomizer(mCustomizer);
             mQsPanel.addTile(mDndTileRecord);
             mQsPanel.setCallback(mCallback);
         });
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/SecureSettingTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/SecureSettingTest.kt
new file mode 100644
index 0000000..418fa61
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/SecureSettingTest.kt
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.qs
+
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.settings.FakeSettings
+import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.fail
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private typealias Callback = (Int, Boolean) -> Unit
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class SecureSettingTest : SysuiTestCase() {
+
+    companion object {
+        private const val TEST_SETTING = "setting"
+        private const val USER = 0
+        private const val OTHER_USER = 1
+        private val FAIL_CALLBACK: Callback = { _, _ -> fail("Callback should not be called") }
+    }
+
+    private lateinit var testableLooper: TestableLooper
+    private lateinit var setting: SecureSetting
+    private lateinit var secureSettings: SecureSettings
+
+    private lateinit var callback: Callback
+
+    @Before
+    fun setUp() {
+        testableLooper = TestableLooper.get(this)
+        secureSettings = FakeSettings()
+
+        setting = object : SecureSetting(
+                secureSettings,
+                Handler(testableLooper.looper),
+                TEST_SETTING,
+                USER
+        ) {
+            override fun handleValueChanged(value: Int, observedChange: Boolean) {
+                callback(value, observedChange)
+            }
+        }
+
+        // Default empty callback
+        callback = { _, _ -> Unit }
+    }
+
+    @After
+    fun tearDown() {
+        setting.isListening = false
+    }
+
+    @Test
+    fun testNotListeningByDefault() {
+        callback = FAIL_CALLBACK
+
+        assertThat(setting.isListening).isFalse()
+        secureSettings.putIntForUser(TEST_SETTING, 2, USER)
+        testableLooper.processAllMessages()
+    }
+
+    @Test
+    fun testChangedWhenListeningCallsCallback() {
+        var changed = false
+        callback = { _, _ -> changed = true }
+
+        setting.isListening = true
+        secureSettings.putIntForUser(TEST_SETTING, 2, USER)
+        testableLooper.processAllMessages()
+
+        assertThat(changed).isTrue()
+    }
+
+    @Test
+    fun testListensToCorrectSetting() {
+        callback = FAIL_CALLBACK
+
+        setting.isListening = true
+        secureSettings.putIntForUser("other", 2, USER)
+        testableLooper.processAllMessages()
+    }
+
+    @Test
+    fun testGetCorrectValue() {
+        secureSettings.putIntForUser(TEST_SETTING, 2, USER)
+        assertThat(setting.value).isEqualTo(2)
+
+        secureSettings.putIntForUser(TEST_SETTING, 4, USER)
+        assertThat(setting.value).isEqualTo(4)
+    }
+
+    @Test
+    fun testSetValue() {
+        setting.value = 5
+        assertThat(secureSettings.getIntForUser(TEST_SETTING, USER)).isEqualTo(5)
+    }
+
+    @Test
+    fun testChangeUser() {
+        setting.isListening = true
+        setting.setUserId(OTHER_USER)
+
+        setting.isListening = true
+        assertThat(setting.currentUser).isEqualTo(OTHER_USER)
+    }
+
+    @Test
+    fun testDoesntListenInOtherUsers() {
+        callback = FAIL_CALLBACK
+        setting.isListening = true
+
+        secureSettings.putIntForUser(TEST_SETTING, 3, OTHER_USER)
+        testableLooper.processAllMessages()
+    }
+
+    @Test
+    fun testListensToCorrectUserAfterChange() {
+        var changed = false
+        callback = { _, _ -> changed = true }
+
+        setting.isListening = true
+        setting.setUserId(OTHER_USER)
+        secureSettings.putIntForUser(TEST_SETTING, 2, OTHER_USER)
+        testableLooper.processAllMessages()
+
+        assertThat(changed).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
index 204de929..3d53062 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
@@ -15,7 +15,6 @@
 package com.android.systemui.qs.customize;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.testing.AndroidTestingRunner;
@@ -31,6 +30,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.Collections;
 
@@ -40,17 +41,20 @@
 public class TileAdapterTest extends SysuiTestCase {
 
     private TileAdapter mTileAdapter;
+    @Mock
+    private QSTileHost mQSTileHost;
 
     @Before
     public void setup() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
         TestableLooper.get(this).runWithLooper(() -> mTileAdapter =
-                new TileAdapter(mContext, new UiEventLoggerFake()));
+                new TileAdapter(mContext, mQSTileHost, new UiEventLoggerFake()));
     }
 
     @Test
     public void testResetNotifiesHost() {
-        QSTileHost host = mock(QSTileHost.class);
-        mTileAdapter.resetTileSpecs(host, Collections.emptyList());
-        verify(host).changeTiles(any(), any());
+        mTileAdapter.resetTileSpecs(Collections.emptyList());
+        verify(mQSTileHost).changeTiles(any(), any());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
index 2006a75..bcfc835 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
@@ -29,6 +29,8 @@
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.statusbar.policy.BatteryController
+import com.android.systemui.util.settings.FakeSettings
+import com.android.systemui.util.settings.SecureSettings
 import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
@@ -60,6 +62,7 @@
     private lateinit var qsLogger: QSLogger
     @Mock
     private lateinit var batteryController: BatteryController
+    private lateinit var secureSettings: SecureSettings
     private lateinit var testableLooper: TestableLooper
     private lateinit var tile: BatterySaverTile
 
@@ -70,6 +73,8 @@
         `when`(qsHost.userContext).thenReturn(userContext)
         `when`(userContext.userId).thenReturn(USER)
 
+        secureSettings = FakeSettings()
+
         tile = BatterySaverTile(
                 qsHost,
                 testableLooper.looper,
@@ -78,7 +83,8 @@
                 statusBarStateController,
                 activityStarter,
                 qsLogger,
-                batteryController)
+                batteryController,
+                secureSettings)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
index de176b8..9a1126f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
@@ -24,14 +24,12 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.app.PendingIntent;
 import android.content.Context;
@@ -54,8 +52,6 @@
 
 import java.util.Optional;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
 @RunWith(AndroidTestingRunner.class)
@@ -67,8 +63,6 @@
     @Mock
     private ActivityManagerWrapper mMockActivityManagerWrapper;
     @Mock
-    private Future mMockFuture;
-    @Mock
     private ScreenshotSmartActions mMockScreenshotSmartActions;
     @Mock
     private PendingIntent mMockPendingIntent;
@@ -80,9 +74,6 @@
         MockitoAnnotations.initMocks(this);
         mIntent = new Intent(mContext, ActionProxyReceiver.class)
                 .putExtra(ScreenshotController.EXTRA_ACTION_INTENT, mMockPendingIntent);
-
-        when(mMockActivityManagerWrapper.closeSystemWindows(anyString())).thenReturn(mMockFuture);
-        when(mMockFuture.get(anyLong(), any(TimeUnit.class))).thenReturn(null);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java
new file mode 100644
index 0000000..a75c39c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeScrollCaptureConnection.java
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.screenshot;
+
+import android.content.pm.ActivityInfo;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.HardwareRenderer;
+import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.Rect;
+import android.graphics.RenderNode;
+import android.os.RemoteException;
+import android.view.IScrollCaptureCallbacks;
+import android.view.IScrollCaptureConnection;
+import android.view.Surface;
+
+/**
+ * An IScrollCaptureConnection which returns a sequence of solid filled rectangles in the
+ * locations requested, in alternating colors.
+ */
+class FakeScrollCaptureConnection extends IScrollCaptureConnection.Stub {
+    private final int[] mColors = {Color.RED, Color.GREEN, Color.BLUE};
+    private IScrollCaptureCallbacks mCallbacks;
+    private Surface mSurface;
+    private Paint mPaint;
+    private int mNextColor;
+    private HwuiContext mHwuiContext;
+
+    FakeScrollCaptureConnection(IScrollCaptureCallbacks cb) {
+        mCallbacks = cb;
+    }
+
+    @Override
+    public void startCapture(Surface surface) {
+        mSurface = surface;
+        mHwuiContext = new HwuiContext(false, surface);
+        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPaint.setStyle(Paint.Style.FILL);
+        try {
+            mCallbacks.onCaptureStarted();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    @Override
+    public void requestImage(Rect rect) {
+        Canvas canvas = mHwuiContext.lockCanvas(rect.width(), rect.height());
+        mPaint.setColor(mColors[mNextColor]);
+        canvas.drawRect(rect, mPaint);
+        mNextColor = (mNextColor++) % mColors.length;
+        long frameNumber = mSurface.getNextFrameNumber();
+        mHwuiContext.unlockAndPost(canvas);
+        try {
+            mCallbacks.onCaptureBufferSent(frameNumber, rect);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    @Override
+    public void endCapture() {
+        try {
+            mCallbacks.onConnectionClosed();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        } finally {
+            mHwuiContext.destroy();
+            mSurface = null;
+            mCallbacks = null;
+        }
+    }
+
+    // From android.view.Surface, but issues render requests synchronously with waitForPresent(true)
+    private static final class HwuiContext {
+        private final RenderNode mRenderNode;
+        private final HardwareRenderer mHardwareRenderer;
+        private RecordingCanvas mCanvas;
+        private final boolean mIsWideColorGamut;
+
+        HwuiContext(boolean isWideColorGamut, Surface surface) {
+            mRenderNode = RenderNode.create("HwuiCanvas", null);
+            mRenderNode.setClipToBounds(false);
+            mRenderNode.setForceDarkAllowed(false);
+            mIsWideColorGamut = isWideColorGamut;
+
+            mHardwareRenderer = new HardwareRenderer();
+            mHardwareRenderer.setContentRoot(mRenderNode);
+            mHardwareRenderer.setSurface(surface, true);
+            mHardwareRenderer.setColorMode(
+                    isWideColorGamut
+                            ? ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT
+                            : ActivityInfo.COLOR_MODE_DEFAULT);
+            mHardwareRenderer.setLightSourceAlpha(0.0f, 0.0f);
+            mHardwareRenderer.setLightSourceGeometry(0.0f, 0.0f, 0.0f, 0.0f);
+        }
+
+        Canvas lockCanvas(int width, int height) {
+            if (mCanvas != null) {
+                throw new IllegalStateException("Surface was already locked!");
+            }
+            mCanvas = mRenderNode.beginRecording(width, height);
+            return mCanvas;
+        }
+
+        void unlockAndPost(Canvas canvas) {
+            if (canvas != mCanvas) {
+                throw new IllegalArgumentException("canvas object must be the same instance that "
+                        + "was previously returned by lockCanvas");
+            }
+            mRenderNode.endRecording();
+            mCanvas = null;
+            mHardwareRenderer.createRenderRequest()
+                    .setVsyncTime(System.nanoTime())
+                    .setWaitForPresent(true) // sync!
+                    .syncAndDraw();
+        }
+
+        void destroy() {
+            mHardwareRenderer.destroy();
+        }
+
+        boolean isWideColorGamut() {
+            return mIsWideColorGamut;
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java
new file mode 100644
index 0000000..4aa730e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.screenshot;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import static java.util.Objects.requireNonNull;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.os.RemoteException;
+import android.testing.AndroidTestingRunner;
+import android.view.Display;
+import android.view.IScrollCaptureCallbacks;
+import android.view.IWindowManager;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.screenshot.ScrollCaptureClient.CaptureResult;
+import com.android.systemui.screenshot.ScrollCaptureClient.Connection;
+import com.android.systemui.screenshot.ScrollCaptureClient.Session;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.mockito.stubbing.Answer;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class ScrollCaptureClientTest extends SysuiTestCase {
+    private Context mContext;
+    private IWindowManager mWm;
+
+    @Spy private TestableConsumer<Session> mSessionConsumer;
+    @Spy private TestableConsumer<Connection> mConnectionConsumer;
+    @Spy private TestableConsumer<CaptureResult> mResultConsumer;
+    @Mock private Runnable mRunnable;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        DisplayManager displayManager = requireNonNull(
+                context.getSystemService(DisplayManager.class));
+        mContext = context.createDisplayContext(
+                displayManager.getDisplay(Display.DEFAULT_DISPLAY));
+        mWm = mock(IWindowManager.class);
+    }
+
+    @Test
+    public void testBasicClientFlow() throws RemoteException {
+        doAnswer((Answer<Void>) invocation -> {
+            IScrollCaptureCallbacks cb = invocation.getArgument(3);
+            cb.onConnected(
+                    new FakeScrollCaptureConnection(cb),
+                    /* scrollBounds */ new Rect(0, 0, 100, 100),
+                    /* positionInWindow */ new Point(0, 0));
+            return null;
+        }).when(mWm).requestScrollCapture(/* displayId */ anyInt(), /* token */  isNull(),
+                /* taskId */ anyInt(), any(IScrollCaptureCallbacks.class));
+
+        // Create client
+        ScrollCaptureClient client = new ScrollCaptureClient(mContext, mWm);
+
+        client.request(Display.DEFAULT_DISPLAY, mConnectionConsumer);
+        verify(mConnectionConsumer, timeout(100)).accept(any(Connection.class));
+
+        Connection conn = mConnectionConsumer.getValue();
+
+        conn.start(5, mSessionConsumer);
+        verify(mSessionConsumer, timeout(100)).accept(any(Session.class));
+
+        Session session = mSessionConsumer.getValue();
+        Rect request = new Rect(0, 0, session.getMaxTileWidth(), session.getMaxTileHeight());
+
+        session.requestTile(request, mResultConsumer);
+        verify(mResultConsumer, timeout(100)).accept(any(CaptureResult.class));
+
+        CaptureResult result = mResultConsumer.getValue();
+        assertThat(result.requested).isEqualTo(request);
+        assertThat(result.captured).isEqualTo(result.requested);
+        assertThat(result.image).isNotNull();
+
+        session.end(mRunnable);
+        verify(mRunnable, timeout(100)).run();
+
+        // TODO verify image
+        // TODO test threading
+        // TODO test failures
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TestableConsumer.java
similarity index 63%
copy from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
copy to packages/SystemUI/tests/src/com/android/systemui/screenshot/TestableConsumer.java
index 24768cd..a554e5f 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TestableConsumer.java
@@ -13,17 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
 
-import android.annotation.DimenRes
-import android.annotation.UserIdInt
+package com.android.systemui.screenshot;
 
-data class BubbleEntity(
-    @UserIdInt val userId: Int,
-    val packageName: String,
-    val shortcutId: String,
-    val key: String,
-    val desiredHeight: Int,
-    @DimenRes val desiredHeightResId: Int,
-    val title: String? = null
-)
+import java.util.function.Consumer;
+
+/** Accepts and retains the most recent value for verification */
+class TestableConsumer<T> implements Consumer<T> {
+    T mValue;
+
+    @Override
+    public void accept(T t) {
+        mValue = t;
+    }
+
+    public T getValue() {
+        return mValue;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 10eca00..7fb7b86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -36,7 +36,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
 import com.android.systemui.statusbar.notification.DynamicChildBindController;
@@ -54,6 +53,7 @@
 import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import com.google.android.collect.Lists;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
index cd46dda..05cf33a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
@@ -42,7 +42,6 @@
 
 import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.media.MediaFeatureFlag;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -54,6 +53,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
 import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 4698b8e..f7dfe0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -76,12 +76,12 @@
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.BubblesTestActivity;
 import com.android.systemui.statusbar.SbnBuilder;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.wmshell.BubblesManager;
+import com.android.systemui.wmshell.BubblesTestActivity;
 
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index b482968..4a2cbcc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -860,6 +860,33 @@
     }
 
     @Test
+    public void testHandleCloseControls_persistAutomatic()
+            throws Exception {
+        mNotificationChannel.unlockFields(USER_LOCKED_IMPORTANCE);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mOnUserInteractionCallback,
+                mChannelEditorDialogController,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mEntry,
+                null,
+                null,
+                mUiEventLogger,
+                true,
+                false,
+                true,
+                true);
+
+        mNotificationInfo.handleCloseControls(true, false);
+        mTestableLooper.processAllMessages();
+        verify(mMockINotificationManager, times(1)).unlockNotificationChannel(
+                anyString(), eq(TEST_UID), any());
+    }
+
+    @Test
     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
             throws Exception {
         int originalImportance = mNotificationChannel.getImportance();
@@ -1015,16 +1042,17 @@
                 mUiEventLogger,
                 true,
                 false,
-                false,
-                false);
+                true,
+                true);
 
         mNotificationInfo.findViewById(R.id.automatic).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
         mNotificationInfo.handleCloseControls(true, false);
 
         mTestableLooper.processAllMessages();
-        assertTrue(mNotificationChannel.hasUserSetImportance());
-        assertEquals(mNotificationChannel.getImportance(), IMPORTANCE_DEFAULT);
+        verify(mMockINotificationManager, times(1)).unlockNotificationChannel(
+                anyString(), eq(TEST_UID), any());
+        assertEquals(IMPORTANCE_DEFAULT, mNotificationChannel.getImportance());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 48375e0..baae8fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -45,8 +45,6 @@
 
 import com.android.systemui.R;
 import com.android.systemui.TestableDependency;
-import com.android.systemui.bubbles.Bubbles;
-import com.android.systemui.bubbles.BubblesTestActivity;
 import com.android.systemui.media.MediaFeatureFlag;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
 import com.android.systemui.plugins.FalsingManager;
@@ -71,6 +69,8 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.InflatedSmartReplies;
 import com.android.systemui.wmshell.BubblesManager;
+import com.android.systemui.wmshell.BubblesTestActivity;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import org.mockito.ArgumentCaptor;
 
@@ -432,7 +432,8 @@
                 mStatusBarStateController,
                 mPeopleNotificationIdentifier,
                 mock(OnUserInteractionCallback.class),
-                Optional.of(mock(BubblesManager.class)));
+                Optional.of(mock(BubblesManager.class)),
+                mock(NotificationGutsManager.class));
 
         row.setAboveShelfChangedListener(aboveShelf -> { });
         mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 3ebb77a..82d1f43 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -22,31 +22,22 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.isNotNull;
 import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.content.ContextWrapper;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.NightDisplayListener;
 import android.os.Handler;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
-import android.testing.TestableContentResolver;
-import android.testing.TestableContext;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
@@ -61,6 +52,8 @@
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.util.settings.FakeSettings;
+import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.After;
 import org.junit.Before;
@@ -100,10 +93,12 @@
     @Mock private Context mUserContext;
 
     private AutoTileManager mAutoTileManager;
+    private SecureSettings mSecureSettings;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        mSecureSettings = new FakeSettings();
 
         mContext.getOrCreateTestableResources().addOverride(
                 R.array.config_quickSettingsAutoAdd,
@@ -119,7 +114,7 @@
         when(mQsTileHost.getUserContext()).thenReturn(mUserContext);
         when(mUserContext.getUser()).thenReturn(UserHandle.of(USER));
 
-        mAutoTileManager = createAutoTileManager(new MyContextWrapper(mContext));
+        mAutoTileManager = createAutoTileManager(mContext);
         mAutoTileManager.init();
     }
 
@@ -138,6 +133,7 @@
             CastController castController) {
         return new AutoTileManager(context, autoAddTrackerBuilder, mQsTileHost,
                 Handler.createAsync(TestableLooper.get(this).getLooper()),
+                mSecureSettings,
                 hotspotController,
                 dataSaverController,
                 managedProfileController,
@@ -342,7 +338,6 @@
     @Test
     public void testSettingTileAdded_onChanged() {
         changeValue(TEST_SETTING, 1);
-        waitForIdleSync();
         verify(mAutoAddTracker).setTileAdded(TEST_SPEC);
         verify(mQsTileHost).addTile(TEST_SPEC);
     }
@@ -350,7 +345,6 @@
     @Test
     public void testSettingTileAddedComponentAtEnd_onChanged() {
         changeValue(TEST_SETTING_COMPONENT, 1);
-        waitForIdleSync();
         verify(mAutoAddTracker).setTileAdded(TEST_CUSTOM_SPEC);
         verify(mQsTileHost).addTile(ComponentName.unflattenFromString(TEST_COMPONENT)
             , /* end */ true);
@@ -359,10 +353,7 @@
     @Test
     public void testSettingTileAdded_onlyOnce() {
         changeValue(TEST_SETTING, 1);
-        waitForIdleSync();
-        TestableLooper.get(this).processAllMessages();
         changeValue(TEST_SETTING, 2);
-        waitForIdleSync();
         verify(mAutoAddTracker).setTileAdded(TEST_SPEC);
         verify(mQsTileHost).addTile(TEST_SPEC);
     }
@@ -370,7 +361,6 @@
     @Test
     public void testSettingTileNotAdded_onChangedTo0() {
         changeValue(TEST_SETTING, 0);
-        waitForIdleSync();
         verify(mAutoAddTracker, never()).setTileAdded(TEST_SPEC);
         verify(mQsTileHost, never()).addTile(TEST_SPEC);
     }
@@ -380,7 +370,6 @@
         when(mAutoAddTracker.isAdded(TEST_SPEC)).thenReturn(true);
 
         changeValue(TEST_SETTING, 1);
-        waitForIdleSync();
         verify(mAutoAddTracker, never()).setTileAdded(TEST_SPEC);
         verify(mQsTileHost, never()).addTile(TEST_SPEC);
     }
@@ -401,28 +390,7 @@
 
     // Will only notify if it's listening
     private void changeValue(String key, int value) {
-        SecureSetting s = mAutoTileManager.getSecureSettingForKey(key);
-        Settings.Secure.putInt(mContext.getContentResolver(), key, value);
-        if (s != null && s.isListening()) {
-            s.onChange(false);
-        }
-    }
-
-    class MyContextWrapper extends ContextWrapper {
-
-        private TestableContentResolver mSpiedTCR;
-
-        MyContextWrapper(TestableContext context) {
-            super(context);
-            mSpiedTCR = spy(context.getContentResolver());
-            doNothing().when(mSpiedTCR).registerContentObserver(any(), anyBoolean(), any(),
-                    anyInt());
-            doNothing().when(mSpiedTCR).unregisterContentObserver(any());
-        }
-
-        @Override
-        public ContentResolver getContentResolver() {
-            return mSpiedTCR;
-        }
+        mSecureSettings.putIntForUser(key, value, USER);
+        TestableLooper.get(this).processAllMessages();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
index 72a0258..aca3424 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
@@ -32,7 +32,6 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -81,25 +80,21 @@
     private Resources mResources;
     @Mock
     private HeadsUpManagerPhone mHeadsUpManagerPhone;
-    @Mock
-    private AuthController mAuthController;
 
     private LockscreenLockIconController mLockIconController;
     private OnAttachStateChangeListener mOnAttachStateChangeListener;
 
-
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        when(mAuthController.isUdfpsEnrolled()).thenReturn(false);
         when(mLockIcon.getContext()).thenReturn(mContext);
         mLockIconController = new LockscreenLockIconController(
                 mLockscreenGestureLogger, mKeyguardUpdateMonitor, mLockPatternUtils,
                 mShadeController, mAccessibilityController, mKeyguardIndicationController,
                 mStatusBarStateController, mConfigurationController, mNotificationWakeUpCoordinator,
                 mKeyguardBypassController, mDockManager, mKeyguardStateController, mResources,
-                mHeadsUpManagerPhone, mAuthController);
+                mHeadsUpManagerPhone);
 
         ArgumentCaptor<OnAttachStateChangeListener> onAttachStateChangeListenerArgumentCaptor =
                 ArgumentCaptor.forClass(OnAttachStateChangeListener.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
index b0086ef..7c8b413 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
@@ -37,7 +37,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -48,6 +47,7 @@
 import com.android.systemui.statusbar.notification.row.RowContentBindParams;
 import com.android.systemui.statusbar.notification.row.RowContentBindStage;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java
index f81672a..3e9fd51 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java
@@ -30,12 +30,12 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
index a1d419c..858227f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
@@ -27,7 +27,6 @@
 
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -35,6 +34,7 @@
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
+import com.android.wm.shell.bubbles.Bubbles;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 3b123f6..e9e6b3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -21,6 +21,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
@@ -63,6 +64,7 @@
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.media.MediaHierarchyManager;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.qs.QSDetailDisplayer;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -204,7 +206,7 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        when(mAuthController.isUdfpsEnrolled()).thenReturn(false);
+        when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
         when(mHeadsUpCallback.getContext()).thenReturn(mContext);
         when(mView.getResources()).thenReturn(mResources);
         when(mResources.getConfiguration()).thenReturn(mConfiguration);
@@ -213,6 +215,7 @@
         mDisplayMetrics.density = 100;
         when(mResources.getBoolean(R.bool.config_enableNotificationShadeDrag)).thenReturn(true);
         when(mView.getContext()).thenReturn(getContext());
+        when(mView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
         when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch);
         when(mView.findViewById(R.id.notification_stack_scroller))
                 .thenReturn(mNotificationStackScrollLayout);
@@ -272,7 +275,8 @@
                 mKeyguardStatusViewComponentFactory,
                 mGroupManager,
                 mNotificationAreaController,
-                mAuthController);
+                mAuthController,
+                new QSDetailDisplayer());
         mNotificationPanelViewController.initDependencies(
                 mStatusBar,
                 mNotificationShelfController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 9f096da..2f9b601 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -83,7 +83,6 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.demomode.DemoModeController;
@@ -146,6 +145,7 @@
 import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.volume.VolumeComponent;
 import com.android.systemui.wmshell.BubblesManager;
+import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.splitscreen.SplitScreen;
 
 import org.junit.Before;
@@ -337,7 +337,7 @@
         mShadeController = new ShadeControllerImpl(mCommandQueue,
                 mStatusBarStateController, mNotificationShadeWindowController,
                 mStatusBarKeyguardViewManager, mContext.getSystemService(WindowManager.class),
-                () -> mStatusBar, () -> mAssistManager, Optional.of(() -> mBubbles));
+                () -> mStatusBar, () -> mAssistManager, Optional.of(mBubbles));
 
         mStatusBar = new StatusBar(
                 mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 88d0401..a46e563 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -64,14 +64,6 @@
 import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.Bubble;
-import com.android.systemui.bubbles.BubbleData;
-import com.android.systemui.bubbles.BubbleDataRepository;
-import com.android.systemui.bubbles.BubbleEntry;
-import com.android.systemui.bubbles.BubbleLogger;
-import com.android.systemui.bubbles.BubblePositioner;
-import com.android.systemui.bubbles.BubbleStackView;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -102,6 +94,14 @@
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.bubbles.Bubble;
+import com.android.wm.shell.bubbles.BubbleData;
+import com.android.wm.shell.bubbles.BubbleDataRepository;
+import com.android.wm.shell.bubbles.BubbleEntry;
+import com.android.wm.shell.bubbles.BubbleLogger;
+import com.android.wm.shell.bubbles.BubblePositioner;
+import com.android.wm.shell.bubbles.BubbleStackView;
+import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 
 import com.google.common.collect.ImmutableList;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTestActivity.java
similarity index 82%
rename from packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
rename to packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTestActivity.java
index 43d2ad1..f4d96a12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTestActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.bubbles;
+package com.android.systemui.wmshell;
 
 import android.app.Activity;
 import android.content.Intent;
@@ -27,8 +27,7 @@
  */
 public class BubblesTestActivity extends Activity {
 
-    public static final String BUBBLE_ACTIVITY_OPENED =
-            "com.android.systemui.bubbles.BUBBLE_ACTIVITY_OPENED";
+    public static final String BUBBLE_ACTIVITY_OPENED = "BUBBLE_ACTIVITY_OPENED";
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
index 99c8ca4..d8033db 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -60,13 +60,6 @@
 import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.BubbleData;
-import com.android.systemui.bubbles.BubbleDataRepository;
-import com.android.systemui.bubbles.BubbleEntry;
-import com.android.systemui.bubbles.BubbleLogger;
-import com.android.systemui.bubbles.BubblePositioner;
-import com.android.systemui.bubbles.BubbleStackView;
-import com.android.systemui.bubbles.Bubbles;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -95,6 +88,13 @@
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.bubbles.BubbleData;
+import com.android.wm.shell.bubbles.BubbleDataRepository;
+import com.android.wm.shell.bubbles.BubbleEntry;
+import com.android.wm.shell.bubbles.BubbleLogger;
+import com.android.wm.shell.bubbles.BubblePositioner;
+import com.android.wm.shell.bubbles.BubbleStackView;
+import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
index 2273bc4..fd39b6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -22,13 +22,13 @@
 import android.view.WindowManager;
 
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.bubbles.BubbleController;
-import com.android.systemui.bubbles.BubbleData;
-import com.android.systemui.bubbles.BubbleDataRepository;
-import com.android.systemui.bubbles.BubbleLogger;
-import com.android.systemui.bubbles.BubblePositioner;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.bubbles.BubbleData;
+import com.android.wm.shell.bubbles.BubbleDataRepository;
+import com.android.wm.shell.bubbles.BubbleLogger;
+import com.android.wm.shell.bubbles.BubblePositioner;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 
 /**
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 374bd28..ca4b5d4 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -23,6 +23,9 @@
     <uses-permission android:name="android.permission.CONTROL_ALWAYS_ON_VPN" />
     <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"/>
 
+    <!-- Query all packages on device on R+ -->
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+
     <application android:label="VpnDialogs"
                  android:allowBackup="false">
 
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java b/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java
index 2c38dc3..25f4abe 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java
@@ -111,9 +111,9 @@
     // Shared state information.
     private TouchState mState;
 
-    GestureManifold(Context context, Listener listener, TouchState state) {
+    GestureManifold(Context context, Listener listener, TouchState state, Handler handler) {
         mContext = context;
-        mHandler = new Handler(context.getMainLooper());
+        mHandler = handler;
         mListener = listener;
         mState = state;
         mMultiFingerGesturesEnabled = false;
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 5460e80..b397782 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -199,7 +199,7 @@
                 new SendAccessibilityEventDelayed(
                         TYPE_TOUCH_INTERACTION_END, mDetermineUserIntentTimeout);
         if (detector == null) {
-            mGestureDetector = new GestureManifold(context, this, mState);
+            mGestureDetector = new GestureManifold(context, this, mState, mHandler);
         } else {
             mGestureDetector = detector;
         }
@@ -245,6 +245,8 @@
         mSendTouchInteractionEndDelayed.cancel();
         // Clear the gesture detector
         mGestureDetector.clear();
+        // Clear the offset data by long pressing.
+        mDispatcher.clear();
         // Go to initial state.
         mState.clear();
         mAms.onTouchInteractionEnd();
@@ -389,7 +391,6 @@
     public boolean onGestureStarted() {
         // We have to perform gesture detection, so
         // clear the current state and try to detect.
-        mState.startGestureDetecting();
         mSendHoverEnterAndMoveDelayed.cancel();
         mSendHoverExitDelayed.cancel();
         mExitGestureDetectionModeDelayed.post();
@@ -1193,7 +1194,7 @@
     }
 
     private boolean shouldPerformGestureDetection(MotionEvent event) {
-        if (mState.isDelegating()) {
+        if (mState.isDelegating() || mState.isDragging()) {
             return false;
         }
         if (event.getActionMasked() == ACTION_DOWN) {
@@ -1286,6 +1287,15 @@
         }
 
         public void run() {
+            if (mReceivedPointerTracker.getReceivedPointerDownCount() > 1) {
+                // Multi-finger touch exploration doesn't make sense.
+                Slog.e(
+                        LOG_TAG,
+                        "Attempted touch exploration with "
+                                + mReceivedPointerTracker.getReceivedPointerDownCount()
+                                + " pointers down.");
+                return;
+            }
             // Send an accessibility event to announce the touch exploration start.
             mDispatcher.sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_START);
             if (isSendMotionEventsEnabled()) {
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
index 7a39bc2..dae16b2 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
@@ -207,9 +207,6 @@
             case AccessibilityEvent.TYPE_GESTURE_DETECTION_START:
                 startGestureDetecting();
                 break;
-            case AccessibilityEvent.TYPE_GESTURE_DETECTION_END:
-                startTouchInteracting();
-                break;
             default:
                 break;
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index b3fc07a..6f81b5c 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -37,7 +37,7 @@
  * Handles all magnification controllers initialization, generic interactions
  * and magnification mode transition.
  */
-public class MagnificationController {
+public class MagnificationController implements WindowMagnificationManager.Callback {
 
     private static final boolean DEBUG = false;
     private static final String TAG = "MagnificationController";
@@ -78,6 +78,14 @@
         mWindowMagnificationMgr = windowMagnificationManager;
     }
 
+    @Override
+    public void onPerformScaleAction(int displayId, float scale) {
+        getWindowMagnificationMgr().setScale(displayId, scale);
+        getWindowMagnificationMgr().persistScale(displayId);
+        mAms.onMagnificationScaleChanged(displayId,
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+    }
+
     /**
      * Transitions to the target Magnification mode with current center of the magnification mode
      * if it is available.
@@ -223,7 +231,8 @@
         synchronized (mLock) {
             if (mWindowMagnificationMgr == null) {
                 mWindowMagnificationMgr = new WindowMagnificationManager(mContext,
-                        mAms.getCurrentUserIdLocked());
+                        mAms.getCurrentUserIdLocked(),
+                        this);
             }
             return mWindowMagnificationMgr;
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
index ed3085f..40668d8 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -16,6 +16,7 @@
 
 package com.android.server.accessibility.magnification;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -79,9 +80,27 @@
         }
     };
 
-    public WindowMagnificationManager(Context context, int userId) {
+    /**
+     * Callback to handle magnification actions from system UI.
+     */
+    public interface Callback {
+
+        /**
+         * Called when the accessibility action of scale requests to be performed.
+         * It is invoked from System UI. And the action is provided by the mirror window.
+         *
+         * @param displayId The logical display id.
+         * @param scale the target scale, or {@link Float#NaN} to leave unchanged
+         */
+        void onPerformScaleAction(int displayId, float scale);
+    }
+
+    private final Callback mCallback;
+
+    public WindowMagnificationManager(Context context, int userId, @NonNull Callback callback) {
         mContext = context;
         mUserId = userId;
+        mCallback = callback;
     }
 
     /**
@@ -498,6 +517,13 @@
         }
 
         @Override
+        public void onPerformScaleAction(int displayId, float scale) {
+            synchronized (mLock) {
+                mCallback.onPerformScaleAction(displayId, scale);
+            }
+        }
+
+        @Override
         public void binderDied() {
             synchronized (mLock) {
                 Slog.w(TAG, "binderDied DeathRecipient :" + mExpiredDeathRecipient);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index ad85784..a1ad72c 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -84,7 +84,6 @@
 import com.android.internal.util.SyncResultReceiver;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
-import com.android.server.SystemService.TargetUser;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.infra.AbstractMasterSystemService;
 import com.android.server.infra.FrameworkResourcesServiceNameResolver;
@@ -170,7 +169,7 @@
                 // beneath it is brought back to top. Ideally, we should just hide the UI and
                 // bring it back when the activity resumes.
                 synchronized (mLock) {
-                    visitServicesLocked((s) -> s.destroyFinishedSessionsLocked());
+                    visitServicesLocked((s) -> s.forceRemoveFinishedSessionsLocked());
                 }
                 mUi.hideAll(null);
             }
@@ -386,18 +385,18 @@
     }
 
     // Called by Shell command.
-    void destroySessions(@UserIdInt int userId, IResultReceiver receiver) {
-        Slog.i(TAG, "destroySessions() for userId " + userId);
+    void removeAllSessions(@UserIdInt int userId, IResultReceiver receiver) {
+        Slog.i(TAG, "removeAllSessions() for userId " + userId);
         enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             if (userId != UserHandle.USER_ALL) {
                 AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
                 if (service != null) {
-                    service.destroySessionsLocked();
+                    service.forceRemoveAllSessionsLocked();
                 }
             } else {
-                visitServicesLocked((s) -> s.destroySessionsLocked());
+                visitServicesLocked((s) -> s.forceRemoveAllSessionsLocked());
             }
         }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 864ead1..3212698 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -215,14 +215,14 @@
     @GuardedBy("mLock")
     @Override // from PerUserSystemService
     protected boolean updateLocked(boolean disabled) {
-        destroySessionsLocked();
+        forceRemoveAllSessionsLocked();
         final boolean enabledChanged = super.updateLocked(disabled);
         if (enabledChanged) {
             if (!isEnabledLocked()) {
                 final int sessionCount = mSessions.size();
                 for (int i = sessionCount - 1; i >= 0; i--) {
                     final Session session = mSessions.valueAt(i);
-                    session.removeSelfLocked();
+                    session.removeFromServiceLocked();
                 }
             }
             sendStateToClients(/* resetClient= */ false);
@@ -442,7 +442,7 @@
         if (sVerbose) Slog.v(TAG, "finishSessionLocked(): session finished on save? " + finished);
 
         if (finished) {
-            session.removeSelfLocked();
+            session.removeFromServiceLocked();
         }
     }
 
@@ -457,7 +457,7 @@
             Slog.w(TAG, "cancelSessionLocked(): no session for " + sessionId + "(" + uid + ")");
             return;
         }
-        session.removeSelfLocked();
+        session.removeFromServiceLocked();
     }
 
     @GuardedBy("mLock")
@@ -483,7 +483,7 @@
                         componentName.getPackageName());
                 Settings.Secure.putStringForUser(getContext().getContentResolver(),
                         Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
-                destroySessionsLocked();
+                forceRemoveAllSessionsLocked();
             } else {
                 Slog.w(TAG, "disableOwnedServices(): ignored because current service ("
                         + serviceInfo + ") does not match Settings (" + autoFillService + ")");
@@ -1107,35 +1107,41 @@
     }
 
     @GuardedBy("mLock")
-    void destroySessionsLocked() {
-        if (mSessions.size() == 0) {
+    void forceRemoveAllSessionsLocked() {
+        final int sessionCount = mSessions.size();
+        if (sessionCount == 0) {
             mUi.destroyAll(null, null, false);
             return;
         }
-        while (mSessions.size() > 0) {
-            mSessions.valueAt(0).forceRemoveSelfLocked();
+
+        for (int i = sessionCount - 1; i >= 0; i--) {
+            mSessions.valueAt(i).forceRemoveFromServiceLocked();
         }
     }
 
     @GuardedBy("mLock")
-    void destroySessionsForAugmentedAutofillOnlyLocked() {
+    void forceRemoveForAugmentedOnlySessionsLocked() {
         final int sessionCount = mSessions.size();
         for (int i = sessionCount - 1; i >= 0; i--) {
-            mSessions.valueAt(i).forceRemoveSelfIfForAugmentedAutofillOnlyLocked();
+            mSessions.valueAt(i).forceRemoveFromServiceIfForAugmentedOnlyLocked();
         }
     }
 
+    /**
+     * This method is called exclusively in response to {@code Intent.ACTION_CLOSE_SYSTEM_DIALOGS}.
+     * The method removes all sessions that are finished but showing SaveUI due to how SaveUI is
+     * managed (see b/64940307). Otherwise it will remove any augmented autofill generated windows.
+     */
     // TODO(b/64940307): remove this method if SaveUI is refactored to be attached on activities
     @GuardedBy("mLock")
-    void destroyFinishedSessionsLocked() {
+    void forceRemoveFinishedSessionsLocked() {
         final int sessionCount = mSessions.size();
         for (int i = sessionCount - 1; i >= 0; i--) {
             final Session session = mSessions.valueAt(i);
             if (session.isSavingLocked()) {
                 if (sDebug) Slog.d(TAG, "destroyFinishedSessionsLocked(): " + session.id);
-                session.forceRemoveSelfLocked();
-            }
-            else {
+                session.forceRemoveFromServiceLocked();
+            } else {
                 session.destroyAugmentedAutofillWindowsLocked();
             }
         }
@@ -1261,7 +1267,7 @@
                     Slog.v(TAG, "updateRemoteAugmentedAutofillService(): "
                             + "destroying old remote service");
                 }
-                destroySessionsForAugmentedAutofillOnlyLocked();
+                forceRemoveForAugmentedOnlySessionsLocked();
                 mRemoteAugmentedAutofillService.unbind();
                 mRemoteAugmentedAutofillService = null;
                 mRemoteAugmentedAutofillServiceInfo = null;
@@ -1663,7 +1669,7 @@
                                 Slog.i(TAG, "Prune session " + sessionToRemove.id + " ("
                                     + sessionToRemove.getActivityTokenLocked() + ")");
                             }
-                            sessionToRemove.removeSelfLocked();
+                            sessionToRemove.removeFromServiceLocked();
                         }
                     }
                 }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index bbe37a5..68e6290 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -355,7 +355,7 @@
                 latch.countDown();
             }
         };
-        return requestSessionCommon(pw, latch, () -> mService.destroySessions(userId, receiver));
+        return requestSessionCommon(pw, latch, () -> mService.removeAllSessions(userId, receiver));
     }
 
     private int requestList(PrintWriter pw) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 0302b22..b48d71a 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -227,8 +227,8 @@
     private boolean mHasCallback;
 
     /**
-     * Extras sent by service on {@code onFillRequest()} calls; the first non-null extra is saved
-     * and used on subsequent {@code onFillRequest()} and {@code onSaveRequest()} calls.
+     * Extras sent by service on {@code onFillRequest()} calls; the most recent non-null extra is
+     * saved and used on subsequent {@code onFillRequest()} and {@code onSaveRequest()} calls.
      */
     @GuardedBy("mLock")
     private Bundle mClientState;
@@ -1086,7 +1086,7 @@
         if (showMessage) {
             getUiForShowing().showError(message, this);
         }
-        removeSelf();
+        removeFromService();
     }
 
     // FillServiceCallbacks
@@ -1111,7 +1111,7 @@
         }
 
         // Nothing left to do...
-        removeSelf();
+        removeFromService();
     }
 
     // FillServiceCallbacks
@@ -1147,7 +1147,7 @@
         if (showMessage) {
             getUiForShowing().showError(message, this);
         }
-        removeSelf();
+        removeFromService();
     }
 
     /**
@@ -1179,7 +1179,7 @@
     @Override
     public void onServiceDied(@NonNull RemoteFillService service) {
         Slog.w(TAG, "removing session because service died");
-        forceRemoveSelfLocked();
+        forceRemoveFromServiceLocked();
     }
 
     // AutoFillUiCallback
@@ -1199,7 +1199,7 @@
             }
             fillInIntent = createAuthFillInIntentLocked(requestId, extras);
             if (fillInIntent == null) {
-                forceRemoveSelfLocked();
+                forceRemoveFromServiceLocked();
                 return;
             }
         }
@@ -1255,7 +1255,7 @@
             }
         }
         mHandler.sendMessage(obtainMessage(
-                Session::removeSelf, this));
+                Session::removeFromService, this));
     }
 
     // AutoFillUiCallback
@@ -1327,7 +1327,7 @@
     @Override
     public void cancelSession() {
         synchronized (mLock) {
-            removeSelfLocked();
+            removeFromServiceLocked();
         }
     }
 
@@ -1347,7 +1347,7 @@
                 return;
             }
             if (intent == null) {
-                removeSelfLocked();
+                removeFromServiceLocked();
             }
         }
         mHandler.sendMessage(obtainMessage(
@@ -1401,13 +1401,13 @@
             // Typically happens when app explicitly called cancel() while the service was showing
             // the auth UI.
             Slog.w(TAG, "setAuthenticationResultLocked(" + authenticationId + "): no responses");
-            removeSelf();
+            removeFromService();
             return;
         }
         final FillResponse authenticatedResponse = mResponses.get(requestId);
         if (authenticatedResponse == null || data == null) {
             Slog.w(TAG, "no authenticated response");
-            removeSelf();
+            removeFromService();
             return;
         }
 
@@ -1418,7 +1418,7 @@
             final Dataset dataset = authenticatedResponse.getDatasets().get(datasetIdx);
             if (dataset == null) {
                 Slog.w(TAG, "no dataset with index " + datasetIdx + " on fill response");
-                removeSelf();
+                removeFromService();
                 return;
             }
         }
@@ -1504,7 +1504,7 @@
                 Slog.d(TAG, "Rejecting empty/invalid auth result");
             }
             mService.resetLastAugmentedAutofillResponse();
-            removeSelfLocked();
+            removeFromServiceLocked();
             return;
         }
 
@@ -2715,7 +2715,7 @@
                         return;
                     }
                     if (sDebug) Slog.d(TAG, "Finishing session because URL bar changed");
-                    forceRemoveSelfLocked(AutofillManager.STATE_UNKNOWN_COMPAT_MODE);
+                    forceRemoveFromServiceLocked(AutofillManager.STATE_UNKNOWN_COMPAT_MODE);
                     return;
                 }
                 if (!Objects.equals(value, viewState.getCurrentValue())) {
@@ -3226,7 +3226,7 @@
             }
             // Nothing to be done, but need to notify client.
             notifyUnavailableToClient(AutofillManager.STATE_FINISHED, autofillableIds);
-            removeSelf();
+            removeFromService();
         } else {
             if ((flags & FLAG_PASSWORD_INPUT_TYPE) != 0) {
                 if (sVerbose) {
@@ -3393,20 +3393,6 @@
     }
 
     @GuardedBy("mLock")
-    private void logAugmentedAutofillRequestLocked(int mode,
-            ComponentName augmentedRemoteServiceName, AutofillId focusedId, boolean isWhitelisted,
-            Boolean isInline) {
-        final String historyItem =
-                "aug:id=" + id + " u=" + uid + " m=" + mode
-                        + " a=" + ComponentName.flattenToShortString(mComponentName)
-                        + " f=" + focusedId
-                        + " s=" + augmentedRemoteServiceName
-                        + " w=" + isWhitelisted
-                        + " i=" + isInline;
-        mService.getMaster().logRequestLocked(historyItem);
-    }
-
-    @GuardedBy("mLock")
     private void cancelAugmentedAutofillLocked() {
         final RemoteAugmentedAutofillService remoteService = mService
                 .getRemoteAugmentedAutofillServiceLocked();
@@ -3574,7 +3560,7 @@
             setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH, false);
             final Intent fillInIntent = createAuthFillInIntentLocked(requestId, mClientState);
             if (fillInIntent == null) {
-                forceRemoveSelfLocked();
+                forceRemoveFromServiceLocked();
                 return;
             }
             final int authenticationId = AutofillManager.makeAuthenticationId(requestId,
@@ -3923,12 +3909,12 @@
     }
 
     /**
-     * Cleans up this session.
+     * Destroy this session and perform any clean up work.
      *
      * <p>Typically called in 2 scenarios:
      *
      * <ul>
-     *   <li>When the session naturally finishes (i.e., from {@link #removeSelfLocked()}.
+     *   <li>When the session naturally finishes (i.e., from {@link #removeFromServiceLocked()}.
      *   <li>When the service hosting the session is finished (for example, because the user
      *       disabled it).
      * </ul>
@@ -3990,32 +3976,32 @@
     }
 
     /**
-     * Cleans up this session and remove it from the service always, even if it does have a pending
+     * Destroy this session and remove it from the service always, even if it does have a pending
      * Save UI.
      */
     @GuardedBy("mLock")
-    void forceRemoveSelfLocked() {
-        forceRemoveSelfLocked(AutofillManager.STATE_UNKNOWN);
+    void forceRemoveFromServiceLocked() {
+        forceRemoveFromServiceLocked(AutofillManager.STATE_UNKNOWN);
     }
 
     @GuardedBy("mLock")
-    void forceRemoveSelfIfForAugmentedAutofillOnlyLocked() {
+    void forceRemoveFromServiceIfForAugmentedOnlyLocked() {
         if (sVerbose) {
-            Slog.v(TAG, "forceRemoveSelfIfForAugmentedAutofillOnly(" + this.id + "): "
+            Slog.v(TAG, "forceRemoveFromServiceIfForAugmentedOnlyLocked(" + this.id + "): "
                     + mForAugmentedAutofillOnly);
         }
         if (!mForAugmentedAutofillOnly) return;
 
-        forceRemoveSelfLocked();
+        forceRemoveFromServiceLocked();
     }
 
     @GuardedBy("mLock")
-    void forceRemoveSelfLocked(int clientState) {
-        if (sVerbose) Slog.v(TAG, "forceRemoveSelfLocked(): " + mPendingSaveUi);
+    void forceRemoveFromServiceLocked(int clientState) {
+        if (sVerbose) Slog.v(TAG, "forceRemoveFromServiceLocked(): " + mPendingSaveUi);
 
         final boolean isPendingSaveUi = isSaveUiPendingLocked();
         mPendingSaveUi = null;
-        removeSelfLocked();
+        removeFromServiceLocked();
         mUi.destroyAll(mPendingSaveUi, this, false);
         if (!isPendingSaveUi) {
             try {
@@ -4036,28 +4022,28 @@
     }
 
     /**
-     * Thread-safe version of {@link #removeSelfLocked()}.
+     * Thread-safe version of {@link #removeFromServiceLocked()}.
      */
-    private void removeSelf() {
+    private void removeFromService() {
         synchronized (mLock) {
-            removeSelfLocked();
+            removeFromServiceLocked();
         }
     }
 
     /**
-     * Cleans up this session and remove it from the service, but but only if it does not have a
+     * Destroy this session and remove it from the service, but but only if it does not have a
      * pending Save UI.
      */
     @GuardedBy("mLock")
-    void removeSelfLocked() {
-        if (sVerbose) Slog.v(TAG, "removeSelfLocked(" + this.id + "): " + mPendingSaveUi);
+    void removeFromServiceLocked() {
+        if (sVerbose) Slog.v(TAG, "removeFromServiceLocked(" + this.id + "): " + mPendingSaveUi);
         if (mDestroyed) {
-            Slog.w(TAG, "Call to Session#removeSelfLocked() rejected - session: "
+            Slog.w(TAG, "Call to Session#removeFromServiceLocked() rejected - session: "
                     + id + " destroyed");
             return;
         }
         if (isSaveUiPendingLocked()) {
-            Slog.i(TAG, "removeSelfLocked() ignored, waiting for pending save ui");
+            Slog.i(TAG, "removeFromServiceLocked() ignored, waiting for pending save ui");
             return;
         }
 
@@ -4139,6 +4125,20 @@
         requestLog.addTaggedData(tag, value);
     }
 
+    @GuardedBy("mLock")
+    private void logAugmentedAutofillRequestLocked(int mode,
+            ComponentName augmentedRemoteServiceName, AutofillId focusedId, boolean isWhitelisted,
+            Boolean isInline) {
+        final String historyItem =
+                "aug:id=" + id + " u=" + uid + " m=" + mode
+                        + " a=" + ComponentName.flattenToShortString(mComponentName)
+                        + " f=" + focusedId
+                        + " s=" + augmentedRemoteServiceName
+                        + " w=" + isWhitelisted
+                        + " i=" + isInline;
+        mService.getMaster().logRequestLocked(historyItem);
+    }
+
     private void wtf(@Nullable Exception e, String fmt, Object...args) {
         final String message = String.format(fmt, args);
         synchronized (mLock) {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 75bbec6..ac6ed44 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -32,6 +32,7 @@
 import android.app.backup.IFullBackupRestoreObserver;
 import android.app.backup.IRestoreSession;
 import android.app.backup.ISelectBackupTransportCallback;
+import android.app.compat.CompatChanges;
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
 import android.app.job.JobService;
@@ -61,7 +62,6 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
-import com.android.server.SystemService.TargetUser;
 import com.android.server.backup.utils.RandomAccessFileUtils;
 
 import java.io.File;
@@ -509,6 +509,12 @@
      */
     @Override
     public boolean isBackupServiceActive(int userId) {
+        int callingUid = Binder.getCallingUid();
+        if (CompatChanges.isChangeEnabled(
+                BackupManager.IS_BACKUP_SERVICE_ACTIVE_ENFORCE_PERMISSION_IN_SERVICE, callingUid)) {
+            mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
+                    "isBackupServiceActive");
+        }
         synchronized (mStateLock) {
             return !mGlobalDisable && isBackupActivatedForUser(userId);
         }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 22423fe..d613427 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -135,8 +135,6 @@
 import android.net.metrics.NetworkEvent;
 import android.net.netlink.InetDiagMessage;
 import android.net.shared.PrivateDnsConfig;
-import android.net.util.LinkPropertiesUtils.CompareOrUpdateResult;
-import android.net.util.LinkPropertiesUtils.CompareResult;
 import android.net.util.MultinetworkPolicyTracker;
 import android.net.util.NetdService;
 import android.os.BasicShellCommandHandler;
@@ -192,6 +190,8 @@
 import com.android.internal.util.LocationPermissionChecker;
 import com.android.internal.util.MessageUtils;
 import com.android.internal.util.XmlUtils;
+import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
+import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.connectivity.AutodestructReference;
 import com.android.server.connectivity.DataConnectionStats;
@@ -235,6 +235,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.ConcurrentModificationException;
 import java.util.HashMap;
@@ -1105,23 +1106,26 @@
         intentFilter.addAction(Intent.ACTION_USER_ADDED);
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
         intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiverAsUser(
+
+        final Context userAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
+        userAllContext.registerReceiver(
                 mIntentReceiver,
-                UserHandle.ALL,
                 intentFilter,
                 null /* broadcastPermission */,
                 mHandler);
-        mContext.registerReceiverAsUser(mUserPresentReceiver, UserHandle.SYSTEM,
-                new IntentFilter(Intent.ACTION_USER_PRESENT), null, null);
+        mContext.createContextAsUser(UserHandle.SYSTEM, 0 /* flags */).registerReceiver(
+                mUserPresentReceiver,
+                new IntentFilter(Intent.ACTION_USER_PRESENT),
+                null /* broadcastPermission */,
+                null /* scheduler */);
 
         // Listen to package add and removal events for all users.
         intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
         intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         intentFilter.addDataScheme("package");
-        mContext.registerReceiverAsUser(
+        userAllContext.registerReceiver(
                 mIntentReceiver,
-                UserHandle.ALL,
                 intentFilter,
                 null /* broadcastPermission */,
                 mHandler);
@@ -1129,8 +1133,8 @@
         // Listen to lockdown VPN reset.
         intentFilter = new IntentFilter();
         intentFilter.addAction(LockdownVpnTracker.ACTION_LOCKDOWN_RESET);
-        mContext.registerReceiverAsUser(
-                mIntentReceiver, UserHandle.ALL, intentFilter, NETWORK_STACK, mHandler);
+        userAllContext.registerReceiver(
+                mIntentReceiver, intentFilter, NETWORK_STACK, mHandler);
 
         try {
             mNMS.registerObserver(mDataActivityObserver);
@@ -5259,7 +5263,9 @@
             // Try creating lockdown tracker, since user present usually means
             // unlocked keystore.
             updateLockdownVpn();
-            mContext.unregisterReceiver(this);
+            // Use the same context that registered receiver before to unregister it. Because use
+            // different context to unregister receiver will cause exception.
+            context.unregisterReceiver(this);
         }
     };
 
@@ -5353,7 +5359,9 @@
      * Also used to notice when the calling process dies so we can self-expire
      */
     private class NetworkRequestInfo implements IBinder.DeathRecipient {
+        final List<NetworkRequest> mRequests;
         final NetworkRequest request;
+
         // The network currently satisfying this request, or null if none. Must only be touched
         // on the handler thread. This only makes sense for network requests and not for listens,
         // as defined by NetworkRequest#isRequest(). For listens, this is always null.
@@ -5368,6 +5376,7 @@
 
         NetworkRequestInfo(NetworkRequest r, PendingIntent pi) {
             request = r;
+            mRequests = initializeRequests(r);
             ensureNetworkRequestHasType(request);
             mPendingIntent = pi;
             messenger = null;
@@ -5381,6 +5390,7 @@
             super();
             messenger = m;
             request = r;
+            mRequests = initializeRequests(r);
             ensureNetworkRequestHasType(request);
             mBinder = binder;
             mPid = getCallingPid();
@@ -5399,6 +5409,13 @@
             this(r, null);
         }
 
+        private List<NetworkRequest> initializeRequests(NetworkRequest r) {
+            final ArrayList<NetworkRequest> tempRequests = new ArrayList<>();
+            tempRequests.add(new NetworkRequest(r));
+            return Collections.unmodifiableList(tempRequests);
+        }
+
+
         private void enforceRequestCountLimit() {
             synchronized (mUidToNetworkRequestCount) {
                 int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index 78bd4cd..84f40cb 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -25,7 +25,6 @@
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
 import android.net.nsd.NsdServiceInfo;
-import android.net.util.nsd.DnsSdTxtRecord;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
@@ -42,6 +41,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.net.module.util.DnsSdTxtRecord;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index e675d8d..f079546 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -68,6 +68,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
@@ -117,6 +118,9 @@
     static final int DEFAULT_TRIGGER_FAILURE_COUNT = 5;
     @VisibleForTesting
     static final long DEFAULT_OBSERVING_DURATION_MS = TimeUnit.DAYS.toMillis(2);
+    // Sliding window for tracking how many mitigation calls were made for a package.
+    @VisibleForTesting
+    static final long DEFAULT_DEESCALATION_WINDOW_MS = TimeUnit.HOURS.toMillis(1);
     // Whether explicit health checks are enabled or not
     private static final boolean DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED = true;
 
@@ -388,6 +392,7 @@
                         // Observer that will receive failure for versionedPackage
                         PackageHealthObserver currentObserverToNotify = null;
                         int currentObserverImpact = Integer.MAX_VALUE;
+                        MonitoredPackage currentMonitoredPackage = null;
 
                         // Find observer with least user impact
                         for (int oIndex = 0; oIndex < mAllObservers.size(); oIndex++) {
@@ -396,19 +401,33 @@
                             if (registeredObserver != null
                                     && observer.onPackageFailureLocked(
                                     versionedPackage.getPackageName())) {
+                                MonitoredPackage p = observer.getMonitoredPackage(
+                                        versionedPackage.getPackageName());
+                                int mitigationCount = 1;
+                                if (p != null) {
+                                    mitigationCount = p.getMitigationCountLocked() + 1;
+                                }
                                 int impact = registeredObserver.onHealthCheckFailed(
-                                        versionedPackage, failureReason);
+                                        versionedPackage, failureReason, mitigationCount);
                                 if (impact != PackageHealthObserverImpact.USER_IMPACT_NONE
                                         && impact < currentObserverImpact) {
                                     currentObserverToNotify = registeredObserver;
                                     currentObserverImpact = impact;
+                                    currentMonitoredPackage = p;
                                 }
                             }
                         }
 
                         // Execute action with least user impact
                         if (currentObserverToNotify != null) {
-                            currentObserverToNotify.execute(versionedPackage, failureReason);
+                            int mitigationCount = 1;
+                            if (currentMonitoredPackage != null) {
+                                currentMonitoredPackage.noteMitigationCallLocked();
+                                mitigationCount =
+                                        currentMonitoredPackage.getMitigationCountLocked();
+                            }
+                            currentObserverToNotify.execute(versionedPackage,
+                                    failureReason, mitigationCount);
                         }
                     }
                 }
@@ -429,7 +448,7 @@
             PackageHealthObserver registeredObserver = observer.registeredObserver;
             if (registeredObserver != null) {
                 int impact = registeredObserver.onHealthCheckFailed(
-                        failingPackage, failureReason);
+                        failingPackage, failureReason, 1);
                 if (impact != PackageHealthObserverImpact.USER_IMPACT_NONE
                         && impact < currentObserverImpact) {
                     currentObserverToNotify = registeredObserver;
@@ -438,7 +457,7 @@
             }
         }
         if (currentObserverToNotify != null) {
-            currentObserverToNotify.execute(failingPackage,  failureReason);
+            currentObserverToNotify.execute(failingPackage,  failureReason, 1);
         }
     }
 
@@ -559,6 +578,8 @@
          * @param versionedPackage the package that is failing. This may be null if a native
          *                          service is crashing.
          * @param failureReason   the type of failure that is occurring.
+         * @param mitigationCount the number of times mitigation has been called for this package
+         *                        (including this time).
          *
          *
          * @return any one of {@link PackageHealthObserverImpact} to express the impact
@@ -566,7 +587,8 @@
          */
         @PackageHealthObserverImpact int onHealthCheckFailed(
                 @Nullable VersionedPackage versionedPackage,
-                @FailureReasons int failureReason);
+                @FailureReasons int failureReason,
+                int mitigationCount);
 
         /**
          * Executes mitigation for {@link #onHealthCheckFailed}.
@@ -574,10 +596,12 @@
          * @param versionedPackage the package that is failing. This may be null if a native
          *                          service is crashing.
          * @param failureReason   the type of failure that is occurring.
+         * @param mitigationCount the number of times mitigation has been called for this package
+         *                        (including this time).
          * @return {@code true} if action was executed successfully, {@code false} otherwise
          */
         boolean execute(@Nullable VersionedPackage versionedPackage,
-                @FailureReasons int failureReason);
+                @FailureReasons int failureReason, int mitigationCount);
 
 
         /**
@@ -684,7 +708,7 @@
         synchronized (mLock) {
             for (int observerIdx = 0; observerIdx < mAllObservers.size(); observerIdx++) {
                 ObserverInternal observer = mAllObservers.valueAt(observerIdx);
-                MonitoredPackage monitoredPackage = observer.packages.get(packageName);
+                MonitoredPackage monitoredPackage = observer.getMonitoredPackage(packageName);
 
                 if (monitoredPackage != null) {
                     int oldState = monitoredPackage.getHealthCheckStateLocked();
@@ -713,7 +737,8 @@
             Slog.d(TAG, "Received supported packages " + supportedPackages);
             Iterator<ObserverInternal> oit = mAllObservers.values().iterator();
             while (oit.hasNext()) {
-                Iterator<MonitoredPackage> pit = oit.next().packages.values().iterator();
+                Iterator<MonitoredPackage> pit = oit.next().getMonitoredPackages()
+                        .values().iterator();
                 while (pit.hasNext()) {
                     MonitoredPackage monitoredPackage = pit.next();
                     String packageName = monitoredPackage.getName();
@@ -746,7 +771,7 @@
         while (oit.hasNext()) {
             ObserverInternal observer = oit.next();
             Iterator<MonitoredPackage> pit =
-                    observer.packages.values().iterator();
+                    observer.getMonitoredPackages().values().iterator();
             while (pit.hasNext()) {
                 MonitoredPackage monitoredPackage = pit.next();
                 String packageName = monitoredPackage.getName();
@@ -804,7 +829,8 @@
     private long getNextStateSyncMillisLocked() {
         long shortestDurationMs = Long.MAX_VALUE;
         for (int oIndex = 0; oIndex < mAllObservers.size(); oIndex++) {
-            ArrayMap<String, MonitoredPackage> packages = mAllObservers.valueAt(oIndex).packages;
+            ArrayMap<String, MonitoredPackage> packages = mAllObservers.valueAt(oIndex)
+                    .getMonitoredPackages();
             for (int pIndex = 0; pIndex < packages.size(); pIndex++) {
                 MonitoredPackage mp = packages.valueAt(pIndex);
                 long duration = mp.getShortestScheduleDurationMsLocked();
@@ -838,7 +864,7 @@
             if (!failedPackages.isEmpty()) {
                 onHealthCheckFailed(observer, failedPackages);
             }
-            if (observer.packages.isEmpty() && (observer.registeredObserver == null
+            if (observer.getMonitoredPackages().isEmpty() && (observer.registeredObserver == null
                     || !observer.registeredObserver.isPersistent())) {
                 Slog.i(TAG, "Discarding observer " + observer.name + ". All packages expired");
                 it.remove();
@@ -857,7 +883,7 @@
                         VersionedPackage versionedPkg = it.next().mPackage;
                         Slog.i(TAG, "Explicit health check failed for package " + versionedPkg);
                         registeredObserver.execute(versionedPkg,
-                                PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+                                PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK, 1);
                     }
                 }
             }
@@ -1054,7 +1080,7 @@
     private static class ObserverInternal {
         public final String name;
         @GuardedBy("mLock")
-        public final ArrayMap<String, MonitoredPackage> packages = new ArrayMap<>();
+        private final ArrayMap<String, MonitoredPackage> mPackages = new ArrayMap<>();
         @Nullable
         @GuardedBy("mLock")
         public PackageHealthObserver registeredObserver;
@@ -1073,8 +1099,8 @@
             try {
                 out.startTag(null, TAG_OBSERVER);
                 out.attribute(null, ATTR_NAME, name);
-                for (int i = 0; i < packages.size(); i++) {
-                    MonitoredPackage p = packages.valueAt(i);
+                for (int i = 0; i < mPackages.size(); i++) {
+                    MonitoredPackage p = mPackages.valueAt(i);
                     p.writeLocked(out);
                 }
                 out.endTag(null, TAG_OBSERVER);
@@ -1089,11 +1115,11 @@
         public void updatePackagesLocked(List<MonitoredPackage> packages) {
             for (int pIndex = 0; pIndex < packages.size(); pIndex++) {
                 MonitoredPackage p = packages.get(pIndex);
-                MonitoredPackage existingPackage = this.packages.get(p.getName());
+                MonitoredPackage existingPackage = getMonitoredPackage(p.getName());
                 if (existingPackage != null) {
                     existingPackage.updateHealthCheckDuration(p.mDurationMs);
                 } else {
-                    this.packages.put(p.getName(), p);
+                    putMonitoredPackage(p);
                 }
             }
         }
@@ -1111,7 +1137,7 @@
         @GuardedBy("mLock")
         private Set<MonitoredPackage> prunePackagesLocked(long elapsedMs) {
             Set<MonitoredPackage> failedPackages = new ArraySet<>();
-            Iterator<MonitoredPackage> it = packages.values().iterator();
+            Iterator<MonitoredPackage> it = mPackages.values().iterator();
             while (it.hasNext()) {
                 MonitoredPackage p = it.next();
                 int oldState = p.getHealthCheckStateLocked();
@@ -1134,12 +1160,12 @@
          */
         @GuardedBy("mLock")
         public boolean onPackageFailureLocked(String packageName) {
-            if (packages.get(packageName) == null && registeredObserver.isPersistent()
+            if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
                     && registeredObserver.mayObservePackage(packageName)) {
-                packages.put(packageName, sPackageWatchdog.newMonitoredPackage(
+                putMonitoredPackage(sPackageWatchdog.newMonitoredPackage(
                         packageName, DEFAULT_OBSERVING_DURATION_MS, false));
             }
-            MonitoredPackage p = packages.get(packageName);
+            MonitoredPackage p = getMonitoredPackage(packageName);
             if (p != null) {
                 return p.onFailureLocked();
             }
@@ -1147,6 +1173,40 @@
         }
 
         /**
+         * Returns the map of packages monitored by this observer.
+         *
+         * @return a mapping of package names to {@link MonitoredPackage} objects.
+         */
+        @GuardedBy("mLock")
+        public ArrayMap<String, MonitoredPackage> getMonitoredPackages() {
+            return mPackages;
+        }
+
+        /**
+         * Returns the {@link MonitoredPackage} associated with a given package name if the
+         * package is being monitored by this observer.
+         *
+         * @param packageName: the name of the package.
+         * @return the {@link MonitoredPackage} object associated with the package name if one
+         *         exists, {@code null} otherwise.
+         */
+        @GuardedBy("mLock")
+        @Nullable
+        public MonitoredPackage getMonitoredPackage(String packageName) {
+            return mPackages.get(packageName);
+        }
+
+        /**
+         * Associates a {@link MonitoredPackage} with the observer.
+         *
+         * @param p: the {@link MonitoredPackage} to store.
+         */
+        @GuardedBy("mLock")
+        public void putMonitoredPackage(MonitoredPackage p) {
+            mPackages.put(p.getName(), p);
+        }
+
+        /**
          * Returns one ObserverInternal from the {@code parser} and advances its state.
          *
          * <p>Note that this method is <b>not</b> thread safe. It should only be called from
@@ -1201,8 +1261,8 @@
         public void dump(IndentingPrintWriter pw) {
             boolean isPersistent = registeredObserver != null && registeredObserver.isPersistent();
             pw.println("Persistent: " + isPersistent);
-            for (String packageName : packages.keySet()) {
-                MonitoredPackage p = packages.get(packageName);
+            for (String packageName : mPackages.keySet()) {
+                MonitoredPackage p = getMonitoredPackage(packageName);
                 pw.println(packageName +  ": ");
                 pw.increaseIndent();
                 pw.println("# Failures: " + p.mFailureHistory.size());
@@ -1257,6 +1317,10 @@
         // Times when package failures happen sorted in ascending order
         @GuardedBy("mLock")
         private final LongArrayQueue mFailureHistory = new LongArrayQueue();
+        // Times when an observer was called to mitigate this package's failure. Sorted in
+        // ascending order.
+        @GuardedBy("mLock")
+        private final LongArrayQueue mMitigationCalls = new LongArrayQueue();
         // One of STATE_[ACTIVE|INACTIVE|PASSED|FAILED]. Updated on construction and after
         // methods that could change the health check state: handleElapsedTimeLocked and
         // tryPassHealthCheckLocked
@@ -1322,6 +1386,33 @@
         }
 
         /**
+         * Notes the timestamp of a mitigation call into the observer.
+         */
+        @GuardedBy("mLock")
+        public void noteMitigationCallLocked() {
+            mMitigationCalls.addLast(mSystemClock.uptimeMillis());
+        }
+
+        /**
+         * Prunes any mitigation calls outside of the de-escalation window, and returns the
+         * number of calls that are in the window afterwards.
+         *
+         * @return the number of mitigation calls made in the de-escalation window.
+         */
+        @GuardedBy("mLock")
+        public int getMitigationCountLocked() {
+            try {
+                final long now = mSystemClock.uptimeMillis();
+                while (now - mMitigationCalls.peekFirst() > DEFAULT_DEESCALATION_WINDOW_MS) {
+                    mMitigationCalls.removeFirst();
+                }
+            } catch (NoSuchElementException ignore) {
+            }
+
+            return mMitigationCalls.size();
+        }
+
+        /**
          * Sets the initial health check duration.
          *
          * @return the new health check state
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 9fc8f0b..6206f7a 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -56,6 +56,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -76,6 +77,7 @@
     static final String PROP_ENABLE_RESCUE = "persist.sys.enable_rescue";
     @VisibleForTesting
     static final String PROP_RESCUE_LEVEL = "sys.rescue_level";
+    static final String PROP_ATTEMPTING_FACTORY_RESET = "sys.attempting_factory_reset";
     @VisibleForTesting
     static final int LEVEL_NONE = 0;
     @VisibleForTesting
@@ -100,6 +102,10 @@
     private static final String PROP_VIRTUAL_DEVICE = "ro.hardware.virtual_device";
     private static final String PROP_DEVICE_CONFIG_DISABLE_FLAG =
             "persist.device_config.configuration.disable_rescue_party";
+    private static final String PROP_DISABLE_FACTORY_RESET_FLAG =
+            "persist.device_config.configuration.disable_rescue_party_factory_reset";
+    // The DeviceConfig namespace containing all RescueParty switches.
+    private static final String NAMESPACE_CONFIGURATION = "configuration";
 
     private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT
             | ApplicationInfo.FLAG_SYSTEM;
@@ -150,7 +156,7 @@
      * Check if we're currently attempting to reboot for a factory reset.
      */
     public static boolean isAttemptingFactoryReset() {
-        return SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE) == LEVEL_FACTORY_RESET;
+        return SystemProperties.getBoolean(PROP_ATTEMPTING_FACTORY_RESET, false);
     }
 
     /**
@@ -215,18 +221,48 @@
         if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) {
             String[] resetNativeCategories = SettingsToPropertiesMapper.getResetNativeCategories();
             for (int i = 0; i < resetNativeCategories.length; i++) {
+                // Don't let RescueParty reset the namespace for RescueParty switches.
+                if (NAMESPACE_CONFIGURATION.equals(resetNativeCategories[i])) {
+                    continue;
+                }
                 DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
                         resetNativeCategories[i]);
             }
         }
     }
 
+    private static int getMaxRescueLevel() {
+        return SystemProperties.getBoolean(PROP_DISABLE_FACTORY_RESET_FLAG, false)
+                ? LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS : LEVEL_FACTORY_RESET;
+    }
+
+    /**
+     * Get the rescue level to perform if this is the n-th attempt at mitigating failure.
+     *
+     * @param mitigationCount: the mitigation attempt number (1 = first attempt etc.)
+     * @return the rescue level for the n-th mitigation attempt.
+     */
+    private static int getRescueLevel(int mitigationCount) {
+        if (mitigationCount == 1) {
+            return LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS;
+        } else if (mitigationCount == 2) {
+            return LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES;
+        } else if (mitigationCount == 3) {
+            return LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS;
+        } else if (mitigationCount >= 4) {
+            return getMaxRescueLevel();
+        } else {
+            Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount);
+            return LEVEL_NONE;
+        }
+    }
+
     /**
      * Get the next rescue level. This indicates the next level of mitigation that may be taken.
      */
     private static int getNextRescueLevel() {
         return MathUtils.constrain(SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE) + 1,
-                LEVEL_NONE, LEVEL_FACTORY_RESET);
+                LEVEL_NONE, getMaxRescueLevel());
     }
 
     /**
@@ -245,7 +281,11 @@
     private static void executeRescueLevel(Context context, @Nullable String failedPackage) {
         final int level = SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE);
         if (level == LEVEL_NONE) return;
+        executeRescueLevel(context, failedPackage, level);
+    }
 
+    private static void executeRescueLevel(Context context, @Nullable String failedPackage,
+            int level) {
         Slog.w(TAG, "Attempting rescue level " + levelToString(level));
         try {
             executeRescueLevelInternal(context, level, failedPackage);
@@ -273,6 +313,7 @@
             case LEVEL_FACTORY_RESET:
                 // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog
                 // when device shutting down.
+                SystemProperties.set(PROP_ATTEMPTING_FACTORY_RESET, "true");
                 Runnable runnable = new Runnable() {
                     @Override
                     public void run() {
@@ -309,15 +350,6 @@
         }
     }
 
-    private static int getPackageUid(Context context, String packageName) {
-        try {
-            return context.getPackageManager().getPackageUid(packageName, 0);
-        } catch (PackageManager.NameNotFoundException e) {
-            // Since UIDs are always >= 0, this value means the UID could not be determined.
-            return -1;
-        }
-    }
-
     private static void resetAllSettings(Context context, int mode, @Nullable String failedPackage)
             throws Exception {
         // Try our best to reset all settings possible, and once finished
@@ -348,18 +380,33 @@
 
     private static void resetDeviceConfig(Context context, int resetMode,
             @Nullable String failedPackage) {
-        if (!shouldPerformScopedResets() || failedPackage == null) {
-            DeviceConfig.resetToDefaults(resetMode, /*namespace=*/ null);
+        if (!shouldPerformScopedResets(resetMode) || failedPackage == null) {
+            resetAllAffectedNamespaces(context, resetMode);
         } else {
             performScopedReset(context, resetMode, failedPackage);
         }
     }
 
-    private static boolean shouldPerformScopedResets() {
-        int rescueLevel = MathUtils.constrain(
-                SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE),
-                LEVEL_NONE, LEVEL_FACTORY_RESET);
-        return rescueLevel <= LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES;
+    private static void resetAllAffectedNamespaces(Context context, int resetMode) {
+        RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
+        Set<String> allAffectedNamespaces = rescuePartyObserver.getAllAffectedNamespaceSet();
+
+        Slog.w(TAG,
+                "Performing reset for all affected namespaces: "
+                        + Arrays.toString(allAffectedNamespaces.toArray()));
+        Iterator<String> it = allAffectedNamespaces.iterator();
+        while (it.hasNext()) {
+            String namespace = it.next();
+            // Don't let RescueParty reset the namespace for RescueParty switches.
+            if (NAMESPACE_CONFIGURATION.equals(namespace)) {
+                continue;
+            }
+            DeviceConfig.resetToDefaults(resetMode, namespace);
+        }
+    }
+
+    private static boolean shouldPerformScopedResets(int resetMode) {
+        return resetMode <= Settings.RESET_MODE_UNTRUSTED_CHANGES;
     }
 
     private static void performScopedReset(Context context, int resetMode,
@@ -367,16 +414,21 @@
         RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
         Set<String> affectedNamespaces = rescuePartyObserver.getAffectedNamespaceSet(
                 failedPackage);
-        if (affectedNamespaces == null) {
-            DeviceConfig.resetToDefaults(resetMode, /*namespace=*/ null);
-        } else {
+        // If we can't find namespaces affected for current package,
+        // skip this round of reset.
+        if (affectedNamespaces != null) {
             Slog.w(TAG,
                     "Performing scoped reset for package: " + failedPackage
                             + ", affected namespaces: "
                             + Arrays.toString(affectedNamespaces.toArray()));
             Iterator<String> it = affectedNamespaces.iterator();
             while (it.hasNext()) {
-                DeviceConfig.resetToDefaults(resetMode, it.next());
+                String namespace = it.next();
+                // Don't let RescueParty reset the namespace for RescueParty switches.
+                if (NAMESPACE_CONFIGURATION.equals(namespace)) {
+                    continue;
+                }
+                DeviceConfig.resetToDefaults(resetMode, namespace);
             }
         }
     }
@@ -418,10 +470,10 @@
 
         @Override
         public int onHealthCheckFailed(@Nullable VersionedPackage failedPackage,
-                @FailureReasons int failureReason) {
+                @FailureReasons int failureReason, int mitigationCount) {
             if (!isDisabled() && (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
                     || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING)) {
-                return mapRescueLevelToUserImpact(getNextRescueLevel());
+                return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
             } else {
                 return PackageHealthObserverImpact.USER_IMPACT_NONE;
             }
@@ -429,16 +481,15 @@
 
         @Override
         public boolean execute(@Nullable VersionedPackage failedPackage,
-                @FailureReasons int failureReason) {
+                @FailureReasons int failureReason, int mitigationCount) {
             if (isDisabled()) {
                 return false;
             }
             if (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
                     || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING) {
-                int triggerUid = getPackageUid(mContext, failedPackage.getPackageName());
-                incrementRescueLevel(triggerUid);
+                final int level = getRescueLevel(mitigationCount);
                 executeRescueLevel(mContext,
-                        failedPackage == null ? null : failedPackage.getPackageName());
+                        failedPackage == null ? null : failedPackage.getPackageName(), level);
                 return true;
             } else {
                 return false;
@@ -514,6 +565,10 @@
             return mCallingPackageNamespaceSetMap.get(failedPackage);
         }
 
+        private synchronized Set<String> getAllAffectedNamespaceSet() {
+            return new HashSet<String>(mNamespaceCallingPackageSetMap.keySet());
+        }
+
         private synchronized Set<String> getCallingPackagesSet(String namespace) {
             return mNamespaceCallingPackageSetMap.get(namespace);
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 112814c69..9f2216d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4890,6 +4890,15 @@
     }
 
     @Override
+    public boolean isIntentSenderImmutable(IIntentSender pendingResult) {
+        if (pendingResult instanceof PendingIntentRecord) {
+            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
+            return (res.key.flags & PendingIntent.FLAG_IMMUTABLE) != 0;
+        }
+        return false;
+    }
+
+    @Override
     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
         if (!(pendingResult instanceof PendingIntentRecord)) {
             return false;
@@ -7736,11 +7745,15 @@
      * @return true if the process should exit immediately (WTF is fatal)
      */
     @Override
-    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
-            final ApplicationErrorReport.ParcelableCrashInfo crashInfo, int immediateCallerPid) {
+    public boolean handleApplicationWtf(@Nullable final IBinder app, @Nullable final String tag,
+            boolean system, @NonNull final ApplicationErrorReport.ParcelableCrashInfo crashInfo,
+            int immediateCallerPid) {
         final int callingUid = Binder.getCallingUid();
         final int callingPid = Binder.getCallingPid();
 
+        // Internal callers in RuntimeInit should always generate a crashInfo.
+        Preconditions.checkNotNull(crashInfo);
+
         // If this is coming from the system, we could very well have low-level
         // system locks held, so we want to do this all asynchronously.  And we
         // never want this to become fatal, so there is that too.
@@ -7773,14 +7786,15 @@
         }
     }
 
-    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
-            final ApplicationErrorReport.CrashInfo crashInfo) {
+    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, @Nullable IBinder app,
+            @Nullable String tag, @Nullable final ApplicationErrorReport.CrashInfo crashInfo) {
         final ProcessRecord r = findAppProcess(app, "WTF");
         final String processName = app == null ? "system_server"
                 : (r == null ? "unknown" : r.processName);
 
         EventLogTags.writeAmWtf(UserHandle.getUserId(callingUid), callingPid,
-                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
+                processName, r == null ? -1 : r.info.flags, tag,
+                crashInfo == null ? "unknown" : crashInfo.exceptionMessage);
 
         FrameworkStatsLog.write(FrameworkStatsLog.WTF_OCCURRED, callingUid, tag, processName,
                 callingPid, (r != null) ? r.getProcessClassEnum() : 0);
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 5e59a35..cace260 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -247,6 +247,9 @@
     private int mMemWatchDumpUid;
     private boolean mMemWatchIsUserInitiated;
 
+    boolean mHasHomeProcess;
+    boolean mHasPreviousProcess;
+
     /**
      * Used to collect per-process CPU use for ANRs, battery stats, etc.
      * Must acquire this object's lock when accessing it.
@@ -961,8 +964,8 @@
             }
             int factor = numTrimming / 3;
             int minFactor = 2;
-            if (mService.mAtmInternal.getHomeProcess() != null) minFactor++;
-            if (mService.mAtmInternal.getPreviousProcess() != null) minFactor++;
+            if (mHasHomeProcess) minFactor++;
+            if (mHasPreviousProcess) minFactor++;
             if (factor < minFactor) factor = minFactor;
             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
             for (int i = 0; i < numOfLru; i++) {
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 9d49236..01d0a6d 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -500,6 +500,7 @@
         final ProcessRecord topApp = mService.getTopAppLocked();
         // Clear any pending ones because we are doing a full update now.
         mPendingProcessSet.clear();
+        mService.mAppProfiler.mHasPreviousProcess = mService.mAppProfiler.mHasHomeProcess = false;
         updateOomAdjLockedInner(oomAdjReason, topApp , null, null, true, true);
     }
 
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index ccdd6a7..463ba6d 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1875,16 +1875,24 @@
 
     boolean getCachedIsHomeProcess() {
         if (mCachedIsHomeProcess == VALUE_INVALID) {
-            mCachedIsHomeProcess = getWindowProcessController().isHomeProcess()
-                    ? VALUE_TRUE : VALUE_FALSE;
+            if (getWindowProcessController().isHomeProcess()) {
+                mCachedIsHomeProcess = VALUE_TRUE;
+                mService.mAppProfiler.mHasHomeProcess = true;
+            } else {
+                mCachedIsHomeProcess = VALUE_FALSE;
+            }
         }
         return mCachedIsHomeProcess == VALUE_TRUE;
     }
 
     boolean getCachedIsPreviousProcess() {
         if (mCachedIsPreviousProcess == VALUE_INVALID) {
-            mCachedIsPreviousProcess = getWindowProcessController().isPreviousProcess()
-                    ? VALUE_TRUE : VALUE_FALSE;
+            if (getWindowProcessController().isPreviousProcess()) {
+                mCachedIsPreviousProcess = VALUE_TRUE;
+                mService.mAppProfiler.mHasPreviousProcess = true;
+            } else {
+                mCachedIsPreviousProcess = VALUE_FALSE;
+            }
         }
         return mCachedIsPreviousProcess == VALUE_TRUE;
     }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 5379f32..2b2d9b55 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -94,6 +94,7 @@
 import android.app.RuntimeAppOpAccessMessage;
 import android.app.SyncNotedAppOp;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -3015,6 +3016,25 @@
         }
     }
 
+    private boolean isTrustedVoiceServiceProxy(String packageName, int code) {
+        if (code != OP_RECORD_AUDIO) {
+            return false;
+        }
+        final String voiceRecognitionComponent = Settings.Secure.getString(
+                mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE);
+        final String voiceInteractionComponent = Settings.Secure.getString(
+                mContext.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE);
+
+        final String voiceRecognitionServicePackageName =
+                voiceRecognitionComponent != null ? ComponentName.unflattenFromString(
+                        voiceRecognitionComponent).getPackageName() : "";
+        final String voiceInteractionServicePackageName =
+                voiceInteractionComponent != null ? ComponentName.unflattenFromString(
+                        voiceInteractionComponent).getPackageName() : "";
+        return Objects.equals(packageName, voiceRecognitionServicePackageName) && Objects.equals(
+                voiceRecognitionServicePackageName, voiceInteractionServicePackageName);
+    }
+
     @Override
     public int noteProxyOperation(int code, int proxiedUid, String proxiedPackageName,
             String proxiedAttributionTag, int proxyUid, String proxyPackageName,
@@ -3030,9 +3050,12 @@
             return AppOpsManager.MODE_IGNORED;
         }
 
+        // This is a workaround for R QPR, new API change is not allowed. We only allow the current
+        // voice recognizer is also the voice interactor to noteproxy op.
+        final boolean isTrustVoiceServiceProxy = isTrustedVoiceServiceProxy(proxyPackageName, code);
         final boolean isProxyTrusted = mContext.checkPermission(
                 Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)
-                == PackageManager.PERMISSION_GRANTED;
+                == PackageManager.PERMISSION_GRANTED || isTrustVoiceServiceProxy;
 
         final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
                 : AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
@@ -3494,9 +3517,12 @@
             return AppOpsManager.MODE_IGNORED;
         }
 
+        // This is a workaround for R QPR, new API change is not allowed. We only allow the current
+        // voice recognizer is also the voice interactor to noteproxy op.
+        final boolean isTrustVoiceServiceProxy = isTrustedVoiceServiceProxy(proxyPackageName, code);
         final boolean isProxyTrusted = mContext.checkPermission(
                 Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)
-                == PackageManager.PERMISSION_GRANTED;
+                == PackageManager.PERMISSION_GRANTED || isTrustVoiceServiceProxy;
 
         final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
                 : AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 54c1790..d52cf02 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -329,6 +329,10 @@
                     return;
                 }
 
+                // Initialize this outside of FingerprintAuthenticator. Only HIDL HALs require
+                // initialization from here. AIDL HALs are initialized by FingerprintService since
+                // the HAL interface provides ID, strength, and other configuration information.
+                fingerprintService.initializeConfiguration(config.id, config.strength);
                 authenticator = new FingerprintAuthenticator(fingerprintService, config);
                 break;
 
@@ -340,6 +344,10 @@
                     return;
                 }
 
+                // Initialize this outside of FingerprintAuthenticator. Only HIDL HALs require
+                // initialization from here. AIDL HALs are initialized by FaceService since
+                // the HAL interface provides ID, strength, and other configuration information.
+                faceService.initializeConfiguration(config.id, config.strength);
                 authenticator = new FaceAuthenticator(faceService, config);
                 break;
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index 3318bcb..e742d10 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -30,11 +30,12 @@
  */
 public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
     private final IFaceService mFaceService;
+    private final int mSensorId;
 
     public FaceAuthenticator(IFaceService faceService, SensorConfig config)
             throws RemoteException {
         mFaceService = faceService;
-        mFaceService.initializeConfiguration(config.id, config.strength);
+        mSensorId = config.id;
     }
 
     @Override
@@ -42,40 +43,41 @@
             long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
             String opPackageName, int cookie, int callingUid, int callingPid, int callingUserId)
             throws RemoteException {
-        mFaceService.prepareForAuthentication(requireConfirmation, token, operationId, userId,
-                sensorReceiver, opPackageName, cookie, callingUid, callingPid, callingUserId);
+        mFaceService.prepareForAuthentication(mSensorId, requireConfirmation, token, operationId,
+                userId, sensorReceiver, opPackageName, cookie, callingUid, callingPid,
+                callingUserId);
     }
 
     @Override
     public void startPreparedClient(int cookie) throws RemoteException {
-        mFaceService.startPreparedClient(cookie);
+        mFaceService.startPreparedClient(mSensorId, cookie);
     }
 
     @Override
     public void cancelAuthenticationFromService(IBinder token, String opPackageName, int callingUid,
             int callingPid, int callingUserId) throws RemoteException {
-        mFaceService.cancelAuthenticationFromService(token, opPackageName, callingUid, callingPid,
-                callingUserId);
+        mFaceService.cancelAuthenticationFromService(mSensorId, token, opPackageName, callingUid,
+                callingPid, callingUserId);
     }
 
     @Override
     public boolean isHardwareDetected(String opPackageName) throws RemoteException {
-        return mFaceService.isHardwareDetected(opPackageName);
+        return mFaceService.isHardwareDetected(mSensorId, opPackageName);
     }
 
     @Override
     public boolean hasEnrolledTemplates(int userId, String opPackageName) throws RemoteException {
-        return mFaceService.hasEnrolledFaces(userId, opPackageName);
+        return mFaceService.hasEnrolledFaces(mSensorId, userId, opPackageName);
     }
 
     @Override
     public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId)
             throws RemoteException {
-        return mFaceService.getLockoutModeForUser(userId);
+        return mFaceService.getLockoutModeForUser(mSensorId, userId);
     }
 
     @Override
     public long getAuthenticatorId(int callingUserId) throws RemoteException {
-        return mFaceService.getAuthenticatorId(callingUserId);
+        return mFaceService.getAuthenticatorId(mSensorId, callingUserId);
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index a298e19..00a708d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -66,7 +66,7 @@
     private final LockoutResetDispatcher mLockoutResetDispatcher;
     private final LockPatternUtils mLockPatternUtils;
     @NonNull
-    private List<ServiceProvider> mServiceProviders;
+    private final List<ServiceProvider> mServiceProviders;
 
     @Nullable
     private ServiceProvider getProviderForSensor(int sensorId) {
@@ -255,35 +255,35 @@
         }
 
         @Override // Binder call
-        public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
-                long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
-                String opPackageName, int cookie, int callingUid, int callingPid,
-                int callingUserId) {
+        public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
+                IBinder token, long operationId, int userId,
+                IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie,
+                int callingUid, int callingPid, int callingUserId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for prepareForAuthentication");
                 return;
             }
 
             final boolean restricted = true; // BiometricPrompt is always restricted
-            provider.second.scheduleAuthenticate(provider.first, token, operationId, userId, cookie,
+            provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
                     new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted,
                     BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, false /* isKeyguard */);
         }
 
         @Override // Binder call
-        public void startPreparedClient(int cookie) {
+        public void startPreparedClient(int sensorId, int cookie) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for startPreparedClient");
                 return;
             }
 
-            provider.second.startPreparedClient(provider.first, cookie);
+            provider.startPreparedClient(sensorId, cookie);
         }
 
         @Override // Binder call
@@ -312,17 +312,17 @@
         }
 
         @Override // Binder call
-        public void cancelAuthenticationFromService(final IBinder token, final String opPackageName,
-                int callingUid, int callingPid, int callingUserId) {
+        public void cancelAuthenticationFromService(int sensorId, final IBinder token,
+                final String opPackageName, int callingUid, int callingPid, int callingUserId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
                 return;
             }
 
-            provider.second.cancelAuthentication(provider.first, token);
+            provider.cancelAuthentication(sensorId, token);
         }
 
         @Override // Binder call
@@ -384,24 +384,24 @@
         }
 
         @Override // Binder call
-        public boolean isHardwareDetected(String opPackageName) {
+        public boolean isHardwareDetected(int sensorId, String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final long token = Binder.clearCallingIdentity();
             try {
-                final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+                final ServiceProvider provider = getProviderForSensor(sensorId);
                 if (provider == null) {
                     Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
                     return false;
                 }
-                return provider.second.isHardwareDetected(provider.first);
+                return provider.isHardwareDetected(sensorId);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override // Binder call
-        public List<Face> getEnrolledFaces(int userId, String opPackageName) {
+        public List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             if (userId != UserHandle.getCallingUserId()) {
@@ -412,7 +412,7 @@
         }
 
         @Override // Binder call
-        public boolean hasEnrolledFaces(int userId, String opPackageName) {
+        public boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             if (userId != UserHandle.getCallingUserId()) {
@@ -423,30 +423,29 @@
         }
 
         @Override // Binder call
-        @LockoutTracker.LockoutMode
-        public int getLockoutModeForUser(int userId) {
+        public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for getLockoutModeForUser");
                 return LockoutTracker.LOCKOUT_NONE;
             }
 
-            return provider.second.getLockoutModeForUser(provider.first, userId);
+            return provider.getLockoutModeForUser(sensorId, userId);
         }
 
         @Override // Binder call
-        public long getAuthenticatorId(int userId) {
+        public long getAuthenticatorId(int sensorId, int userId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for getAuthenticatorId");
                 return 0;
             }
 
-            return provider.second.getAuthenticatorId(provider.first, userId);
+            return provider.getAuthenticatorId(sensorId, userId);
         }
 
         @Override // Binder call
@@ -454,13 +453,13 @@
                 String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName);
                 return;
             }
 
-            provider.second.scheduleResetLockout(provider.first, userId, hardwareAuthToken);
+            provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
         }
 
         @Override
@@ -499,7 +498,8 @@
                 @BiometricManager.Authenticators.Types int strength) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             mServiceProviders.add(
-                    new Face10(getContext(), sensorId, strength, mLockoutResetDispatcher));
+                    new com.android.server.biometrics.sensors.face.hidl.Face10(getContext(),
+                            sensorId, strength, mLockoutResetDispatcher));
         }
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/UsageStats.java b/services/core/java/com/android/server/biometrics/sensors/face/UsageStats.java
index 4841bf4..d99abcd 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/UsageStats.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/UsageStats.java
@@ -28,7 +28,7 @@
  * Keep a short historical buffer of stats, with an aggregated usage time.
  */
 
-class UsageStats {
+public class UsageStats {
     private static final int EVENT_LOG_SIZE = 100;
 
     /**
@@ -44,7 +44,7 @@
         private int mVendorError;
         private int mUser;
 
-        AuthenticationEvent(long startTime, long latency, boolean authenticated, int error,
+        public AuthenticationEvent(long startTime, long latency, boolean authenticated, int error,
                 int vendorError, int user) {
             mStartTime = startTime;
             mLatency = latency;
@@ -76,14 +76,14 @@
     private long mRejectLatency;
     private SparseLongArray mErrorLatency;
 
-    UsageStats(Context context) {
+    public UsageStats(Context context) {
         mAuthenticationEvents = new ArrayDeque<>();
         mErrorCount = new SparseIntArray();
         mErrorLatency = new SparseLongArray();
         mContext = context;
     }
 
-    void addEvent(AuthenticationEvent event) {
+    public void addEvent(AuthenticationEvent event) {
         if (mAuthenticationEvents.size() >= EVENT_LOG_SIZE) {
             mAuthenticationEvents.removeFirst();
         }
@@ -101,7 +101,7 @@
         }
     }
 
-    void print(PrintWriter pw) {
+    public void print(PrintWriter pw) {
         pw.println("Events since last reboot: " + mAuthenticationEvents.size());
         for (AuthenticationEvent event : mAuthenticationEvents) {
             pw.println(event.toString(mContext));
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
similarity index 76%
rename from services/core/java/com/android/server/biometrics/sensors/face/Face10.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 15f8c53..7b70bd8a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -63,6 +63,10 @@
 import com.android.server.biometrics.sensors.LockoutTracker;
 import com.android.server.biometrics.sensors.PerformanceTracker;
 import com.android.server.biometrics.sensors.RemovalConsumer;
+import com.android.server.biometrics.sensors.face.FaceUtils;
+import com.android.server.biometrics.sensors.face.LockoutHalImpl;
+import com.android.server.biometrics.sensors.face.ServiceProvider;
+import com.android.server.biometrics.sensors.face.UsageStats;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -82,7 +86,7 @@
  * Supports a single instance of the {@link android.hardware.biometrics.face.V1_0} or
  * its extended minor versions.
  */
-class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
+public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
 
     private static final String TAG = "Face10";
     private static final int ENROLL_TIMEOUT_SEC = 75;
@@ -120,166 +124,175 @@
 
     private final IBiometricsFaceClientCallback mDaemonCallback =
             new IBiometricsFaceClientCallback.Stub() {
-        @Override
-        public void onEnrollResult(long deviceId, int faceId, int userId, int remaining) {
-            mHandler.post(() -> {
-                final CharSequence name = FaceUtils.getInstance()
-                        .getUniqueName(mContext, userId);
-                final Face face = new Face(name, faceId, deviceId);
+                @Override
+                public void onEnrollResult(long deviceId, int faceId, int userId, int remaining) {
+                    mHandler.post(() -> {
+                        final CharSequence name = FaceUtils.getInstance()
+                                .getUniqueName(mContext, userId);
+                        final Face face = new Face(name, faceId, deviceId);
 
-                final ClientMonitor<?> client = mScheduler.getCurrentClient();
-                if (!(client instanceof FaceEnrollClient)) {
-                    Slog.e(TAG, "onEnrollResult for non-enroll client: "
-                            + Utils.getClientName(client));
-                    return;
+                        final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                        if (!(client instanceof FaceEnrollClient)) {
+                            Slog.e(TAG, "onEnrollResult for non-enroll client: "
+                                    + Utils.getClientName(client));
+                            return;
+                        }
+
+                        final FaceEnrollClient enrollClient = (FaceEnrollClient) client;
+                        enrollClient.onEnrollResult(face, remaining);
+                    });
                 }
 
-                final FaceEnrollClient enrollClient = (FaceEnrollClient) client;
-                enrollClient.onEnrollResult(face, remaining);
-            });
-        }
+                @Override
+                public void onAuthenticated(long deviceId, int faceId, int userId,
+                        ArrayList<Byte> token) {
+                    mHandler.post(() -> {
+                        final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                        if (!(client instanceof AuthenticationConsumer)) {
+                            Slog.e(TAG, "onAuthenticated for non-authentication consumer: "
+                                    + Utils.getClientName(client));
+                            return;
+                        }
 
-        @Override
-        public void onAuthenticated(long deviceId, int faceId, int userId, ArrayList<Byte> token) {
-            mHandler.post(() -> {
-                final ClientMonitor<?> client = mScheduler.getCurrentClient();
-                if (!(client instanceof AuthenticationConsumer)) {
-                    Slog.e(TAG, "onAuthenticated for non-authentication consumer: "
-                            + Utils.getClientName(client));
-                    return;
+                        final AuthenticationConsumer authenticationConsumer =
+                                (AuthenticationConsumer) client;
+                        final boolean authenticated = faceId != 0;
+                        final Face face = new Face("", faceId, deviceId);
+                        authenticationConsumer.onAuthenticated(face, authenticated, token);
+                    });
                 }
 
-                final AuthenticationConsumer authenticationConsumer =
-                        (AuthenticationConsumer) client;
-                final boolean authenticated = faceId != 0;
-                final Face face = new Face("", faceId, deviceId);
-                authenticationConsumer.onAuthenticated(face, authenticated, token);
-            });
-        }
+                @Override
+                public void onAcquired(long deviceId, int userId, int acquiredInfo,
+                        int vendorCode) {
+                    mHandler.post(() -> {
+                        final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                        if (!(client instanceof AcquisitionClient)) {
+                            Slog.e(TAG, "onAcquired for non-acquire client: "
+                                    + Utils.getClientName(client));
+                            return;
+                        }
 
-        @Override
-        public void onAcquired(long deviceId, int userId, int acquiredInfo, int vendorCode) {
-            mHandler.post(() -> {
-                final ClientMonitor<?> client = mScheduler.getCurrentClient();
-                if (!(client instanceof AcquisitionClient)) {
-                    Slog.e(TAG, "onAcquired for non-acquire client: "
-                            + Utils.getClientName(client));
-                    return;
+                        final AcquisitionClient<?> acquisitionClient =
+                                (AcquisitionClient<?>) client;
+                        acquisitionClient.onAcquired(acquiredInfo, vendorCode);
+                    });
                 }
 
-                final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client;
-                acquisitionClient.onAcquired(acquiredInfo, vendorCode);
-            });
-        }
+                @Override
+                public void onError(long deviceId, int userId, int error, int vendorCode) {
+                    mHandler.post(() -> {
+                        final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                        Slog.d(TAG, "handleError"
+                                + ", client: " + (client != null ? client.getOwnerString() : null)
+                                + ", error: " + error
+                                + ", vendorCode: " + vendorCode);
+                        if (!(client instanceof Interruptable)) {
+                            Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(
+                                    client));
+                            return;
+                        }
 
-        @Override
-        public void onError(long deviceId, int userId, int error, int vendorCode) {
-            mHandler.post(() -> {
-                final ClientMonitor<?> client = mScheduler.getCurrentClient();
-                Slog.d(TAG, "handleError"
-                        + ", client: " + (client != null ? client.getOwnerString() : null)
-                        + ", error: " + error
-                        + ", vendorCode: " + vendorCode);
-                if (!(client instanceof Interruptable)) {
-                    Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(client));
-                    return;
+                        final Interruptable interruptable = (Interruptable) client;
+                        interruptable.onError(error, vendorCode);
+
+                        if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
+                            Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
+                            mDaemon = null;
+                            mCurrentUserId = UserHandle.USER_NULL;
+                        }
+                    });
                 }
 
-                final Interruptable interruptable = (Interruptable) client;
-                interruptable.onError(error, vendorCode);
+                @Override
+                public void onRemoved(long deviceId, ArrayList<Integer> removed, int userId) {
+                    mHandler.post(() -> {
+                        final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                        if (!(client instanceof RemovalConsumer)) {
+                            Slog.e(TAG, "onRemoved for non-removal consumer: "
+                                    + Utils.getClientName(client));
+                            return;
+                        }
 
-                if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
-                    Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
-                    mDaemon = null;
-                    mCurrentUserId = UserHandle.USER_NULL;
-                }
-            });
-        }
+                        final RemovalConsumer removalConsumer = (RemovalConsumer) client;
 
-        @Override
-        public void onRemoved(long deviceId, ArrayList<Integer> removed, int userId) {
-            mHandler.post(() -> {
-                final ClientMonitor<?> client = mScheduler.getCurrentClient();
-                if (!(client instanceof RemovalConsumer)) {
-                    Slog.e(TAG, "onRemoved for non-removal consumer: "
-                            + Utils.getClientName(client));
-                    return;
+                        if (!removed.isEmpty()) {
+                            // Convert to old fingerprint-like behavior, where remove() receives
+                            // one removal
+                            // at a time. This way, remove can share some more common code.
+                            for (int i = 0; i < removed.size(); i++) {
+                                final int id = removed.get(i);
+                                final Face face = new Face("", id, deviceId);
+                                final int remaining = removed.size() - i - 1;
+                                Slog.d(TAG, "Removed, faceId: " + id + ", remaining: " + remaining);
+                                removalConsumer.onRemoved(face, remaining);
+                            }
+                        } else {
+                            removalConsumer.onRemoved(null, 0 /* remaining */);
+                        }
+
+                        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                                Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, UserHandle.USER_CURRENT);
+                    });
                 }
 
-                final RemovalConsumer removalConsumer = (RemovalConsumer) client;
+                @Override
+                public void onEnumerate(long deviceId, ArrayList<Integer> faceIds, int userId) {
+                    mHandler.post(() -> {
+                        final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                        if (!(client instanceof EnumerateConsumer)) {
+                            Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
+                                    + Utils.getClientName(client));
+                            return;
+                        }
 
-                if (!removed.isEmpty()) {
-                    // Convert to old fingerprint-like behavior, where remove() receives one removal
-                    // at a time. This way, remove can share some more common code.
-                    for (int i = 0; i < removed.size(); i++) {
-                        final int id = removed.get(i);
-                        final Face face = new Face("", id, deviceId);
-                        final int remaining = removed.size() - i - 1;
-                        Slog.d(TAG, "Removed, faceId: " + id + ", remaining: " + remaining);
-                        removalConsumer.onRemoved(face, remaining);
-                    }
-                } else {
-                    removalConsumer.onRemoved(null, 0 /* remaining */);
+                        final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
+
+                        if (!faceIds.isEmpty()) {
+                            // Convert to old fingerprint-like behavior, where enumerate()
+                            // receives one
+                            // template at a time. This way, enumerate can share some more common
+                            // code.
+                            for (int i = 0; i < faceIds.size(); i++) {
+                                final Face face = new Face("", faceIds.get(i), deviceId);
+                                enumerateConsumer.onEnumerationResult(face, faceIds.size() - i - 1);
+                            }
+                        } else {
+                            // For face, the HIDL contract is to receive an empty list when there
+                            // are no
+                            // templates enrolled. Send a null identifier since we don't consume
+                            // them
+                            // anywhere, and send remaining == 0 so this code can be shared with
+                            // Fingerprint@2.1
+                            enumerateConsumer.onEnumerationResult(null /* identifier */, 0);
+                        }
+                    });
                 }
 
-                Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                        Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, UserHandle.USER_CURRENT);
-            });
-        }
+                @Override
+                public void onLockoutChanged(long duration) {
+                    mHandler.post(() -> {
+                        Slog.d(TAG, "onLockoutChanged: " + duration);
+                        final @LockoutTracker.LockoutMode int lockoutMode;
+                        if (duration == 0) {
+                            lockoutMode = LockoutTracker.LOCKOUT_NONE;
+                        } else if (duration == -1 || duration == Long.MAX_VALUE) {
+                            lockoutMode = LockoutTracker.LOCKOUT_PERMANENT;
+                        } else {
+                            lockoutMode = LockoutTracker.LOCKOUT_TIMED;
+                        }
 
-        @Override
-        public void onEnumerate(long deviceId, ArrayList<Integer> faceIds, int userId) {
-            mHandler.post(() -> {
-                final ClientMonitor<?> client = mScheduler.getCurrentClient();
-                if (!(client instanceof EnumerateConsumer)) {
-                    Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
-                            + Utils.getClientName(client));
-                    return;
+                        mLockoutTracker.setCurrentUserLockoutMode(lockoutMode);
+
+                        if (duration == 0) {
+                            mLockoutResetDispatcher.notifyLockoutResetCallbacks(mSensorId);
+                        }
+                    });
                 }
-
-                final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
-
-                if (!faceIds.isEmpty()) {
-                    // Convert to old fingerprint-like behavior, where enumerate() receives one
-                    // template at a time. This way, enumerate can share some more common code.
-                    for (int i = 0; i < faceIds.size(); i++) {
-                        final Face face = new Face("", faceIds.get(i), deviceId);
-                        enumerateConsumer.onEnumerationResult(face, faceIds.size() - i - 1);
-                    }
-                } else {
-                    // For face, the HIDL contract is to receive an empty list when there are no
-                    // templates enrolled. Send a null identifier since we don't consume them
-                    // anywhere, and send remaining == 0 so this code can be shared with
-                    // Fingerprint@2.1
-                    enumerateConsumer.onEnumerationResult(null /* identifier */, 0);
-                }
-            });
-        }
-
-        @Override
-        public void onLockoutChanged(long duration) {
-            mHandler.post(() -> {
-                Slog.d(TAG, "onLockoutChanged: " + duration);
-                final @LockoutTracker.LockoutMode int lockoutMode;
-                if (duration == 0) {
-                    lockoutMode = LockoutTracker.LOCKOUT_NONE;
-                } else if (duration == -1 || duration == Long.MAX_VALUE) {
-                    lockoutMode = LockoutTracker.LOCKOUT_PERMANENT;
-                } else {
-                    lockoutMode = LockoutTracker.LOCKOUT_TIMED;
-                }
-
-                mLockoutTracker.setCurrentUserLockoutMode(lockoutMode);
-
-                if (duration == 0) {
-                    mLockoutResetDispatcher.notifyLockoutResetCallbacks(mSensorId);
-                }
-            });
-        }
-    };
+            };
 
     @VisibleForTesting
-    Face10(@NonNull Context context, int sensorId,
+    public Face10(@NonNull Context context, int sensorId,
             @BiometricManager.Authenticators.Types int strength,
             @NonNull LockoutResetDispatcher lockoutResetDispatcher,
             boolean supportsSelfIllumination, int maxTemplatesAllowed) {
@@ -304,7 +317,7 @@
         }
     }
 
-    Face10(@NonNull Context context, int sensorId,
+    public Face10(@NonNull Context context, int sensorId,
             @BiometricManager.Authenticators.Types int strength,
             @NonNull LockoutResetDispatcher lockoutResetDispatcher) {
         this(context, sensorId, strength, lockoutResetDispatcher,
@@ -479,8 +492,8 @@
     public void scheduleRevokeChallenge(int sensorId, int userId, @NonNull IBinder token,
             @NonNull String opPackageName, long challenge) {
         mHandler.post(() -> {
-            if (mCurrentChallengeOwner != null &&
-                    !mCurrentChallengeOwner.getOwnerString().contentEquals(opPackageName)) {
+            if (mCurrentChallengeOwner != null
+                    && !mCurrentChallengeOwner.getOwnerString().contentEquals(opPackageName)) {
                 Slog.e(TAG, "scheduleRevokeChallenge, package: " + opPackageName
                         + " attempting to revoke challenge owned by: "
                         + mCurrentChallengeOwner.getOwnerString());
@@ -717,10 +730,10 @@
             JSONArray sets = new JSONArray();
             for (UserInfo user : UserManager.get(mContext).getUsers()) {
                 final int userId = user.getUserHandle().getIdentifier();
-                final int N = FaceUtils.getInstance().getBiometricsForUser(mContext, userId).size();
+                final int c = FaceUtils.getInstance().getBiometricsForUser(mContext, userId).size();
                 JSONObject set = new JSONObject();
                 set.put("id", userId);
-                set.put("count", N);
+                set.put("count", c);
                 set.put("accept", performanceTracker.getAcceptForUser(userId));
                 set.put("reject", performanceTracker.getRejectForUser(userId));
                 set.put("acquire", performanceTracker.getAcquireForUser(userId));
@@ -816,7 +829,7 @@
             try {
                 devnull = new FileOutputStream("/dev/null");
                 final NativeHandle handle = new NativeHandle(
-                        new FileDescriptor[] { devnull.getFD(), fd },
+                        new FileDescriptor[]{devnull.getFD(), fd},
                         new int[0], false);
                 daemon.debug(handle, new ArrayList<String>(Arrays.asList(args)));
             } catch (IOException | RemoteException ex) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
similarity index 98%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
index 892d6a4..ce880aa 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.app.Notification;
@@ -40,6 +40,7 @@
 import com.android.server.biometrics.sensors.AuthenticationClient;
 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
 import com.android.server.biometrics.sensors.LockoutTracker;
+import com.android.server.biometrics.sensors.face.UsageStats;
 
 import java.util.ArrayList;
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java
similarity index 98%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java
index 989b5c9..1a7544fc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClient.java
similarity index 96%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClient.java
index 406a7cc..c3d54c2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGenerateChallengeClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -24,7 +24,6 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.server.biometrics.sensors.ClientMonitor;
 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
 import com.android.server.biometrics.sensors.GenerateChallengeClient;
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java
similarity index 98%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java
index 33b2b6a..e25bb81 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalCleanupClient.java
similarity index 97%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceInternalCleanupClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalCleanupClient.java
index 7626587..abfda49 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceInternalCleanupClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalCleanupClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.content.Context;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceInternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalEnumerateClient.java
similarity index 97%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceInternalEnumerateClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalEnumerateClient.java
index 4166dff..9a0974b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceInternalEnumerateClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceInternalEnumerateClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.content.Context;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java
similarity index 97%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceRemovalClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java
index 31ae3a3..acae899 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.content.Context;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java
similarity index 97%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java
index f4324be..8df9b9f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.content.Context;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceRevokeChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRevokeChallengeClient.java
similarity index 96%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceRevokeChallengeClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRevokeChallengeClient.java
index a10c573..e5edfaf 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceRevokeChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRevokeChallengeClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.content.Context;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java
similarity index 98%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java
index 94abb7f..0e20728 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.content.Context;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
similarity index 98%
rename from services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java
rename to services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
index 05b176d..22275e5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors.face;
+package com.android.server.biometrics.sensors.face.hidl;
 
 import android.annotation.NonNull;
 import android.content.Context;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index 4b59112..f77bc79 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -30,11 +30,12 @@
  */
 public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub {
     private final IFingerprintService mFingerprintService;
+    private final int mSensorId;
 
     public FingerprintAuthenticator(IFingerprintService fingerprintService, SensorConfig config)
             throws RemoteException {
         mFingerprintService = fingerprintService;
-        mFingerprintService.initializeConfiguration(config.id, config.strength);
+        mSensorId = config.id;
     }
 
     @Override
@@ -42,40 +43,40 @@
             long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
             String opPackageName, int cookie, int callingUid, int callingPid, int callingUserId)
             throws RemoteException {
-        mFingerprintService.prepareForAuthentication(token, operationId, userId, sensorReceiver,
-                opPackageName, cookie, callingUid, callingPid, callingUserId);
+        mFingerprintService.prepareForAuthentication(mSensorId, token, operationId, userId,
+                sensorReceiver, opPackageName, cookie, callingUid, callingPid, callingUserId);
     }
 
     @Override
     public void startPreparedClient(int cookie) throws RemoteException {
-        mFingerprintService.startPreparedClient(cookie);
+        mFingerprintService.startPreparedClient(mSensorId, cookie);
     }
 
     @Override
     public void cancelAuthenticationFromService(IBinder token, String opPackageName, int callingUid,
             int callingPid, int callingUserId) throws RemoteException {
-        mFingerprintService.cancelAuthenticationFromService(token, opPackageName, callingUid,
-                callingPid, callingUserId);
+        mFingerprintService.cancelAuthenticationFromService(mSensorId, token, opPackageName,
+                callingUid, callingPid, callingUserId);
     }
 
     @Override
     public boolean isHardwareDetected(String opPackageName) throws RemoteException {
-        return mFingerprintService.isHardwareDetected(opPackageName);
+        return mFingerprintService.isHardwareDetected(mSensorId, opPackageName);
     }
 
     @Override
     public boolean hasEnrolledTemplates(int userId, String opPackageName) throws RemoteException {
-        return mFingerprintService.hasEnrolledFingerprints(userId, opPackageName);
+        return mFingerprintService.hasEnrolledFingerprints(mSensorId, userId, opPackageName);
     }
 
     @Override
     public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId)
             throws RemoteException {
-        return mFingerprintService.getLockoutModeForUser(userId);
+        return mFingerprintService.getLockoutModeForUser(mSensorId, userId);
     }
 
     @Override
     public long getAuthenticatorId(int callingUserId) throws RemoteException {
-        return mFingerprintService.getAuthenticatorId(callingUserId);
+        return mFingerprintService.getAuthenticatorId(mSensorId, callingUserId);
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 265ba05..99569b1 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -255,34 +255,34 @@
         }
 
         @Override // Binder call
-        public void prepareForAuthentication(IBinder token, long operationId, int userId,
-                IBiometricSensorReceiver sensorReceiver, String opPackageName,
+        public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
+                int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
                 int cookie, int callingUid, int callingPid, int callingUserId) {
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for prepareForAuthentication");
                 return;
             }
 
             final boolean restricted = true; // BiometricPrompt is always restricted
-            provider.second.scheduleAuthenticate(provider.first, token, operationId, userId, cookie,
+            provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
                     new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted,
                     BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, false /* isKeyguard */);
         }
 
         @Override // Binder call
-        public void startPreparedClient(int cookie) {
+        public void startPreparedClient(int sensorId, int cookie) {
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for startPreparedClient");
                 return;
             }
 
-            provider.second.startPreparedClient(provider.first, cookie);
+            provider.startPreparedClient(sensorId, cookie);
         }
 
 
@@ -328,17 +328,17 @@
         }
 
         @Override // Binder call
-        public void cancelAuthenticationFromService(final IBinder token, final String opPackageName,
-                int callingUid, int callingPid, int callingUserId) {
+        public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
+                final String opPackageName, int callingUid, int callingPid, int callingUserId) {
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
                 return;
             }
 
-            provider.second.cancelAuthentication(provider.first, token);
+            provider.cancelAuthentication(sensorId, token);
         }
 
         @Override // Binder call
@@ -402,7 +402,7 @@
         }
 
         @Override // Binder call
-        public boolean isHardwareDetected(String opPackageName) {
+        public boolean isHardwareDetectedDeprecated(String opPackageName) {
             if (!canUseFingerprint(opPackageName, false /* foregroundOnly */,
                     Binder.getCallingUid(), Binder.getCallingPid(),
                     UserHandle.getCallingUserId())) {
@@ -413,7 +413,8 @@
             try {
                 final Pair<Integer, ServiceProvider> provider = getSingleProvider();
                 if (provider == null) {
-                    Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
+                    Slog.w(TAG, "Null provider for isHardwareDetectedDeprecated, caller: "
+                            + opPackageName);
                     return false;
                 }
                 return provider.second.isHardwareDetected(provider.first);
@@ -423,6 +424,19 @@
         }
 
         @Override // Binder call
+        public boolean isHardwareDetected(int sensorId, String opPackageName) {
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
+                return false;
+            }
+
+            return provider.isHardwareDetected(sensorId);
+        }
+
+        @Override // Binder call
         public void rename(final int fingerId, final int userId, final String name) {
             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
             if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
@@ -450,11 +464,11 @@
                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
             }
 
-            return FingerprintService.this.getEnrolledFingerprints(userId, opPackageName);
+            return FingerprintService.this.getEnrolledFingerprintsDeprecated(userId, opPackageName);
         }
 
         @Override // Binder call
-        public boolean hasEnrolledFingerprints(int userId, String opPackageName) {
+        public boolean hasEnrolledFingerprintsDeprecated(int userId, String opPackageName) {
             if (!canUseFingerprint(opPackageName, false /* foregroundOnly */,
                     Binder.getCallingUid(), Binder.getCallingPid(),
                     UserHandle.getCallingUserId())) {
@@ -464,7 +478,7 @@
             if (userId != UserHandle.getCallingUserId()) {
                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
             }
-            return !FingerprintService.this.getEnrolledFingerprints(userId, opPackageName)
+            return !FingerprintService.this.getEnrolledFingerprintsDeprecated(userId, opPackageName)
                     .isEmpty();
         }
 
@@ -489,28 +503,40 @@
             return false;
         }
 
-        @Override // Binder call
-        public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) {
+        public boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for hasEnrolledFingerprints, caller: " + opPackageName);
+                return false;
+            }
+
+            return provider.getEnrolledFingerprints(sensorId, userId).size() > 0;
+        }
+
+        @Override // Binder call
+        public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for getLockoutModeForUser");
                 return LockoutTracker.LOCKOUT_NONE;
             }
-            return provider.second.getLockoutModeForUser(provider.first, userId);
+            return provider.getLockoutModeForUser(sensorId, userId);
         }
 
         @Override // Binder call
-        public long getAuthenticatorId(int userId) {
+        public long getAuthenticatorId(int sensorId, int userId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for getAuthenticatorId");
                 return 0;
             }
-            return provider.second.getAuthenticatorId(provider.first, userId);
+            return provider.getAuthenticatorId(sensorId, userId);
         }
 
         @Override // Binder call
@@ -691,10 +717,11 @@
     }
 
     @NonNull
-    private List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName) {
+    private List<Fingerprint> getEnrolledFingerprintsDeprecated(int userId, String opPackageName) {
         final Pair<Integer, ServiceProvider> provider = getSingleProvider();
         if (provider == null) {
-            Slog.w(TAG, "Null provider for getEnrolledFingerprints, caller: " + opPackageName);
+            Slog.w(TAG, "Null provider for getEnrolledFingerprintsDeprecated, caller: "
+                    + opPackageName);
             return Collections.emptyList();
         }
 
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index d548871..17828a0 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -95,7 +95,11 @@
 
     private static final boolean DBG = false;
 
+    // This context is for the current user.
     private final Context mContext;
+    // This context is for all users, so register a BroadcastReceiver which can receive intents from
+    // all users.
+    private final Context mUserAllContext;
     private final Handler mHandler;
     private final Clock mClock;
     private final Dependencies mDeps;
@@ -132,6 +136,7 @@
 
     public MultipathPolicyTracker(Context ctx, Handler handler, Dependencies deps) {
         mContext = ctx;
+        mUserAllContext = ctx.createContextAsUser(UserHandle.ALL, 0 /* flags */);
         mHandler = handler;
         mClock = deps.getClock();
         mDeps = deps;
@@ -155,8 +160,8 @@
 
         final IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
-        mContext.registerReceiverAsUser(
-                mConfigChangeReceiver, UserHandle.ALL, intentFilter, null, mHandler);
+        mUserAllContext.registerReceiver(
+                mConfigChangeReceiver, intentFilter, null /* broadcastPermission */, mHandler);
     }
 
     public void shutdown() {
@@ -167,7 +172,7 @@
         }
         mMultipathTrackers.clear();
         mResolver.unregisterContentObserver(mSettingsObserver);
-        mContext.unregisterReceiver(mConfigChangeReceiver);
+        mUserAllContext.unregisterReceiver(mConfigChangeReceiver);
     }
 
     // Called on an arbitrary binder thread.
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 4d39989..6ac3e4a 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -25,6 +25,7 @@
 import static android.net.RouteInfo.RTN_THROW;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 
+import static com.android.internal.util.Preconditions.checkArgument;
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.Manifest;
@@ -865,7 +866,7 @@
             Intent serviceIntent = new Intent(VpnConfig.SERVICE_INTERFACE);
             serviceIntent.setPackage(alwaysOnPackage);
             try {
-                return mContext.startServiceAsUser(serviceIntent, UserHandle.of(mUserId)) != null;
+                return mUserIdContext.startService(serviceIntent) != null;
             } catch (RuntimeException e) {
                 Log.e(TAG, "VpnService " + serviceIntent + " failed to start", e);
                 return false;
@@ -1036,20 +1037,21 @@
 
         final long token = Binder.clearCallingIdentity();
         try {
-            final int[] toChange;
+            final String[] toChange;
 
             // Clear all AppOps if the app is being unauthorized.
             switch (vpnType) {
                 case VpnManager.TYPE_VPN_NONE:
-                    toChange = new int[] {
-                            AppOpsManager.OP_ACTIVATE_VPN, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN
+                    toChange = new String[] {
+                            AppOpsManager.OPSTR_ACTIVATE_VPN,
+                            AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN
                     };
                     break;
                 case VpnManager.TYPE_VPN_PLATFORM:
-                    toChange = new int[] {AppOpsManager.OP_ACTIVATE_PLATFORM_VPN};
+                    toChange = new String[] {AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN};
                     break;
                 case VpnManager.TYPE_VPN_SERVICE:
-                    toChange = new int[] {AppOpsManager.OP_ACTIVATE_VPN};
+                    toChange = new String[] {AppOpsManager.OPSTR_ACTIVATE_VPN};
                     break;
                 default:
                     Log.wtf(TAG, "Unrecognized VPN type while granting authorization");
@@ -1058,9 +1060,9 @@
 
             final AppOpsManager appOpMgr =
                     (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
-            for (final int appOp : toChange) {
+            for (final String appOpStr : toChange) {
                 appOpMgr.setMode(
-                        appOp,
+                        appOpStr,
                         uid,
                         packageName,
                         vpnType == VpnManager.TYPE_VPN_NONE
@@ -1086,21 +1088,22 @@
         }
     }
 
-    private static boolean doesPackageHaveAppop(Context context, String packageName, int appop) {
+    private static boolean doesPackageHaveAppop(Context context, String packageName,
+            String appOpStr) {
         final AppOpsManager appOps =
                 (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
 
         // Verify that the caller matches the given package and has the required permission.
-        return appOps.noteOpNoThrow(appop, Binder.getCallingUid(), packageName)
-                == AppOpsManager.MODE_ALLOWED;
+        return appOps.noteOpNoThrow(appOpStr, Binder.getCallingUid(), packageName,
+                null /* attributionTag */, null /* message */) == AppOpsManager.MODE_ALLOWED;
     }
 
     private static boolean isVpnServicePreConsented(Context context, String packageName) {
-        return doesPackageHaveAppop(context, packageName, AppOpsManager.OP_ACTIVATE_VPN);
+        return doesPackageHaveAppop(context, packageName, AppOpsManager.OPSTR_ACTIVATE_VPN);
     }
 
     private static boolean isVpnProfilePreConsented(Context context, String packageName) {
-        return doesPackageHaveAppop(context, packageName, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN)
+        return doesPackageHaveAppop(context, packageName, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN)
                 || isVpnServicePreConsented(context, packageName);
     }
 
@@ -2757,6 +2760,8 @@
 
         LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd, VpnProfile profile) {
             super(TAG);
+            checkArgument(racoon != null || mtpd != null, "Arguments to racoon and mtpd "
+                    + "must not both be null");
             mConfig = config;
             mDaemons = new String[] {"racoon", "mtpd"};
             // TODO: clear arguments from memory once launched
@@ -2913,15 +2918,6 @@
                 }
                 new File("/data/misc/vpn/abort").delete();
 
-                // Check if we need to restart any of the daemons.
-                boolean restart = false;
-                for (String[] arguments : mArguments) {
-                    restart = restart || (arguments != null);
-                }
-                if (!restart) {
-                    agentDisconnect();
-                    return;
-                }
                 updateState(DetailedState.CONNECTING, "execute");
 
                 // Start the daemon with arguments.
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index 62630300..fa03e59 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -60,12 +60,12 @@
 import android.net.ipsec.ike.TunnelModeChildSessionParams;
 import android.net.ipsec.ike.exceptions.IkeException;
 import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.net.util.IpRange;
 import android.system.OsConstants;
 import android.util.Log;
 
 import com.android.internal.net.VpnProfile;
 import com.android.internal.util.HexDump;
+import com.android.net.module.util.IpRange;
 
 import java.net.Inet4Address;
 import java.net.Inet6Address;
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 6a4ca8d..0b2d4d7 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -151,6 +151,8 @@
  * run at a later time. Similarly, when a sync succeeds, backoff is cleared and all associated syncs
  * are rescheduled. A rescheduled sync will get a new jobId.
  *
+ * See also {@code SyncManager.md} in the same directory for how app-standby affects sync adapters.
+ *
  * @hide
  */
 public class SyncManager {
diff --git a/services/core/java/com/android/server/content/SyncManager.md b/services/core/java/com/android/server/content/SyncManager.md
new file mode 100644
index 0000000..8507abd
--- /dev/null
+++ b/services/core/java/com/android/server/content/SyncManager.md
@@ -0,0 +1,122 @@
+# Sync Manager notes
+
+## App-standby and Sync Manager
+
+Android 9 Pie introduced
+["App Standby Buckets"](https://developer.android.com/topic/performance/appstandby), which throttles various things
+including
+[JobScheduler](https://developer.android.com/reference/android/app/job/JobScheduler)
+and [AlarmManager](https://developer.android.com/reference/android/app/AlarmManager),
+[among other things](https://developer.android.com/topic/performance/power/power-details),
+for background applications.
+
+Because SyncManager executes sync operations as JobScheduler jobs, sync operations are subject
+to the same throttling.
+
+However, unlike JobScheduler jobs, any apps (with the proper permission) can schedule a sync
+operation in any other apps using
+[ContentResolver.requestSync()](https://developer.android.com/reference/android/content/ContentResolver#requestSync(android.content.SyncRequest)),
+whch means it's possible for a foreground app to request a sync in another app that is either in the
+background or is not even running.
+For example, when the user hits the refresh button on the Contacts app, it'll
+request sync to all the contacts sync adapters, which are implemented in other packages (and they're
+likely not in the foreground).
+
+Because of this, calls to
+[ContentResolver.requestSync()](https://developer.android.com/reference/android/content/ContentResolver#requestSync(android.content.SyncRequest))
+made by foreground apps are special cased such that the resulting sync operations will be
+exempted from app-standby throttling.
+
+### Two Levels of Exemption
+Specifically, there are two different levels of exemption, depending on the state of the caller:
+1. `ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET`
+2. `ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP`, which is more powerful than 1.
+
+The exemption level is calculated in
+[ContentService.getSyncExemptionAndCleanUpExtrasForCaller()](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/content/ContentService.java?q=%22int%20getSyncExemptionAndCleanUpExtrasForCaller%22&ss=android%2Fplatform%2Fsuperproject),
+which was [implemented slightly differently](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/content/ContentService.java?q=%22int%20getSyncExemptionAndCleanUpExtrasForCaller%22&ss=android%2Fplatform%2Fsuperproject)
+in Android 9, compared to Android 10 and later.
+
+The logic is as follows:
+- When the caller's procstate is `PROCESS_STATE_TOP` or above,
+  meaning if the caller has a foreground activity,
+  `SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP` will be set.
+
+- Otherwise, when the caller's procstate is `PROCESS_STATE_IMPORTANT_FOREGROUND` or above,
+  e.g. when the caller has a foreground service, a service bound by the system of a specific kind,
+  `SYNC_EXEMPTION_PROMOTE_BUCKET` will be set.
+
+- Additionally, on Android 10 and later, when the caller is
+  "UID-active" (but the procstate is below `PROCESS_STATE_TOP`),
+  `SYNC_EXEMPTION_PROMOTE_BUCKET` will be set.
+  This is what happens when the app has just received a high-priority FCM, for example.
+  Temp-allowlist is also used in various other situations.
+
+### Behavior of Each Exemption
+
+The exemptions are tracked in `SyncOperation.syncExemptionFlag`.
+
+- Behavior of `SYNC_EXEMPTION_PROMOTE_BUCKET`
+  - This will add `JobInfo.FLAG_EXEMPT_FROM_APP_STANDBY` to the sync job. This makes the job
+    subject to "ACTIVE" app quota, so minimum deferral will be applied to it.
+
+  - This also reports `AppStandbyController.reportExemptedSyncStart()`, so the package that owns
+    the sync adapter is temporarily put in the "ACTIVE" bucket for the
+    duration of `mExemptedSyncStartTimeoutMillis`, whose default is 10 minutes as of 2020-10-23.
+
+    This will allow the app to access network, even if it has been in the `RARE` bucket
+    (in which case, the system cuts its network access).
+
+    Note if the device is dozing or in battery saver, promoting to the "ACTIVE" bucket will still
+    _not_ give the app network access.
+
+- Behavior of `SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP`
+  - This gives all the perks given by `SYNC_EXEMPTION_PROMOTE_BUCKET`, plus puts the target app
+    in the temp-allowlist (by calling `DeviceIdleInternal.addPowerSaveTempWhitelistApp()`)
+    for the duration of `SyncManagerConstants.getKeyExemptionTempWhitelistDurationInSeconds()`,
+    whose default is 10 minutes.
+
+    Temp-allowlist will grant the app network access even if the device is in doze or in battery
+    saver.
+
+    (However, note that when the device is dozing, sync jobs will not run anyway.)
+
+### How Retries Are Handled
+
+- When a sync operation needs a retry, SyncManager creates a new operation (job) with a back-off
+  (in `SyncManager.maybeRescheduleSync()`). In this case, the new sync operation will inherit
+  `SyncOperation.syncExemptionFlag`, unless the number of retries (not counting the original sync
+  job) is equal to or greater than `SyncManagerConstants.getMaxRetriesWithAppStandbyExemption()`,
+  whose default is 5.
+
+### Special-handling of Pre-installed Packages
+
+- When a content provider is accessed, `AppStandbyController.reportContentProviderUsage()` is
+  triggered, which elevates the standby bucket of the associated sync adapters' packages to `ACTIVE`
+  for the duration of `mSyncAdapterTimeoutMillis`, whose default is 10 minutes, but _only for_
+  pre-installed packages. This is to help pre-installed sync adapters, which often don't have UI,
+  sync properly.
+
+- Also, since Android 11, all the pre-installed apps with no activities will be kept in
+  the `ACTIVE` bucket, which greatly relaxes app-standby throttling. But they're still subject
+  to doze and battery saver.
+
+### Summary
+
+- When the device is dozing, no sync operations will be executed.
+
+- Normally, sync operations are subject to App-Standby, which throttles jobs owned by background
+  apps. Jobs owned by foreground apps are not affected.
+
+- A sync operation requested by a foreground activity will be executed immediately even if the
+  app owning the sync adapter is in RARE bucket, and the device is in battery saver.
+
+- A sync operation requested by a foreground service (or a "bound foreground" service)
+  will be executed immediately even if the app owning the sync adapter is in RARE bucket,
+  *unless* the device is in battery saver.
+
+  Since Android 9 and later, the same thing will happen if the requester is temp-allowlisted (e.g.
+  when it has just received a "high-priority FCM").
+
+- There are certain exemptions for pre-installed apps, but doze and battery saver will still
+  block their sync adapters.
\ No newline at end of file
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index fe6e60f..3172a04 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -16,18 +16,22 @@
 
 package com.android.server.devicestate;
 
-import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
 import static android.Manifest.permission.CONTROL_DEVICE_STATE;
+import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
 
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.hardware.devicestate.IDeviceStateManager;
+import android.hardware.devicestate.IDeviceStateManagerCallback;
 import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
 import android.util.IntArray;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -37,6 +41,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Arrays;
 
 /**
@@ -66,6 +71,8 @@
     private final Object mLock = new Object();
     @NonNull
     private final DeviceStatePolicy mDeviceStatePolicy;
+    @NonNull
+    private final BinderService mBinderService;
 
     @GuardedBy("mLock")
     private IntArray mSupportedDeviceStates;
@@ -88,6 +95,10 @@
     @GuardedBy("mLock")
     private int mRequestedOverrideState = INVALID_DEVICE_STATE;
 
+    // List of registered callbacks indexed by process id.
+    @GuardedBy("mLock")
+    private final SparseArray<CallbackRecord> mCallbacks = new SparseArray<>();
+
     public DeviceStateManagerService(@NonNull Context context) {
         this(context, new DeviceStatePolicyImpl());
     }
@@ -96,12 +107,13 @@
     DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy) {
         super(context);
         mDeviceStatePolicy = policy;
+        mDeviceStatePolicy.getDeviceStateProvider().setListener(new DeviceStateProviderListener());
+        mBinderService = new BinderService();
     }
 
     @Override
     public void onStart() {
-        mDeviceStatePolicy.getDeviceStateProvider().setListener(new DeviceStateProviderListener());
-        publishBinderService(Context.DEVICE_STATE_SERVICE, new BinderService());
+        publishBinderService(Context.DEVICE_STATE_SERVICE, mBinderService);
     }
 
     /**
@@ -186,6 +198,11 @@
         }
     }
 
+    @VisibleForTesting
+    IDeviceStateManager getBinderService() {
+        return mBinderService;
+    }
+
     private void updateSupportedStates(int[] supportedDeviceStates) {
         // Must ensure sorted as isSupportedStateLocked() impl uses binary search.
         Arrays.sort(supportedDeviceStates, 0, supportedDeviceStates.length);
@@ -310,18 +327,81 @@
      * </p>
      */
     private void commitPendingState() {
+        // Update the current state.
+        int newState;
         synchronized (mLock) {
             if (DEBUG) {
                 Slog.d(TAG, "Committing state: " + mPendingState);
             }
             mCommittedState = mPendingState;
+            newState = mCommittedState;
             mPendingState = INVALID_DEVICE_STATE;
             updatePendingStateLocked();
         }
 
+        // Notify callbacks of a change.
+        notifyDeviceStateChanged(newState);
+
+        // Try to configure the next state if needed.
         notifyPolicyIfNeeded();
     }
 
+    private void notifyDeviceStateChanged(int deviceState) {
+        if (Thread.holdsLock(mLock)) {
+            throw new IllegalStateException(
+                    "Attempting to notify callbacks with service lock held.");
+        }
+
+        // Grab the lock and copy the callbacks.
+        ArrayList<CallbackRecord> callbacks;
+        synchronized (mLock) {
+            if (mCallbacks.size() == 0) {
+                return;
+            }
+
+            callbacks = new ArrayList<>();
+            for (int i = 0; i < mCallbacks.size(); i++) {
+                callbacks.add(mCallbacks.valueAt(i));
+            }
+        }
+
+        // After releasing the lock, send the notifications out.
+        for (int i = 0; i < callbacks.size(); i++) {
+            callbacks.get(i).notifyDeviceStateAsync(deviceState);
+        }
+    }
+
+    private void registerCallbackInternal(IDeviceStateManagerCallback callback, int callingPid) {
+        int currentState;
+        CallbackRecord record;
+        // Grab the lock to register the callback and get the current state.
+        synchronized (mLock) {
+            if (mCallbacks.contains(callingPid)) {
+                throw new SecurityException("The calling process has already registered an"
+                        + " IDeviceStateManagerCallback.");
+            }
+
+            record = new CallbackRecord(callback, callingPid);
+            try {
+                callback.asBinder().linkToDeath(record, 0);
+            } catch (RemoteException ex) {
+                throw new RuntimeException(ex);
+            }
+
+            mCallbacks.put(callingPid, record);
+            currentState = mCommittedState;
+        }
+
+        // Notify the callback of the state at registration.
+        record.notifyDeviceStateAsync(currentState);
+    }
+
+    private void unregisterCallbackInternal(CallbackRecord record) {
+        synchronized (mLock) {
+            mCallbacks.remove(record.mPid);
+        }
+    }
+
     private void dumpInternal(PrintWriter pw) {
         pw.println("DEVICE STATE MANAGER (dumpsys device_state)");
 
@@ -330,6 +410,14 @@
             pw.println("  mPendingState=" + toString(mPendingState));
             pw.println("  mRequestedState=" + toString(mRequestedState));
             pw.println("  mRequestedOverrideState=" + toString(mRequestedOverrideState));
+
+            final int callbackCount = mCallbacks.size();
+            pw.println();
+            pw.println("Callbacks: size=" + callbackCount);
+            for (int i = 0; i < callbackCount; i++) {
+                CallbackRecord callback = mCallbacks.valueAt(i);
+                pw.println("  " + i + ": mPid=" + callback.mPid);
+            }
         }
     }
 
@@ -360,9 +448,48 @@
         }
     }
 
+    private final class CallbackRecord implements IBinder.DeathRecipient {
+        private final IDeviceStateManagerCallback mCallback;
+        private final int mPid;
+
+        CallbackRecord(IDeviceStateManagerCallback callback, int pid) {
+            mCallback = callback;
+            mPid = pid;
+        }
+
+        @Override
+        public void binderDied() {
+            unregisterCallbackInternal(this);
+        }
+
+        public void notifyDeviceStateAsync(int devicestate) {
+            try {
+                mCallback.onDeviceStateChanged(devicestate);
+            } catch (RemoteException ex) {
+                Slog.w(TAG, "Failed to notify process " + mPid + " that device state changed.",
+                        ex);
+            }
+        }
+    }
+
     /** Implementation of {@link IDeviceStateManager} published as a binder service. */
     private final class BinderService extends IDeviceStateManager.Stub {
         @Override // Binder call
+        public void registerCallback(IDeviceStateManagerCallback callback) {
+            if (callback == null) {
+                throw new IllegalArgumentException("Device state callback must not be null.");
+            }
+
+            final int callingPid = Binder.getCallingPid();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                registerCallbackInternal(callback, callingPid);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override // Binder call
         public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
                 String[] args, ShellCallback callback, ResultReceiver result) {
             new DeviceStateManagerShellCommand(DeviceStateManagerService.this)
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index b10cd12..3ac2185 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1423,17 +1423,18 @@
 
     private Optional<Integer> getViewportType(DisplayDeviceInfo info) {
         // Get the corresponding viewport type.
-        if ((info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
-            return Optional.of(VIEWPORT_INTERNAL);
-        } else if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
-            return Optional.of(VIEWPORT_EXTERNAL);
-        } else if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL
-                && !TextUtils.isEmpty(info.uniqueId)) {
-            return Optional.of(VIEWPORT_VIRTUAL);
-        } else {
-            if (DEBUG) {
-                Slog.i(TAG, "Display " + info + " does not support input device matching.");
-            }
+        switch (info.touch) {
+            case DisplayDeviceInfo.TOUCH_INTERNAL:
+                return Optional.of(VIEWPORT_INTERNAL);
+            case DisplayDeviceInfo.TOUCH_EXTERNAL:
+                return Optional.of(VIEWPORT_EXTERNAL);
+            case DisplayDeviceInfo.TOUCH_VIRTUAL:
+                if (!TextUtils.isEmpty(info.uniqueId)) {
+                    return Optional.of(VIEWPORT_VIRTUAL);
+                }
+                // fallthrough
+            default:
+                Slog.w(TAG, "Display " + info + " does not support input device matching.");
         }
         return Optional.empty();
     }
@@ -1483,13 +1484,6 @@
             return null;
         }
 
-        // Only allow a single INTERNAL or EXTERNAL viewport by forcing their uniqueIds
-        // to be identical (in particular, empty).
-        // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function.
-        if (viewportType != VIEWPORT_VIRTUAL) {
-            uniqueId = "";
-        }
-
         DisplayViewport viewport;
         final int count = mViewports.size();
         for (int i = 0; i < count; i++) {
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index c013145..1aced07 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -931,6 +931,8 @@
                 Settings.System.getUriFor(Settings.System.MIN_REFRESH_RATE);
         private final Uri mLowPowerModeSetting =
                 Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE);
+        private final Uri mMatchContentFrameRateSetting =
+                Settings.Secure.getUriFor(Settings.Secure.MATCH_CONTENT_FRAME_RATE);
 
         private final Context mContext;
         private float mDefaultPeakRefreshRate;
@@ -953,6 +955,8 @@
                     UserHandle.USER_SYSTEM);
             cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this,
                     UserHandle.USER_SYSTEM);
+            cr.registerContentObserver(mMatchContentFrameRateSetting, false /*notifyDescendants*/,
+                    this);
 
             Float deviceConfigDefaultPeakRefresh =
                     mDeviceConfigDisplaySettings.getDefaultPeakRefreshRate();
@@ -963,6 +967,7 @@
             synchronized (mLock) {
                 updateRefreshRateSettingLocked();
                 updateLowPowerModeSettingLocked();
+                updateModeSwitchingTypeSettingLocked();
             }
         }
 
@@ -988,6 +993,8 @@
                     updateRefreshRateSettingLocked();
                 } else if (mLowPowerModeSetting.equals(uri)) {
                     updateLowPowerModeSettingLocked();
+                } else if (mMatchContentFrameRateSetting.equals(uri)) {
+                    updateModeSwitchingTypeSettingLocked();
                 }
             }
         }
@@ -1050,6 +1057,17 @@
             mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, maxRefreshRate);
         }
 
+        private void updateModeSwitchingTypeSettingLocked() {
+            final ContentResolver cr = mContext.getContentResolver();
+            int switchingType = Settings.Secure.getIntForUser(
+                    cr, Settings.Secure.MATCH_CONTENT_FRAME_RATE, mModeSwitchingType /*default*/,
+                    cr.getUserId());
+            if (switchingType != mModeSwitchingType) {
+                mModeSwitchingType = switchingType;
+                notifyDesiredDisplayModeSpecsChangedLocked();
+            }
+        }
+
         public void dumpLocked(PrintWriter pw) {
             pw.println("  SettingsObserver");
             pw.println("    mDefaultRefreshRate: " + mDefaultRefreshRate);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 309271c..1a62b9d 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -328,8 +328,8 @@
     private BrightnessReason mBrightnessReasonTemp = new BrightnessReason();
 
     // Brightness animation ramp rates in brightness units per second
-    private final float mBrightnessRampRateSlow = 0.2352941f;
-    private final float mBrightnessRampRateFast = 0.7058823f;
+    private final float mBrightnessRampRateSlow;
+    private final float mBrightnessRampRateFast;
 
 
     // Whether or not to skip the initial brightness ramps into STATE_ON.
@@ -454,6 +454,10 @@
         mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
 
+        mBrightnessRampRateFast = BrightnessSynchronizer.brightnessIntToFloat(resources.getInteger(
+                com.android.internal.R.integer.config_brightness_ramp_rate_fast));
+        mBrightnessRampRateSlow = BrightnessSynchronizer.brightnessIntToFloat(resources.getInteger(
+                com.android.internal.R.integer.config_brightness_ramp_rate_slow));
         mSkipScreenOnBrightnessRamp = resources.getBoolean(
                 com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
 
diff --git a/services/core/java/com/android/server/display/TEST_MAPPING b/services/core/java/com/android/server/display/TEST_MAPPING
new file mode 100644
index 0000000..66ec5c4
--- /dev/null
+++ b/services/core/java/com/android/server/display/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+    "presubmit": [
+        {
+            "name": "FrameworksMockingServicesTests",
+            "options": [
+                {"include-filter": "com.android.server.display"},
+                {"exclude-annotation": "android.platform.test.annotations.FlakyTest"},
+                {"exclude-annotation": "androidx.test.filters.FlakyTest"}
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
index e906a7c..ca78f35 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringDef;
 import android.content.Context;
 import android.hardware.hdmi.HdmiControlManager;
 import android.os.Environment;
@@ -68,6 +69,15 @@
     private static final int STORAGE_SYSPROPS = 0;
     private static final int STORAGE_GLOBAL_SETTINGS = 1;
 
+    private static final String VALUE_TYPE_STRING = "string";
+    private static final String VALUE_TYPE_INT = "int";
+
+    @StringDef({
+        VALUE_TYPE_STRING,
+        VALUE_TYPE_INT,
+    })
+    private @interface ValueType {}
+
     /**
      * System property key for Power State Change on Active Source Lost.
      */
@@ -247,17 +257,15 @@
         }
     }
 
-    private String retrieveValue(@NonNull Setting setting) {
+    private String retrieveValue(@NonNull Setting setting, @NonNull String defaultValue) {
         @Storage int storage = getStorage(setting);
         String storageKey = getStorageKey(setting);
         if (storage == STORAGE_SYSPROPS) {
             Slog.d(TAG, "Reading '" + storageKey + "' sysprop.");
-            return mStorageAdapter.retrieveSystemProperty(storageKey,
-                    setting.getDefaultValue().getStringValue());
+            return mStorageAdapter.retrieveSystemProperty(storageKey, defaultValue);
         } else if (storage == STORAGE_GLOBAL_SETTINGS) {
             Slog.d(TAG, "Reading '" + storageKey + "' global setting.");
-            return mStorageAdapter.retrieveGlobalSetting(mContext, storageKey,
-                    setting.getDefaultValue().getStringValue());
+            return mStorageAdapter.retrieveGlobalSetting(mContext, storageKey, defaultValue);
         }
         return null;
     }
@@ -274,6 +282,10 @@
         }
     }
 
+    private int getIntValue(@NonNull Value value) {
+        return Integer.decode(value.getIntValue());
+    }
+
     /**
      * Returns a list of all settings based on the XML metadata.
      */
@@ -316,13 +328,41 @@
     }
 
     /**
-     * For a given setting name returns values that are allowed for that setting.
+     * For a given setting name returns true if and only if the value type of that
+     * setting is a string.
      */
-    public List<String> getAllowedValues(@NonNull @CecSettingName String name) {
+    public boolean isStringValueType(@NonNull @CecSettingName String name) {
         Setting setting = getSetting(name);
         if (setting == null) {
             throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
         }
+        return getSetting(name).getValueType().equals(VALUE_TYPE_STRING);
+    }
+
+    /**
+     * For a given setting name returns true if and only if the value type of that
+     * setting is an int.
+     */
+    public boolean isIntValueType(@NonNull @CecSettingName String name) {
+        Setting setting = getSetting(name);
+        if (setting == null) {
+            throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+        }
+        return getSetting(name).getValueType().equals(VALUE_TYPE_INT);
+    }
+
+    /**
+     * For a given setting name returns values that are allowed for that setting (string).
+     */
+    public List<String> getAllowedStringValues(@NonNull @CecSettingName String name) {
+        Setting setting = getSetting(name);
+        if (setting == null) {
+            throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+        }
+        if (!setting.getValueType().equals(VALUE_TYPE_STRING)) {
+            throw new IllegalArgumentException("Setting '" + name
+                    + "' is not a string-type setting.");
+        }
         List<String> allowedValues = new ArrayList<String>();
         for (Value allowedValue : setting.getAllowedValues().getValue()) {
             allowedValues.add(allowedValue.getStringValue());
@@ -331,32 +371,92 @@
     }
 
     /**
-     * For a given setting name returns the default value for that setting.
+     * For a given setting name returns values that are allowed for that setting (string).
      */
-    public String getDefaultValue(@NonNull @CecSettingName String name) {
+    public List<Integer> getAllowedIntValues(@NonNull @CecSettingName String name) {
         Setting setting = getSetting(name);
         if (setting == null) {
             throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
         }
+        if (!setting.getValueType().equals(VALUE_TYPE_INT)) {
+            throw new IllegalArgumentException("Setting '" + name
+                    + "' is not a string-type setting.");
+        }
+        List<Integer> allowedValues = new ArrayList<Integer>();
+        for (Value allowedValue : setting.getAllowedValues().getValue()) {
+            allowedValues.add(getIntValue(allowedValue));
+        }
+        return allowedValues;
+    }
+
+    /**
+     * For a given setting name returns the default value for that setting (string).
+     */
+    public String getDefaultStringValue(@NonNull @CecSettingName String name) {
+        Setting setting = getSetting(name);
+        if (setting == null) {
+            throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+        }
+        if (!setting.getValueType().equals(VALUE_TYPE_STRING)) {
+            throw new IllegalArgumentException("Setting '" + name
+                    + "' is not a string-type setting.");
+        }
         return getSetting(name).getDefaultValue().getStringValue();
     }
 
     /**
-     * For a given setting name returns the current value of that setting.
+     * For a given setting name returns the default value for that setting (int).
      */
-    public String getValue(@NonNull @CecSettingName String name) {
+    public int getDefaultIntValue(@NonNull @CecSettingName String name) {
         Setting setting = getSetting(name);
         if (setting == null) {
             throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
         }
-        Slog.d(TAG, "Getting CEC setting value '" + name + "'.");
-        return retrieveValue(setting);
+        if (!setting.getValueType().equals(VALUE_TYPE_INT)) {
+            throw new IllegalArgumentException("Setting '" + name
+                    + "' is not a string-type setting.");
+        }
+        return getIntValue(getSetting(name).getDefaultValue());
     }
 
     /**
-     * For a given setting name and value sets the current value of that setting.
+     * For a given setting name returns the current value of that setting (string).
      */
-    public void setValue(@NonNull @CecSettingName String name, @NonNull String value) {
+    public String getStringValue(@NonNull @CecSettingName String name) {
+        Setting setting = getSetting(name);
+        if (setting == null) {
+            throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+        }
+        if (!setting.getValueType().equals(VALUE_TYPE_STRING)) {
+            throw new IllegalArgumentException("Setting '" + name
+                    + "' is not a string-type setting.");
+        }
+        Slog.d(TAG, "Getting CEC setting value '" + name + "'.");
+        return retrieveValue(setting, setting.getDefaultValue().getStringValue());
+    }
+
+    /**
+     * For a given setting name returns the current value of that setting (int).
+     */
+    public int getIntValue(@NonNull @CecSettingName String name) {
+        Setting setting = getSetting(name);
+        if (setting == null) {
+            throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+        }
+        if (!setting.getValueType().equals(VALUE_TYPE_INT)) {
+            throw new IllegalArgumentException("Setting '" + name
+                    + "' is not a int-type setting.");
+        }
+        Slog.d(TAG, "Getting CEC setting value '" + name + "'.");
+        String defaultValue = Integer.toString(getIntValue(setting.getDefaultValue()));
+        String value = retrieveValue(setting, defaultValue);
+        return Integer.parseInt(value);
+    }
+
+    /**
+     * For a given setting name and value sets the current value of that setting (string).
+     */
+    public void setStringValue(@NonNull @CecSettingName String name, @NonNull String value) {
         Setting setting = getSetting(name);
         if (setting == null) {
             throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
@@ -364,11 +464,38 @@
         if (!setting.getUserConfigurable()) {
             throw new IllegalArgumentException("Updating CEC setting '" + name + "' prohibited.");
         }
-        if (!getAllowedValues(name).contains(value)) {
+        if (!setting.getValueType().equals(VALUE_TYPE_STRING)) {
+            throw new IllegalArgumentException("Setting '" + name
+                    + "' is not a string-type setting.");
+        }
+        if (!getAllowedStringValues(name).contains(value)) {
             throw new IllegalArgumentException("Invalid CEC setting '" + name
                                                + "' value: '" + value + "'.");
         }
         Slog.d(TAG, "Updating CEC setting '" + name + "' to '" + value + "'.");
         storeValue(setting, value);
     }
+
+    /**
+     * For a given setting name and value sets the current value of that setting (int).
+     */
+    public void setIntValue(@NonNull @CecSettingName String name, int value) {
+        Setting setting = getSetting(name);
+        if (setting == null) {
+            throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
+        }
+        if (!setting.getUserConfigurable()) {
+            throw new IllegalArgumentException("Updating CEC setting '" + name + "' prohibited.");
+        }
+        if (!setting.getValueType().equals(VALUE_TYPE_INT)) {
+            throw new IllegalArgumentException("Setting '" + name
+                    + "' is not a int-type setting.");
+        }
+        if (!getAllowedIntValues(name).contains(value)) {
+            throw new IllegalArgumentException("Invalid CEC setting '" + name
+                                               + "' value: '" + value + "'.");
+        }
+        Slog.d(TAG, "Updating CEC setting '" + name + "' to '" + value + "'.");
+        storeValue(setting, Integer.toString(value));
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 62a67b6..38eb7fb 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -997,6 +997,11 @@
     protected void onStandby(boolean initiatedByCec, int standbyAction) {}
 
     /**
+     * Called when the initialization of local devices is complete.
+     */
+    protected void onInitializeCecComplete(int initiatedBy) {}
+
+    /**
      * Disable device. {@code callback} is used to get notified when all pending actions are
      * completed or timeout is issued.
      *
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index fe4fd38..9dc0079 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -495,17 +495,17 @@
     private byte[] getSupportedShortAudioDescriptorsFromConfig(
             List<DeviceConfig> deviceConfig, @AudioCodec int[] audioFormatCodes) {
         DeviceConfig deviceConfigToUse = null;
+        String audioDeviceName = SystemProperties.get(
+                Constants.PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT,
+                "VX_AUDIO_DEVICE_IN_HDMI_ARC");
         for (DeviceConfig device : deviceConfig) {
-            // TODO(amyjojo) use PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT to get the audio device name
-            if (device.name.equals("VX_AUDIO_DEVICE_IN_HDMI_ARC")) {
+            if (device.name.equals(audioDeviceName)) {
                 deviceConfigToUse = device;
                 break;
             }
         }
         if (deviceConfigToUse == null) {
-            // TODO(amyjojo) use PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT to get the audio device name
-            Slog.w(TAG, "sadConfig.xml does not have required device info for "
-                        + "VX_AUDIO_DEVICE_IN_HDMI_ARC");
+            Slog.w(TAG, "sadConfig.xml does not have required device info for " + audioDeviceName);
             return new byte[0];
         }
         HashMap<Integer, byte[]> map = new HashMap<>();
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 6257032..9877919 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -224,6 +224,21 @@
 
     @Override
     @ServiceThreadOnly
+    protected void onInitializeCecComplete(int initiatedBy) {
+        if (initiatedBy == HdmiControlService.INITIATED_BY_SCREEN_ON) {
+            oneTouchPlay(new IHdmiControlCallback.Stub() {
+                @Override
+                public void onComplete(int result) {
+                    if (result != HdmiControlManager.RESULT_SUCCESS) {
+                        Slog.w(TAG, "Failed to complete One Touch Play. result=" + result);
+                    }
+                }
+            });
+        }
+    }
+
+    @Override
+    @ServiceThreadOnly
     void setAutoDeviceOff(boolean enabled) {
         assertRunOnServiceThread();
         mAutoTvOff = enabled;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index e656143..fe97f70 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -122,7 +122,25 @@
         addValidationInfo(Constants.MESSAGE_RECORD_STATUS,
                 new RecordStatusInfoValidator(), DEST_DIRECT);
 
-        // TODO: Handle messages for the Timer Programming.
+        addValidationInfo(
+                Constants.MESSAGE_CLEAR_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_CLEAR_DIGITAL_TIMER, new DigitalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_CLEAR_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_DIGITAL_TIMER, new DigitalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_SET_TIMER_PROGRAM_TITLE, new AsciiValidator(1, 14), DEST_DIRECT);
+        addValidationInfo(
+                Constants.MESSAGE_TIMER_CLEARED_STATUS,
+                new TimerClearedStatusValidator(),
+                DEST_DIRECT);
+        addValidationInfo(Constants.MESSAGE_TIMER_STATUS, new TimerStatusValidator(), DEST_DIRECT);
 
         // Messages for the System Information.
         FixedLengthValidator oneByteValidator = new FixedLengthValidator(1);
@@ -415,6 +433,205 @@
         return (Integer.bitCount(value) <= 1);
     }
 
+    /**
+     * Check if the given value is a valid analogue broadcast type. A valid value is one which falls
+     * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section
+     * 17)
+     *
+     * @param value analogue broadcast type
+     * @return true if the analogue broadcast type is valid
+     */
+    private boolean isValidAnalogueBroadcastType(int value) {
+        return isWithinRange(value, 0x00, 0x02);
+    }
+
+    /**
+     * Check if the given value is a valid analogue frequency. A valid value is one which falls
+     * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section
+     * 17)
+     *
+     * @param value analogue frequency
+     * @return true if the analogue frequency is valid
+     */
+    private boolean isValidAnalogueFrequency(int value) {
+        value = value & 0xFFFF;
+        return (value != 0x000 && value != 0xFFFF);
+    }
+
+    /**
+     * Check if the given value is a valid broadcast system. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value broadcast system
+     * @return true if the broadcast system is valid
+     */
+    private boolean isValidBroadcastSystem(int value) {
+        return isWithinRange(value, 0, 31);
+    }
+
+    /**
+     * Check if the given value is a ARIB type. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value Digital Broadcast System
+     * @return true if the Digital Broadcast System is ARIB type
+     */
+    private boolean isAribDbs(int value) {
+        return (value == 0x00 || isWithinRange(value, 0x08, 0x0A));
+    }
+
+    /**
+     * Check if the given value is a ATSC type. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value Digital Broadcast System
+     * @return true if the Digital Broadcast System is ATSC type
+     */
+    private boolean isAtscDbs(int value) {
+        return (value == 0x01 || isWithinRange(value, 0x10, 0x12));
+    }
+
+    /**
+     * Check if the given value is a DVB type. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value Digital Broadcast System
+     * @return true if the Digital Broadcast System is DVB type
+     */
+    private boolean isDvbDbs(int value) {
+        return (value == 0x02 || isWithinRange(value, 0x18, 0x1B));
+    }
+
+    /**
+     * Check if the given value is a valid Digital Broadcast System. A valid value is one which
+     * falls within the range description defined in CEC 1.4 Specification : Operand Descriptions
+     * (Section 17)
+     *
+     * @param value Digital Broadcast System
+     * @return true if the Digital Broadcast System is valid
+     */
+    private boolean isValidDigitalBroadcastSystem(int value) {
+        return (isAribDbs(value) || isAtscDbs(value) || isDvbDbs(value));
+    }
+
+    /**
+     * Check if the given value is a valid Digital Service Identification. A valid value is one
+     * which falls within the range description defined in CEC 1.4 Specification : Operand
+     * Descriptions (Section 17)
+     *
+     * @param params Digital Timer Message parameters
+     * @param offset start offset of Digital Service Identification
+     * @return true if the Digital Service Identification is valid
+     */
+    private boolean isValidDigitalServiceIdentification(byte[] params, int offset) {
+        // MSB contains Service Identification Method
+        int serviceIdentificationMethod = params[offset] & 0x80;
+        // Last 7 bits contains Digital Broadcast System
+        int digitalBroadcastSystem = params[offset] & 0x7F;
+        offset = offset + 1;
+        if (serviceIdentificationMethod == 0x00) {
+            // Services identified by Digital IDs
+            if (isAribDbs(digitalBroadcastSystem)) {
+                // Validate ARIB type have 6 byte data
+                return params.length - offset >= 6;
+            } else if (isAtscDbs(digitalBroadcastSystem)) {
+                // Validate ATSC type have 4 byte data
+                return params.length - offset >= 4;
+            } else if (isDvbDbs(digitalBroadcastSystem)) {
+                // Validate DVB type have 6 byte data
+                return params.length - offset >= 6;
+            }
+        } else if (serviceIdentificationMethod == 0x80) {
+            // Services identified by Channel
+            if (isValidDigitalBroadcastSystem(digitalBroadcastSystem)) {
+                // First 6 bits contain Channel Number Format
+                int channelNumberFormat = params[offset] & 0xFC;
+                if (channelNumberFormat == 0x04) {
+                    // Validate it contains 1-part Channel Number data (16 bits)
+                    return params.length - offset >= 3;
+                } else if (channelNumberFormat == 0x08) {
+                    // Validate it contains Major Channel Number and Minor Channel Number (26 bits)
+                    return params.length - offset >= 4;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check if the given value is a valid External Plug. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value External Plug
+     * @return true if the External Plug is valid
+     */
+    private boolean isValidExternalPlug(int value) {
+        return isWithinRange(value, 1, 255);
+    }
+
+    /**
+     * Check if the given value is a valid External Source. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value External Source Specifier
+     * @return true if the External Source is valid
+     */
+    private boolean isValidExternalSource(byte[] params, int offset) {
+        int externalSourceSpecifier = params[offset];
+        offset = offset + 1;
+        if (externalSourceSpecifier == 0x04) {
+            // External Plug
+            return isValidExternalPlug(params[offset]);
+        } else if (externalSourceSpecifier == 0x05) {
+            // External Physical Address
+            // Validate it contains 2 bytes Physical Address
+            if (params.length - offset >= 2) {
+                return isValidPhysicalAddress(params, offset);
+            }
+        }
+        return false;
+    }
+
+    private boolean isValidProgrammedInfo(int programedInfo) {
+        return (isWithinRange(programedInfo, 0x00, 0x0B));
+    }
+
+    private boolean isValidNotProgrammedErrorInfo(int nonProgramedErrorInfo) {
+        return (isWithinRange(nonProgramedErrorInfo, 0x00, 0x0E));
+    }
+
+    private boolean isValidTimerStatusData(byte[] params, int offset) {
+        int programedIndicator = params[offset] & 0x10;
+        boolean durationAvailable = false;
+        if (programedIndicator == 0x10) {
+            // Programmed
+            int programedInfo = params[offset] & 0x0F;
+            if (isValidProgrammedInfo(programedInfo)) {
+                if (programedInfo == 0x09 || programedInfo == 0x0B) {
+                    durationAvailable = true;
+                } else {
+                    return true;
+                }
+            }
+        } else {
+            // Non programmed
+            int nonProgramedErrorInfo = params[offset] & 0x0F;
+            if (isValidNotProgrammedErrorInfo(nonProgramedErrorInfo)) {
+                if (nonProgramedErrorInfo == 0x0E) {
+                    durationAvailable = true;
+                } else {
+                    return true;
+                }
+            }
+        }
+        offset = offset + 1;
+        // Duration Available (2 bytes)
+        if (durationAvailable && params.length - offset >= 2) {
+            return (isValidDurationHours(params[offset]) && isValidMinute(params[offset + 1]));
+        }
+        return false;
+    }
+
     private class PhysicalAddressValidator implements ParameterValidator {
         @Override
         public int isValid(byte[] params) {
@@ -544,4 +761,106 @@
             return toErrorCode(isWithinRange(params[0], mMinValue, mMaxValue));
         }
     }
+
+    /**
+     * Check if the given Analogue Timer message parameters are valid. Valid parameters should
+     * adhere to message description of Analogue Timer defined in CEC 1.4 Specification : Message
+     * Descriptions for Timer Programming Feature (CEC Table 12)
+     */
+    private class AnalogueTimerValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 11) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(
+                    isValidDayOfMonth(params[0]) // Day of Month
+                            && isValidMonthOfYear(params[1]) // Month of Year
+                            && isValidHour(params[2]) // Start Time - Hour
+                            && isValidMinute(params[3]) // Start Time - Minute
+                            && isValidDurationHours(params[4]) // Duration - Duration Hours
+                            && isValidMinute(params[5]) // Duration - Minute
+                            && isValidRecordingSequence(params[6]) // Recording Sequence
+                            && isValidAnalogueBroadcastType(params[7]) // Analogue Broadcast Type
+                            && isValidAnalogueFrequency(
+                                    HdmiUtils.twoBytesToInt(params, 8)) // Analogue Frequency
+                            && isValidBroadcastSystem(params[10])); // Broadcast System
+        }
+    }
+
+    /**
+     * Check if the given Digital Timer message parameters are valid. Valid parameters should adhere
+     * to message description of Digital Timer defined in CEC 1.4 Specification : Message
+     * Descriptions for Timer Programming Feature (CEC Table 12)
+     */
+    private class DigitalTimerValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 11) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(
+                    isValidDayOfMonth(params[0]) // Day of Month
+                            && isValidMonthOfYear(params[1]) // Month of Year
+                            && isValidHour(params[2]) // Start Time - Hour
+                            && isValidMinute(params[3]) // Start Time - Minute
+                            && isValidDurationHours(params[4]) // Duration - Duration Hours
+                            && isValidMinute(params[5]) // Duration - Minute
+                            && isValidRecordingSequence(params[6]) // Recording Sequence
+                            && isValidDigitalServiceIdentification(
+                                    params, 7)); // Digital Service Identification
+        }
+    }
+
+    /**
+     * Check if the given External Timer message parameters are valid. Valid parameters should
+     * adhere to message description of External Timer defined in CEC 1.4 Specification : Message
+     * Descriptions for Timer Programming Feature (CEC Table 12)
+     */
+    private class ExternalTimerValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 9) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(
+                    isValidDayOfMonth(params[0]) // Day of Month
+                            && isValidMonthOfYear(params[1]) // Month of Year
+                            && isValidHour(params[2]) // Start Time - Hour
+                            && isValidMinute(params[3]) // Start Time - Minute
+                            && isValidDurationHours(params[4]) // Duration - Duration Hours
+                            && isValidMinute(params[5]) // Duration - Minute
+                            && isValidRecordingSequence(params[6]) // Recording Sequence
+                            && isValidExternalSource(params, 7)); // External Source
+        }
+    }
+
+    /**
+     * Check if the given timer cleared status parameter is valid. A valid parameter should lie
+     * within the range description defined in CEC 1.4 Specification : Operand Descriptions
+     * (Section 17)
+     */
+    private class TimerClearedStatusValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 1) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(isWithinRange(params[0], 0x00, 0x02) || (params[0] & 0xFF) == 0x80);
+        }
+    }
+
+    /**
+     * Check if the given timer status data parameter is valid. A valid parameter should lie within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     */
+    private class TimerStatusValidator implements ParameterValidator {
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 1) {
+                return ERROR_PARAMETER_SHORT;
+            }
+            return toErrorCode(isValidTimerStatusData(params, 0));
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index da4c6f1..b96aa3a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -29,6 +29,7 @@
 import static com.android.server.hdmi.Constants.VERSION_1_4;
 import static com.android.server.power.ShutdownThread.SHUTDOWN_ACTION_PROPERTY;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -90,6 +91,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -178,6 +181,19 @@
 
     private HdmiCecNetwork mHdmiCecNetwork;
 
+    static final int WAKE_UP_SCREEN_ON = 0;
+    static final int WAKE_UP_BOOT_UP = 1;
+
+    // The reason code for starting the wake-up procedure. This procedure starts either by
+    // Intent.ACTION_SCREEN_ON or after boot-up.
+    @IntDef({
+            WAKE_UP_SCREEN_ON,
+            WAKE_UP_BOOT_UP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WakeReason {
+    }
+
     // Logical address of the active source.
     @GuardedBy("mLock")
     protected final ActiveSource mActiveSource = new ActiveSource();
@@ -237,7 +253,7 @@
                     break;
                 case Intent.ACTION_SCREEN_ON:
                     if (isPowerStandbyOrTransient()) {
-                        onWakeUp();
+                        onWakeUp(WAKE_UP_SCREEN_ON);
                     }
                     break;
                 case Intent.ACTION_CONFIGURATION_CHANGED:
@@ -553,7 +569,7 @@
     private void bootCompleted() {
         // on boot, if device is interactive, set HDMI CEC state as powered on as well
         if (mPowerManager.isInteractive() && isPowerStandbyOrTransient()) {
-            onWakeUp();
+            onWakeUp(WAKE_UP_BOOT_UP);
         }
     }
 
@@ -639,6 +655,12 @@
                 reason = HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING;
                 break;
             case INITIATED_BY_SCREEN_ON:
+                reason = HdmiControlManager.CONTROL_STATE_CHANGED_REASON_WAKEUP;
+                final List<HdmiCecLocalDevice> devices = getAllLocalDevices();
+                for (HdmiCecLocalDevice device : devices) {
+                    device.onInitializeCecComplete(initiatedBy);
+                }
+                break;
             case INITIATED_BY_WAKE_UP_MESSAGE:
                 reason = HdmiControlManager.CONTROL_STATE_CHANGED_REASON_WAKEUP;
                 break;
@@ -2242,9 +2264,15 @@
             List<String> allSettings = hdmiCecConfig.getAllSettings();
             Set<String> userSettings = new HashSet<>(hdmiCecConfig.getUserSettings());
             for (String setting : allSettings) {
-                pw.println(setting + ": " + hdmiCecConfig.getValue(setting)
-                        + " (default: " + hdmiCecConfig.getDefaultValue(setting) + ")"
-                        + (userSettings.contains(setting) ? " [modifiable]" : ""));
+                if (hdmiCecConfig.isStringValueType(setting)) {
+                    pw.println(setting + " (string): " + hdmiCecConfig.getStringValue(setting)
+                            + " (default: " + hdmiCecConfig.getDefaultStringValue(setting) + ")"
+                            + (userSettings.contains(setting) ? " [modifiable]" : ""));
+                } else if (hdmiCecConfig.isIntValueType(setting)) {
+                    pw.println(setting + " (int): " + hdmiCecConfig.getIntValue(setting)
+                            + " (default: " + hdmiCecConfig.getDefaultIntValue(setting) + ")"
+                            + (userSettings.contains(setting) ? " [modifiable]" : ""));
+                }
             }
             pw.decreaseIndent();
 
@@ -2273,33 +2301,68 @@
         }
 
         @Override
-        public List<String> getAllowedCecSettingValues(String name) {
+        public List<String> getAllowedCecSettingStringValues(String name) {
             enforceAccessPermission();
             long token = Binder.clearCallingIdentity();
             try {
-                return HdmiControlService.this.getHdmiCecConfig().getAllowedValues(name);
+                return HdmiControlService.this.getHdmiCecConfig().getAllowedStringValues(name);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
-        public String getCecSettingValue(String name) {
+        public int[] getAllowedCecSettingIntValues(String name) {
             enforceAccessPermission();
             long token = Binder.clearCallingIdentity();
             try {
-                return HdmiControlService.this.getHdmiCecConfig().getValue(name);
+                List<Integer> allowedValues =
+                        HdmiControlService.this.getHdmiCecConfig().getAllowedIntValues(name);
+                return allowedValues.stream().mapToInt(i->i).toArray();
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
-        public void setCecSettingValue(String name, String value) {
+        public String getCecSettingStringValue(String name) {
             enforceAccessPermission();
             long token = Binder.clearCallingIdentity();
             try {
-                HdmiControlService.this.getHdmiCecConfig().setValue(name, value);
+                return HdmiControlService.this.getHdmiCecConfig().getStringValue(name);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void setCecSettingStringValue(String name, String value) {
+            enforceAccessPermission();
+            long token = Binder.clearCallingIdentity();
+            try {
+                HdmiControlService.this.getHdmiCecConfig().setStringValue(name, value);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public int getCecSettingIntValue(String name) {
+            enforceAccessPermission();
+            long token = Binder.clearCallingIdentity();
+            try {
+                return HdmiControlService.this.getHdmiCecConfig().getIntValue(name);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void setCecSettingIntValue(String name, int value) {
+            enforceAccessPermission();
+            long token = Binder.clearCallingIdentity();
+            try {
+                HdmiControlService.this.getHdmiCecConfig().setIntValue(name, value);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -2852,14 +2915,26 @@
     }
 
     @ServiceThreadOnly
-    private void onWakeUp() {
+    private void onWakeUp(@WakeReason final int wakeUpAction) {
         assertRunOnServiceThread();
         mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
         if (mCecController != null) {
             if (mHdmiControlEnabled) {
-                int startReason = INITIATED_BY_SCREEN_ON;
-                if (mWakeUpMessageReceived) {
-                    startReason = INITIATED_BY_WAKE_UP_MESSAGE;
+                int startReason = -1;
+                switch (wakeUpAction) {
+                    case WAKE_UP_SCREEN_ON:
+                        startReason = INITIATED_BY_SCREEN_ON;
+                        if (mWakeUpMessageReceived) {
+                            startReason = INITIATED_BY_WAKE_UP_MESSAGE;
+                        }
+                        break;
+                    case WAKE_UP_BOOT_UP:
+                        startReason = INITIATED_BY_BOOT_UP;
+                        break;
+                    default:
+                        Slog.e(TAG, "wakeUpAction " + wakeUpAction + " not defined.");
+                        return;
+
                 }
                 initializeCec(startReason);
             }
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 3f4ddea..9658800 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -2095,7 +2095,7 @@
         DisplayThread.getHandler().post(() ->
                 Toast.makeText(mContext,
                         "Touch obscured by " + packageName
-                                + " will be blocked. Check go/s-untrusted-touches",
+                                + " will be blocked. Check go/untrusted-touches",
                         Toast.LENGTH_SHORT).show());
     }
 
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 9a60afb..6dd91e5 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -15,6 +15,7 @@
 
 package com.android.server.inputmethod;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.server.inputmethod.InputMethodManagerServiceProto.ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD;
 import static android.server.inputmethod.InputMethodManagerServiceProto.BACK_DISPOSITION;
 import static android.server.inputmethod.InputMethodManagerServiceProto.BOUND_TO_METHOD;
@@ -110,6 +111,7 @@
 import android.os.ShellCommand;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
@@ -936,7 +938,7 @@
          * <p>TODO: Consider to follow what other system services have been doing to manage
          * constants (e.g. {@link android.provider.Settings.Global#ACTIVITY_MANAGER_CONSTANTS}).</p>
          */
-        private final static int ENTRY_SIZE_FOR_HIGH_RAM_DEVICE = 16;
+        private final static int ENTRY_SIZE_FOR_HIGH_RAM_DEVICE = 32;
 
         /**
          * Entry size for non low-RAM devices.
@@ -3106,6 +3108,7 @@
     @Override
     public boolean showSoftInput(IInputMethodClient client, IBinder windowToken, int flags,
             ResultReceiver resultReceiver) {
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showSoftInput");
         int uid = Binder.getCallingUid();
         synchronized (mMethodMap) {
             if (!calledFromValidUserLocked()) {
@@ -3133,6 +3136,7 @@
                         SoftInputShowHideReason.SHOW_SOFT_INPUT);
             } finally {
                 Binder.restoreCallingIdentity(ident);
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             }
         }
     }
@@ -3225,6 +3229,7 @@
             }
             final long ident = Binder.clearCallingIdentity();
             try {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput");
                 if (mCurClient == null || client == null
                         || mCurClient.client.asBinder() != client.asBinder()) {
                     // We need to check if this is the current client with
@@ -3248,6 +3253,7 @@
                         SoftInputShowHideReason.HIDE_SOFT_INPUT);
             } finally {
                 Binder.restoreCallingIdentity(ident);
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             }
         }
     }
@@ -3310,43 +3316,52 @@
             Slog.e(TAG, "windowToken cannot be null.");
             return InputBindResult.NULL;
         }
-        final int callingUserId = UserHandle.getCallingUserId();
-        final int userId;
-        if (attribute != null && attribute.targetInputMethodUser != null
-                && attribute.targetInputMethodUser.getIdentifier() != callingUserId) {
-            mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "Using EditorInfo.targetInputMethodUser requires INTERACT_ACROSS_USERS_FULL.");
-            userId = attribute.targetInputMethodUser.getIdentifier();
-            if (!mUserManagerInternal.isUserRunning(userId)) {
-                // There is a chance that we hit here because of race condition.  Let's just return
-                // an error code instead of crashing the caller process, which at least has
-                // INTERACT_ACROSS_USERS_FULL permission thus is likely to be an important process.
-                Slog.e(TAG, "User #" + userId + " is not running.");
-                return InputBindResult.INVALID_USER;
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+                    "IMMS.startInputOrWindowGainedFocus");
+            final int callingUserId = UserHandle.getCallingUserId();
+            final int userId;
+            if (attribute != null && attribute.targetInputMethodUser != null
+                    && attribute.targetInputMethodUser.getIdentifier() != callingUserId) {
+                mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                        "Using EditorInfo.targetInputMethodUser requires"
+                                + " INTERACT_ACROSS_USERS_FULL.");
+                userId = attribute.targetInputMethodUser.getIdentifier();
+                if (!mUserManagerInternal.isUserRunning(userId)) {
+                    // There is a chance that we hit here because of race condition.  Let's just
+                    // return an error code instead of crashing the caller process, which at least
+                    // has INTERACT_ACROSS_USERS_FULL permission thus is likely to be an important
+                    // process.
+                    Slog.e(TAG, "User #" + userId + " is not running.");
+                    return InputBindResult.INVALID_USER;
+                }
+            } else {
+                userId = callingUserId;
             }
-        } else {
-            userId = callingUserId;
-        }
-        final InputBindResult result;
-        synchronized (mMethodMap) {
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                result = startInputOrWindowGainedFocusInternalLocked(startInputReason, client,
-                        windowToken, startInputFlags, softInputMode, windowFlags, attribute,
-                        inputContext, missingMethods, unverifiedTargetSdkVersion, userId);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
+            final InputBindResult result;
+            synchronized (mMethodMap) {
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    result = startInputOrWindowGainedFocusInternalLocked(startInputReason, client,
+                            windowToken, startInputFlags, softInputMode, windowFlags, attribute,
+                            inputContext, missingMethods, unverifiedTargetSdkVersion, userId);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
             }
+            if (result == null) {
+                // This must never happen, but just in case.
+                Slog.wtf(TAG, "InputBindResult is @NonNull. startInputReason="
+                        + InputMethodDebug.startInputReasonToString(startInputReason)
+                        + " windowFlags=#" + Integer.toHexString(windowFlags)
+                        + " editorInfo=" + attribute);
+                return InputBindResult.NULL;
+            }
+
+            return result;
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
-        if (result == null) {
-            // This must never happen, but just in case.
-            Slog.wtf(TAG, "InputBindResult is @NonNull. startInputReason="
-                    + InputMethodDebug.startInputReasonToString(startInputReason)
-                    + " windowFlags=#" + Integer.toHexString(windowFlags)
-                    + " editorInfo=" + attribute);
-            return InputBindResult.NULL;
-        }
-        return result;
     }
 
     @NonNull
@@ -4124,6 +4139,7 @@
 
     @BinderThread
     private void applyImeVisibility(IBinder token, IBinder windowToken, boolean setVisible) {
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility");
         synchronized (mMethodMap) {
             if (!calledWithValidTokenLocked(token)) {
                 return;
@@ -4145,6 +4161,7 @@
                 mWindowManagerInternal.showImePostLayout(mShowRequestWindowMap.get(windowToken));
             }
         }
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
 
     private void setInputMethodWithSubtypeIdLocked(IBinder token, String id, int subtypeId) {
@@ -4172,6 +4189,7 @@
 
     @BinderThread
     private void hideMySoftInput(@NonNull IBinder token, int flags) {
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput");
         synchronized (mMethodMap) {
             if (!calledWithValidTokenLocked(token)) {
                 return;
@@ -4186,10 +4204,12 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
 
     @BinderThread
     private void showMySoftInput(@NonNull IBinder token, int flags) {
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showMySoftInput");
         synchronized (mMethodMap) {
             if (!calledWithValidTokenLocked(token)) {
                 return;
@@ -4202,6 +4222,7 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
 
     void setEnabledSessionInMainThread(SessionState session) {
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 9c48d23..18185ae 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -21,10 +21,10 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.location.LocationManager.BLOCK_PENDING_INTENT_SYSTEM_API_USAGE;
 import static android.location.LocationManager.FUSED_PROVIDER;
 import static android.location.LocationManager.GPS_PROVIDER;
 import static android.location.LocationManager.NETWORK_PROVIDER;
-import static android.location.LocationManager.PREVENT_PENDING_INTENT_SYSTEM_API_USAGE;
 import static android.location.LocationRequest.LOW_POWER_EXCEPTIONS;
 
 import static com.android.server.location.LocationPermissions.PERMISSION_COARSE;
@@ -597,14 +597,15 @@
         // simplest to ensure these apis are simply never set for pending intent requests. the same
         // does not apply for listener requests since those will have the process (including the
         // listener) killed on permission removal
-        boolean usesSystemApi = request.isLowPower()
-                || request.isHiddenFromAppOps()
-                || request.isLocationSettingsIgnored()
-                || !request.getWorkSource().isEmpty();
-        if (usesSystemApi
-                && isChangeEnabled(PREVENT_PENDING_INTENT_SYSTEM_API_USAGE, identity.getUid())) {
-            throw new SecurityException(
-                    "PendingIntent location requests may not use system APIs: " + request);
+        if (isChangeEnabled(BLOCK_PENDING_INTENT_SYSTEM_API_USAGE, identity.getUid())) {
+            boolean usesSystemApi = request.isLowPower()
+                    || request.isHiddenFromAppOps()
+                    || request.isLocationSettingsIgnored()
+                    || !request.getWorkSource().isEmpty();
+            if (usesSystemApi) {
+                throw new SecurityException(
+                        "PendingIntent location requests may not use system APIs: " + request);
+            }
         }
 
         request = validateLocationRequest(request, identity);
@@ -987,9 +988,13 @@
     @Override
     public void getFromLocation(double latitude, double longitude, int maxResults,
             GeocoderParams params, IGeocodeListener listener) {
+        // validate identity
+        CallerIdentity identity = CallerIdentity.fromBinder(mContext, params.getClientPackage(),
+                params.getClientAttributionTag());
+        Preconditions.checkArgument(identity.getUid() == params.getClientUid());
+
         if (mGeocodeProvider != null) {
-            mGeocodeProvider.getFromLocation(latitude, longitude, maxResults,
-                    params, listener);
+            mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, params, listener);
         } else {
             try {
                 listener.onResults(null, Collections.emptyList());
@@ -1004,6 +1009,11 @@
             double lowerLeftLatitude, double lowerLeftLongitude,
             double upperRightLatitude, double upperRightLongitude, int maxResults,
             GeocoderParams params, IGeocodeListener listener) {
+        // validate identity
+        CallerIdentity identity = CallerIdentity.fromBinder(mContext, params.getClientPackage(),
+                params.getClientAttributionTag());
+        Preconditions.checkArgument(identity.getUid() == params.getClientUid());
+
         if (mGeocodeProvider != null) {
             mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude,
                     lowerLeftLongitude, upperRightLatitude, upperRightLongitude,
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceManager.java b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
index 7a59cba..c23bd85 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
@@ -296,15 +296,15 @@
             @Nullable String attributionTag) {
         LocationPermissions.enforceCallingOrSelfLocationPermission(mContext, PERMISSION_FINE);
 
-        CallerIdentity callerIdentity = CallerIdentity.fromBinder(mContext, packageName,
+        CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName,
                 attributionTag, AppOpsManager.toReceiverId(pendingIntent));
 
-        final long identity = Binder.clearCallingIdentity();
+        final long ident = Binder.clearCallingIdentity();
         try {
             putRegistration(new GeofenceKey(pendingIntent, geofence),
-                    new GeofenceRegistration(geofence, callerIdentity, pendingIntent));
+                    new GeofenceRegistration(geofence, identity, pendingIntent));
         } finally {
-            Binder.restoreCallingIdentity(identity);
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
diff --git a/services/core/java/com/android/server/location/timezone/ControllerImpl.java b/services/core/java/com/android/server/location/timezone/ControllerImpl.java
index d482637..621828e 100644
--- a/services/core/java/com/android/server/location/timezone/ControllerImpl.java
+++ b/services/core/java/com/android/server/location/timezone/ControllerImpl.java
@@ -404,13 +404,6 @@
             return;
         }
 
-        // Consistency check for user. This may be possible as there are various races around
-        // current user switches.
-        if (!Objects.equals(event.getUserHandle(), mCurrentUserConfiguration.getUserHandle())) {
-            warnLog("Using event=" + event + " from a different user="
-                    + mCurrentUserConfiguration);
-        }
-
         if (!mCurrentUserConfiguration.getGeoDetectionEnabledBehavior()) {
             // This should not happen: the provider should not be in an enabled state if the user
             // does not have geodetection enabled.
diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
index a817759..74491c5 100644
--- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
+++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
@@ -87,7 +87,7 @@
                 // Binder and is registered as a binder service so it can receive shell commands.
                 publishBinderService("location_time_zone_manager", mService);
             } else {
-                Slog.i(TAG, getClass() + " is compile-time disabled");
+                Slog.i(TAG, getClass() + " is disabled");
             }
         }
 
diff --git a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
index f1d3723..6bf6539 100644
--- a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
+++ b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
@@ -25,11 +25,9 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.ActivityManager;
 import android.location.timezone.LocationTimeZoneEvent;
 import android.os.ShellCommand;
 import android.os.SystemClock;
-import android.os.UserHandle;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -119,8 +117,7 @@
 
     private static LocationTimeZoneEvent parseLocationTimeZoneEventArgs(ShellCommand shellCommand) {
         LocationTimeZoneEvent.Builder eventBuilder = new LocationTimeZoneEvent.Builder()
-                .setElapsedRealtimeNanos(SystemClock.elapsedRealtime())
-                .setUserHandle(UserHandle.of(ActivityManager.getCurrentUser()));
+                .setElapsedRealtimeNanos(SystemClock.elapsedRealtime());
 
         String eventTypeString = shellCommand.getNextArgRequired();
         switch (eventTypeString.toUpperCase()) {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 828a0ac..d5ce8a6 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -44,7 +44,7 @@
 import android.media.AudioManager;
 import android.media.AudioPlaybackConfiguration;
 import android.media.AudioSystem;
-import android.media.IRemoteVolumeController;
+import android.media.IRemoteVolumeControllerCallback;
 import android.media.Session2Token;
 import android.media.session.IActiveSessionsListener;
 import android.media.session.IOnMediaKeyEventDispatchedListener;
@@ -146,7 +146,7 @@
 
     // Used to notify System UI and Settings when remote volume was changed.
     @GuardedBy("mLock")
-    final RemoteCallbackList<IRemoteVolumeController> mRemoteVolumeControllers =
+    final RemoteCallbackList<IRemoteVolumeControllerCallback> mRemoteVolumeControllers =
             new RemoteCallbackList<>();
 
     private SessionPolicyProvider mCustomSessionPolicyProvider;
@@ -309,8 +309,9 @@
             MediaSession.Token token = session.getSessionToken();
             for (int i = size - 1; i >= 0; i--) {
                 try {
-                    IRemoteVolumeController cb = mRemoteVolumeControllers.getBroadcastItem(i);
-                    cb.remoteVolumeChanged(token, flags);
+                    IRemoteVolumeControllerCallback cb =
+                            mRemoteVolumeControllers.getBroadcastItem(i);
+                    cb.onVolumeChanged(token, flags);
                 } catch (Exception e) {
                     Log.w(TAG, "Error sending volume change.", e);
                 }
@@ -715,8 +716,9 @@
 
             for (int i = size - 1; i >= 0; i--) {
                 try {
-                    IRemoteVolumeController cb = mRemoteVolumeControllers.getBroadcastItem(i);
-                    cb.updateRemoteController(token);
+                    IRemoteVolumeControllerCallback cb =
+                            mRemoteVolumeControllers.getBroadcastItem(i);
+                    cb.onSessionChanged(token);
                 } catch (Exception e) {
                     Log.w(TAG, "Error sending default remote volume.", e);
                 }
@@ -991,6 +993,8 @@
                 } else if (mCurrentFullUserRecord.mLastMediaButtonReceiverHolder != null) {
                     String packageName = mLastMediaButtonReceiverHolder.getPackageName();
                     callback.onMediaKeyEventSessionChanged(packageName, null);
+                } else {
+                    callback.onMediaKeyEventSessionChanged("", null);
                 }
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to pushAddressedPlayerChangedLocked", e);
@@ -1843,7 +1847,7 @@
         }
 
         @Override
-        public void registerRemoteVolumeController(IRemoteVolumeController rvc) {
+        public void registerRemoteVolumeControllerCallback(IRemoteVolumeControllerCallback rvc) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
@@ -1858,7 +1862,7 @@
         }
 
         @Override
-        public void unregisterRemoteVolumeController(IRemoteVolumeController rvc) {
+        public void unregisterRemoteVolumeControllerCallback(IRemoteVolumeControllerCallback rvc) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 35d3621..dd6c8f5 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -559,6 +559,10 @@
     /** Set of all merged subscriberId as of last update */
     @GuardedBy("mNetworkPoliciesSecondLock")
     private List<String[]> mMergedSubscriberIds = new ArrayList<>();
+    /** Map from subId to carrierConfig as of last update */
+    @GuardedBy("mNetworkPoliciesSecondLock")
+    private final SparseArray<PersistableBundle> mSubIdToCarrierConfig =
+            new SparseArray<PersistableBundle>();
 
     /**
      * Indicates the uids restricted by admin from accessing metered data. It's a mapping from
@@ -1186,7 +1190,7 @@
             final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd);
 
             // Carrier might want to manage notifications themselves
-            final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+            final PersistableBundle config = mSubIdToCarrierConfig.get(subId);
             if (!CarrierConfigManager.isConfigForIdentifiedCarrier(config)) {
                 if (LOGV) Slog.v(TAG, "isConfigForIdentifiedCarrier returned false");
                 // Don't show notifications until we confirm that the loaded config is from an
@@ -1831,8 +1835,11 @@
 
         final List<String[]> mergedSubscriberIdsList = new ArrayList();
         final SparseArray<String> subIdToSubscriberId = new SparseArray<>(subList.size());
+        final SparseArray<PersistableBundle> subIdToCarrierConfig =
+                new SparseArray<PersistableBundle>();
         for (final SubscriptionInfo sub : subList) {
-            final TelephonyManager tmSub = tm.createForSubscriptionId(sub.getSubscriptionId());
+            final int subId = sub.getSubscriptionId();
+            final TelephonyManager tmSub = tm.createForSubscriptionId(subId);
             final String subscriberId = tmSub.getSubscriberId();
             if (!TextUtils.isEmpty(subscriberId)) {
                 subIdToSubscriberId.put(tmSub.getSubscriptionId(), subscriberId);
@@ -1843,6 +1850,13 @@
             final String[] mergedSubscriberId = ArrayUtils.defeatNullable(
                     tmSub.getMergedImsisFromGroup());
             mergedSubscriberIdsList.add(mergedSubscriberId);
+
+            final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+            if (config != null) {
+                subIdToCarrierConfig.put(subId, config);
+            } else {
+                Slog.e(TAG, "Missing CarrierConfig for subId " + subId);
+            }
         }
 
         synchronized (mNetworkPoliciesSecondLock) {
@@ -1853,6 +1867,12 @@
             }
 
             mMergedSubscriberIds = mergedSubscriberIdsList;
+
+            mSubIdToCarrierConfig.clear();
+            for (int i = 0; i < subIdToCarrierConfig.size(); i++) {
+                mSubIdToCarrierConfig.put(subIdToCarrierConfig.keyAt(i),
+                        subIdToCarrierConfig.valueAt(i));
+            }
         }
 
         Trace.traceEnd(TRACE_TAG_NETWORK);
@@ -2172,7 +2192,7 @@
                 }
             }
         } else {
-            final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+            final PersistableBundle config = mSubIdToCarrierConfig.get(subId);
             final int currentCycleDay;
             if (policy.cycleRule.isMonthly()) {
                 currentCycleDay = policy.cycleRule.start.getDayOfMonth();
diff --git a/services/core/java/com/android/server/notification/NotificationChannelLogger.java b/services/core/java/com/android/server/notification/NotificationChannelLogger.java
index 51faac7..36eec26 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelLogger.java
@@ -215,6 +215,13 @@
     }
 
     /**
+     * @return Small hash of the conversation ID, if present, or 0 otherwise.
+     */
+    static int getConversationIdHash(@NonNull NotificationChannel channel) {
+        return SmallHash.hash(channel.getConversationId());
+    }
+
+    /**
      * @return Small hash of the channel ID, if present, or 0 otherwise.
      */
     static int getIdHash(@NonNull NotificationChannelGroup group) {
diff --git a/services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java
index fd3dd56..5a7bc48 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelLoggerImpl.java
@@ -41,7 +41,12 @@
                 /* String package_name */ pkg,
                 /* int32 channel_id_hash */ NotificationChannelLogger.getIdHash(channel),
                 /* int old_importance*/ oldImportance,
-                /* int importance*/ newImportance);
+                /* int importance*/ newImportance,
+                /* bool is_conversation */ channel.isConversation(),
+                /* int32 conversation_id_hash */
+                NotificationChannelLogger.getConversationIdHash(channel),
+                /* bool is_conversation_demoted */ channel.isDemoted(),
+                /* bool is_conversation_priority */ channel.isImportantConversation());
     }
 
     @Override
@@ -53,7 +58,11 @@
                 /* String package_name */ pkg,
                 /* int32 channel_id_hash */ NotificationChannelLogger.getIdHash(channelGroup),
                 /* int old_importance*/ NotificationChannelLogger.getImportance(wasBlocked),
-                /* int importance*/ NotificationChannelLogger.getImportance(channelGroup));
+                /* int importance*/ NotificationChannelLogger.getImportance(channelGroup),
+                /* bool is_conversation */ false,
+                /* int32 conversation_id_hash */ 0,
+                /* bool is_conversation_demoted */ false,
+                /* bool is_conversation_priority */ false);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4f4f3c6..1516cde 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3526,6 +3526,20 @@
         }
 
         @Override
+        public void unlockNotificationChannel(String pkg, int uid, String channelId) {
+            checkCallerIsSystemOrSystemUiOrShell("Caller not system or sysui or shell");
+            mPreferencesHelper.unlockNotificationChannelImportance(pkg, uid, channelId);
+            handleSavePolicyFile();
+        }
+
+        @Override
+        public void unlockAllNotificationChannels() {
+            checkCallerIsSystem();
+            mPreferencesHelper.unlockAllNotificationChannels();
+            handleSavePolicyFile();
+        }
+
+        @Override
         public ParceledListSlice<NotificationChannel> getNotificationChannelsForPackage(String pkg,
                 int uid, boolean includeDeleted) {
             enforceSystemOrSystemUI("getNotificationChannelsForPackage");
@@ -5498,6 +5512,8 @@
                     pw.println("  mCallState=" + callStateToString(mCallState));
                     pw.println("  mSystemReady=" + mSystemReady);
                     pw.println("  mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate);
+                    pw.println("  hideSilentStatusBar="
+                            + mPreferencesHelper.shouldHideSilentStatusIcons());
                 }
                 pw.println("  mArchive=" + mArchive.toString());
                 Iterator<Pair<StatusBarNotification, Integer>> iter = mArchive.descendingIterator();
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 77713a6..2f990c6 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -18,6 +18,7 @@
 
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
+import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
@@ -955,6 +956,23 @@
         channel.unlockFields(channel.getUserLockedFields());
     }
 
+    void unlockNotificationChannelImportance(String pkg, int uid, String updatedChannelId) {
+        Objects.requireNonNull(updatedChannelId);
+        synchronized (mPackagePreferences) {
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
+            if (r == null) {
+                throw new IllegalArgumentException("Invalid package");
+            }
+
+            NotificationChannel channel = r.channels.get(updatedChannelId);
+            if (channel == null || channel.isDeleted()) {
+                throw new IllegalArgumentException("Channel does not exist");
+            }
+            channel.unlockFields(USER_LOCKED_IMPORTANCE);
+        }
+    }
+
+
     @Override
     public void updateNotificationChannel(String pkg, int uid, NotificationChannel updatedChannel,
             boolean fromUser) {
@@ -2389,6 +2407,18 @@
         return mBadgingEnabled.get(userId, DEFAULT_SHOW_BADGE);
     }
 
+    public void unlockAllNotificationChannels() {
+        synchronized (mPackagePreferences) {
+            final int numPackagePreferences = mPackagePreferences.size();
+            for (int i = 0; i < numPackagePreferences; i++) {
+                final PackagePreferences r = mPackagePreferences.valueAt(i);
+                for (NotificationChannel channel : r.channels.values()) {
+                    channel.unlockFields(USER_LOCKED_IMPORTANCE);
+                }
+            }
+        }
+    }
+
     private void updateConfig() {
         mRankingHandler.requestSort();
     }
diff --git a/services/core/java/com/android/server/pm/IncrementalStates.java b/services/core/java/com/android/server/pm/IncrementalStates.java
index 72803ac..780c522 100644
--- a/services/core/java/com/android/server/pm/IncrementalStates.java
+++ b/services/core/java/com/android/server/pm/IncrementalStates.java
@@ -101,21 +101,18 @@
         if (DEBUG) {
             Slog.i(TAG, "received package commit event");
         }
+        final boolean startableStateChanged;
         synchronized (mLock) {
-            if (!mStartableState.isStartable()) {
-                mStartableState.adoptNewStartableStateLocked(true);
-            }
+            startableStateChanged = mStartableState.adoptNewStartableStateLocked(true);
             if (!isIncremental) {
                 updateProgressLocked(1);
             }
         }
-        mHandler.post(PooledLambda.obtainRunnable(
-                IncrementalStates::reportStartableState,
-                IncrementalStates.this).recycleOnUse());
+        if (startableStateChanged) {
+            onStartableStateChanged();
+        }
         if (!isIncremental) {
-            mHandler.post(PooledLambda.obtainRunnable(
-                    IncrementalStates::reportFullyLoaded,
-                    IncrementalStates.this).recycleOnUse());
+            onLoadingStateChanged();
         }
     }
 
@@ -131,8 +128,7 @@
         synchronized (mLock) {
             if (mStartableState.isStartable() && mLoadingState.isLoading()) {
                 // Changing from startable -> unstartable only if app is still loading.
-                mStartableState.adoptNewStartableStateLocked(false);
-                startableStateChanged = true;
+                startableStateChanged = mStartableState.adoptNewStartableStateLocked(false);
             } else {
                 // If the app is fully loaded, the crash or ANR is caused by the app itself, so
                 // we do not change the startable state.
@@ -140,12 +136,15 @@
             }
         }
         if (startableStateChanged) {
-            mHandler.post(PooledLambda.obtainRunnable(
-                    IncrementalStates::reportStartableState,
-                    IncrementalStates.this).recycleOnUse());
+            onStartableStateChanged();
         }
     }
 
+    private void onStartableStateChanged() {
+        // Disable startable state broadcasts
+        // TODO(b/171920377): completely remove unstartable state.
+    }
+
     private void reportStartableState() {
         final Callback callback;
         final boolean startable;
@@ -165,6 +164,12 @@
         }
     }
 
+    private void onLoadingStateChanged() {
+        mHandler.post(PooledLambda.obtainRunnable(
+                IncrementalStates::reportFullyLoaded,
+                IncrementalStates.this).recycleOnUse());
+    }
+
     private void reportFullyLoaded() {
         final Callback callback;
         synchronized (mLock) {
@@ -178,23 +183,20 @@
     private class StatusConsumer implements Consumer<Integer> {
         @Override
         public void accept(Integer storageStatus) {
-            final boolean oldState, newState;
+            final boolean startableStateChanged;
             synchronized (mLock) {
                 if (!mLoadingState.isLoading()) {
                     // Do nothing if the package is already fully loaded
                     return;
                 }
-                oldState = mStartableState.isStartable();
                 mStorageHealthStatus = storageStatus;
-                updateStartableStateLocked();
-                newState = mStartableState.isStartable();
+                startableStateChanged = updateStartableStateLocked();
             }
-            if (oldState != newState) {
-                mHandler.post(PooledLambda.obtainRunnable(IncrementalStates::reportStartableState,
-                        IncrementalStates.this).recycleOnUse());
+            if (startableStateChanged) {
+                onStartableStateChanged();
             }
         }
-    };
+    }
 
     /**
      * By calling this method, the caller indicates that there issues with the Incremental
@@ -239,14 +241,10 @@
             newStartableState = mStartableState.isStartable();
         }
         if (!newLoadingState) {
-            mHandler.post(PooledLambda.obtainRunnable(
-                    IncrementalStates::reportFullyLoaded,
-                    IncrementalStates.this).recycleOnUse());
+            onLoadingStateChanged();
         }
         if (newStartableState != oldStartableState) {
-            mHandler.post(PooledLambda.obtainRunnable(
-                    IncrementalStates::reportStartableState,
-                    IncrementalStates.this).recycleOnUse());
+            onStartableStateChanged();
         }
     }
 
@@ -284,8 +282,9 @@
      * health
      * status. If the next state is different from the current state, proceed with state
      * change.
+     * @return True if the new startable state is different from the old one.
      */
-    private void updateStartableStateLocked() {
+    private boolean updateStartableStateLocked() {
         final boolean currentState = mStartableState.isStartable();
         boolean nextState = currentState;
         if (!currentState) {
@@ -302,9 +301,9 @@
             }
         }
         if (nextState == currentState) {
-            return;
+            return false;
         }
-        mStartableState.adoptNewStartableStateLocked(nextState);
+        return mStartableState.adoptNewStartableStateLocked(nextState);
     }
 
     private void updateProgressLocked(float progress) {
@@ -343,12 +342,30 @@
             return mUnstartableReason;
         }
 
-        public void adoptNewStartableStateLocked(boolean nextState) {
+        /**
+         * Adopt new startable state if it is different from the current state.
+         * @param nextState True if startable, false if unstartable.
+         * @return True if the state has changed, false otherwise.
+         */
+        public boolean adoptNewStartableStateLocked(boolean nextState) {
+            if (mIsStartable == nextState) {
+                return false;
+            }
+            if (!nextState) {
+                // Do nothing if the next state is "unstartable"; keep package always startable.
+                // TODO(b/171920377): completely remove unstartable state.
+                if (DEBUG) {
+                    Slog.i(TAG, "Attempting to set startable state to false. Abort.");
+                }
+                return false;
+            }
             if (DEBUG) {
-                Slog.i(TAG, "startable state changed from " + mIsStartable + " to " + nextState);
+                Slog.i(TAG,
+                        "startable state changed from " + mIsStartable + " to " + nextState);
             }
             mIsStartable = nextState;
             mUnstartableReason = getUnstartableReasonLocked();
+            return true;
         }
 
         private int getUnstartableReasonLocked() {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 5d2928e..57b80ea 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -3058,6 +3058,31 @@
         }
     }
 
+    /**
+     * Cleans up the relevant stored files and information of all child sessions.
+     * <p>Cleaning up the stored files and session information is necessary for
+     * preventing the orphan children sessions.
+     * <ol>
+     *     <li>To call {@link #destroyInternal()} cleans up the stored files.</li>
+     *     <li>To call {@link #dispatchSessionFinished(int, String, Bundle)} to trigger the
+     *     procedure to clean up the information in PackageInstallerService.</li>
+     * </ol></p>
+     */
+    private void maybeCleanUpChildSessions() {
+        if (!isMultiPackage()) {
+            return;
+        }
+
+        final List<PackageInstallerSession> childSessions = getChildSessions();
+        final int size = childSessions.size();
+        for (int i = 0; i < size; ++i) {
+            final PackageInstallerSession session = childSessions.get(i);
+            session.destroyInternal();
+            session.dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned"
+                            + " because the parent session is abandoned", null);
+        }
+    }
+
     private void abandonNonStaged() {
         synchronized (mLock) {
             assertCallerIsOwnerOrRootLocked();
@@ -3068,6 +3093,7 @@
             destroyInternal();
         }
         dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
+        maybeCleanUpChildSessions();
     }
 
     private void abandonStaged() {
@@ -3092,6 +3118,7 @@
                 cleanStageDir(childSessions);
                 destroyInternal();
                 dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
+                maybeCleanUpChildSessions();
             };
             if (mInPreRebootVerification) {
                 // Pre-reboot verification is ongoing. It is not safe to clean up the session yet.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 925d3cc..f68469f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -545,7 +545,6 @@
     static final int SCAN_AS_SYSTEM_EXT = 1 << 21;
     static final int SCAN_AS_ODM = 1 << 22;
     static final int SCAN_AS_APK_IN_APEX = 1 << 23;
-    static final int SCAN_EXPECTED_BETTER = 1 << 24;
 
     @IntDef(flag = true, prefix = { "SCAN_" }, value = {
             SCAN_NO_DEX,
@@ -805,12 +804,11 @@
     final SparseIntArray mIsolatedOwners = new SparseIntArray();
 
     /**
-     * Tracks packages that we expect to find updated versions of on disk.
-     * Keys are package name, values are package location and package version code.
-     *
-     * @see #expectBetter(String, File, long)
+     * Tracks new system packages [received in an OTA] that we expect to
+     * find updated user-installed versions. Keys are package name, values
+     * are package location.
      */
-    private final ArrayMap<String, List<Pair<File, Long>>> mExpectingBetter = new ArrayMap<>();
+    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
 
     /**
      * Tracks existing packages prior to receiving an OTA. Keys are package name.
@@ -3351,7 +3349,7 @@
                                     + ", versionCode=" + ps.versionCode
                                     + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
                             removePackageLI(scannedPkg, true);
-                            expectBetter(ps.name, ps.getPath(), ps.versionCode);
+                            mExpectingBetter.put(ps.name, ps.getPath());
                         }
 
                         continue;
@@ -3381,8 +3379,7 @@
                             // We're expecting that the system app should remain disabled, but add
                             // it to expecting better to recover in case the data version cannot
                             // be scanned.
-                            expectBetter(disabledPs.name, disabledPs.getPath(),
-                                    disabledPs.versionCode);
+                            mExpectingBetter.put(disabledPs.name, disabledPs.getPath());
                         }
                     }
                 }
@@ -3483,48 +3480,38 @@
                 for (int i = 0; i < mExpectingBetter.size(); i++) {
                     final String packageName = mExpectingBetter.keyAt(i);
                     if (!mPackages.containsKey(packageName)) {
+                        final File scanFile = mExpectingBetter.valueAt(i);
+
                         logCriticalInfo(Log.WARN, "Expected better " + packageName
                                 + " but never showed up; reverting to system");
 
-                        final List<Pair<File, Long>> scanFiles = mExpectingBetter.valueAt(i);
-                        // Sort ascending and iterate backwards to take highest version code
-                        Collections.sort(scanFiles,
-                                (first, second) -> Long.compare(first.second, second.second));
-                        for (int index = scanFiles.size() - 1; index >= 0; index--) {
-                            File scanFile = scanFiles.get(index).first;
-
-                            @ParseFlags int reparseFlags = 0;
-                            @ScanFlags int rescanFlags = 0;
-                            for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) {
-                                final ScanPartition partition = mDirsToScanAsSystem.get(i1);
-                                if (partition.containsPrivApp(scanFile)) {
-                                    reparseFlags = systemParseFlags;
-                                    rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
-                                            | partition.scanFlag;
-                                    break;
-                                }
-                                if (partition.containsApp(scanFile)) {
-                                    reparseFlags = systemParseFlags;
-                                    rescanFlags = systemScanFlags | partition.scanFlag;
-                                    break;
-                                }
-                            }
-                            if (rescanFlags == 0) {
-                                Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
-                                continue;
-                            }
-                            mSettings.enableSystemPackageLPw(packageName);
-
-                            rescanFlags |= SCAN_EXPECTED_BETTER;
-
-                            try {
-                                scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
-                                // Take first success and break out of for loop
+                        @ParseFlags int reparseFlags = 0;
+                        @ScanFlags int rescanFlags = 0;
+                        for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) {
+                            final ScanPartition partition = mDirsToScanAsSystem.get(i1);
+                            if (partition.containsPrivApp(scanFile)) {
+                                reparseFlags = systemParseFlags;
+                                rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
+                                        | partition.scanFlag;
                                 break;
-                            } catch (PackageManagerException e) {
-                                Slog.e(TAG, "Failed to parse original system package: "
-                                        + e.getMessage());
                             }
+                            if (partition.containsApp(scanFile)) {
+                                reparseFlags = systemParseFlags;
+                                rescanFlags = systemScanFlags | partition.scanFlag;
+                                break;
+                            }
+                        }
+                        if (rescanFlags == 0) {
+                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
+                            continue;
+                        }
+                        mSettings.enableSystemPackageLPw(packageName);
+
+                        try {
+                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
+                        } catch (PackageManagerException e) {
+                            Slog.e(TAG, "Failed to parse original system package: "
+                                    + e.getMessage());
                         }
                     }
                 }
@@ -3914,33 +3901,6 @@
     }
 
     /**
-     * Mark a package as skipped during initial scan, expecting a more up to date version to be
-     * available on the scan of a higher priority partition. This can be either a system partition
-     * or the data partition.
-     *
-     * If for some reason that newer version cannot be scanned successfully, the data structure
-     * created here will be used to backtrack in the scanning process to try and take the highest
-     * version code of the package left on disk that scans successfully.
-     *
-     * This can occur if an OTA adds a new system package which the user has already installed an
-     * update on data for. Or if the device image includes multiple versions of the same package,
-     * for cases where the maintainer of a higher priority partition wants to update an app on
-     * a lower priority partition before shipping a device to users.
-     *
-     * @param pkgName the package name identifier to queue under
-     * @param codePath the path to re-scan if needed
-     * @param knownVersionCode the version of the package so that the set of files can be sorted
-     */
-    private void expectBetter(String pkgName, File codePath, long knownVersionCode) {
-        List<Pair<File, Long>> pairs = mExpectingBetter.get(pkgName);
-        if (pairs == null) {
-            pairs = new ArrayList<>(0);
-            mExpectingBetter.put(pkgName, pairs);
-        }
-        pairs.add(Pair.create(codePath, knownVersionCode));
-    }
-
-    /**
      * Extract, install and enable a stub package.
      * <p>If the compressed file can not be extracted / installed for any reason, the stub
      * APK will be installed and the package will be disabled. To recover from this situation,
@@ -11311,23 +11271,7 @@
                 isUpdatedSystemApp = disabledPkgSetting != null;
             }
             applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp);
-            try {
-                assertPackageIsValid(parsedPackage, pkgSetting, parseFlags, scanFlags);
-            } catch (PackageManagerException e) {
-                if (e.error == INSTALL_FAILED_VERSION_DOWNGRADE
-                        && ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0)
-                        && ((scanFlags & SCAN_BOOTING) != 0)) {
-                    if (pkgSetting != null && pkgSetting.getPkg() == null) {
-                        // If a package for the pkgSetting hasn't already been found, this is
-                        // skipping a downgrade on a lower priority partition, and so a later scan
-                        // is expected to fill the package.
-                        expectBetter(pkgSetting.name, new File(parsedPackage.getPath()),
-                                parsedPackage.getLongVersionCode());
-                    }
-                }
-
-                throw e;
-            }
+            assertPackageIsValid(parsedPackage, parseFlags, scanFlags);
 
             SharedUserSetting sharedUserSetting = null;
             if (parsedPackage.getSharedUserId() != null) {
@@ -12179,9 +12123,9 @@
      *
      * @throws PackageManagerException If the package fails any of the validation checks
      */
-    private void assertPackageIsValid(AndroidPackage pkg,
-            @Nullable PackageSetting existingPkgSetting, final @ParseFlags int parseFlags,
-            final @ScanFlags int scanFlags) throws PackageManagerException {
+    private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags,
+            final @ScanFlags int scanFlags)
+                    throws PackageManagerException {
         if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
             assertCodePolicy(pkg);
         }
@@ -12196,11 +12140,11 @@
         // after OTA.
         final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
         final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
-        String pkgName = pkg.getPackageName();
         if ((isUserInstall || isFirstBootOrUpgrade)
-                && mApexManager.isApexPackage(pkgName)) {
+                && mApexManager.isApexPackage(pkg.getPackageName())) {
             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
-                    pkgName + " is an APEX package and can't be installed as an APK.");
+                    pkg.getPackageName()
+                            + " is an APEX package and can't be installed as an APK.");
         }
 
         // Make sure we're not adding any bogus keyset info
@@ -12209,7 +12153,7 @@
 
         synchronized (mLock) {
             // The special "android" package can only be defined once
-            if (pkgName.equals("android")) {
+            if (pkg.getPackageName().equals("android")) {
                 if (mAndroidApplication != null) {
                     Slog.w(TAG, "*************************************************");
                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
@@ -12220,46 +12164,12 @@
                 }
             }
 
-            final long newLongVersionCode = pkg.getLongVersionCode();
-            if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
-                boolean runDuplicateCheck = false;
-
-                // It's possible to re-scan a package if an updated system app was expected, but
-                // no update on /data could be found. To avoid infinitely looping, a flag is passed
-                // in when re-scanning and this first branch is skipped if the flag is set.
-                if ((scanFlags & SCAN_EXPECTED_BETTER) == 0 && existingPkgSetting != null) {
-                    long existingLongVersionCode = existingPkgSetting.versionCode;
-                    if (newLongVersionCode <= existingLongVersionCode) {
-                        // Must check that real name is equivalent, as it's possible to downgrade
-                        // version code if the package is actually a different package taking over
-                        // a package name through <original-package/>. It is assumed that this
-                        // migration is one time, one way, and that there is no failsafe if this
-                        // doesn't hold true.
-                        if (Objects.equals(existingPkgSetting.realName, pkg.getRealPackage())) {
-                            if (newLongVersionCode != existingLongVersionCode) {
-                                throw new PackageManagerException(
-                                        INSTALL_FAILED_VERSION_DOWNGRADE,
-                                        "Ignoring lower version " + newLongVersionCode
-                                                + " for package " + pkgName
-                                                + " with expected version "
-                                                + existingLongVersionCode);
-                            }
-                        }
-                    } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0
-                            && (scanFlags & SCAN_BOOTING) != 0) {
-                        // During system boot scan, if there's already a package known, but this
-                        // package is higher version, use it instead, ignoring the duplicate check.
-                        // This will store the higher version in the setting object, and the above
-                        // branch/exception will cause future scans to skip the lower versions.
-                        runDuplicateCheck = false;
-                    }
-                }
-
-                if (runDuplicateCheck && mPackages.containsKey(pkgName)) {
-                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
-                            "Application package " + pkgName
-                                    + " already installed.  Skipping duplicate.");
-                }
+            // A package name must be unique; don't allow duplicates
+            if ((scanFlags & SCAN_NEW_INSTALL) == 0
+                    && mPackages.containsKey(pkg.getPackageName())) {
+                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
+                        "Application package " + pkg.getPackageName()
+                        + " already installed.  Skipping duplicate.");
             }
 
             if (pkg.isStaticSharedLibrary()) {
@@ -12379,8 +12289,8 @@
                         }
                     }
                 }
-                if (newLongVersionCode < minVersionCode
-                        || newLongVersionCode > maxVersionCode) {
+                if (pkg.getLongVersionCode() < minVersionCode
+                        || pkg.getLongVersionCode() > maxVersionCode) {
                     throw new PackageManagerException("Static shared"
                             + " lib version codes must be ordered as lib versions");
                 }
@@ -12395,10 +12305,11 @@
             // to the user-installed location. If we don't allow this change, any newer,
             // user-installed version of the application will be ignored.
             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
-                if (mExpectingBetter.containsKey(pkgName)) {
-                    Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkgName);
+                if (mExpectingBetter.containsKey(pkg.getPackageName())) {
+                    Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package "
+                            + pkg.getPackageName());
                 } else {
-                    PackageSetting known = mSettings.getPackageLPr(pkgName);
+                    PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
                     if (known != null) {
                         if (DEBUG_PACKAGE_SCANNING) {
                             Log.d(TAG, "Examining " + pkg.getPath()
@@ -12406,14 +12317,14 @@
                         }
                         if (!pkg.getPath().equals(known.getPathString())) {
                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
-                                    "Application package " + pkgName
+                                    "Application package " + pkg.getPackageName()
                                     + " found at " + pkg.getPath()
                                     + " but expected at " + known.getPathString()
                                     + "; ignoring.");
                         }
                     } else {
                         throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
-                                "Application package " + pkgName
+                                "Application package " + pkg.getPackageName()
                                 + " not found; ignoring.");
                     }
                 }
@@ -12436,7 +12347,7 @@
                             INSTALL_FAILED_PROCESS_NOT_DEFINED,
                             "Can't install because application tag's process attribute "
                                     + pkg.getProcessName()
-                                    + " (in package " + pkgName
+                                    + " (in package " + pkg.getPackageName()
                                     + ") is not included in the <processes> list");
                 }
                 assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
@@ -12460,7 +12371,7 @@
                             pkg.getSigningDetails().signatures)) {
                         throw new PackageManagerException("Apps that share a user with a " +
                                 "privileged app must themselves be marked as privileged. " +
-                                pkgName + " shares privileged user " +
+                                pkg.getPackageName() + " shares privileged user " +
                                 pkg.getSharedUserId() + ".");
                     }
                 }
@@ -12477,21 +12388,21 @@
                         // upgraded.
                         Objects.requireNonNull(mOverlayConfig,
                                 "Parsing non-system dir before overlay configs are initialized");
-                        if (!mOverlayConfig.isMutable(pkgName)) {
+                        if (!mOverlayConfig.isMutable(pkg.getPackageName())) {
                             throw new PackageManagerException("Overlay "
-                                    + pkgName
+                                    + pkg.getPackageName()
                                     + " is static and cannot be upgraded.");
                         }
                     } else {
                         if ((scanFlags & SCAN_AS_VENDOR) != 0) {
                             if (pkg.getTargetSdkVersion() < getVendorPartitionVersion()) {
-                                Slog.w(TAG, "System overlay " + pkgName
+                                Slog.w(TAG, "System overlay " + pkg.getPackageName()
                                         + " targets an SDK below the required SDK level of vendor"
                                         + " overlays (" + getVendorPartitionVersion() + ")."
                                         + " This will become an install error in a future release");
                             }
                         } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) {
-                            Slog.w(TAG, "System overlay " + pkgName
+                            Slog.w(TAG, "System overlay " + pkg.getPackageName()
                                     + " targets an SDK below the required SDK level of system"
                                     + " overlays (" + Build.VERSION.SDK_INT + ")."
                                     + " This will become an install error in a future release");
@@ -12507,7 +12418,7 @@
                         if (!comparePackageSignatures(platformPkgSetting,
                                 pkg.getSigningDetails().signatures)) {
                             throw new PackageManagerException("Overlay "
-                                    + pkgName
+                                    + pkg.getPackageName()
                                     + " must target Q or later, "
                                     + "or be signed with the platform certificate");
                         }
@@ -12529,7 +12440,7 @@
                                 // check reference signature
                                 if (mOverlayConfigSignaturePackage == null) {
                                     throw new PackageManagerException("Overlay "
-                                            + pkgName + " and target "
+                                            + pkg.getPackageName() + " and target "
                                             + pkg.getOverlayTarget() + " signed with"
                                             + " different certificates, and the overlay lacks"
                                             + " <overlay android:targetName>");
@@ -12539,7 +12450,7 @@
                                 if (!comparePackageSignatures(refPkgSetting,
                                         pkg.getSigningDetails().signatures)) {
                                     throw new PackageManagerException("Overlay "
-                                            + pkgName + " signed with a different "
+                                            + pkg.getPackageName() + " signed with a different "
                                             + "certificate than both the reference package and "
                                             + "target " + pkg.getOverlayTarget() + ", and the "
                                             + "overlay lacks <overlay android:targetName>");
@@ -12559,7 +12470,7 @@
                 if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
                     throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
                             "No signature found in package of version " + minSignatureSchemeVersion
-                                    + " or newer for package " + pkgName);
+                                    + " or newer for package " + pkg.getPackageName());
                 }
             }
         }
@@ -16567,8 +16478,8 @@
                     healthCheckParams.unhealthyTimeoutMs = INCREMENTAL_STORAGE_UNHEALTHY_TIMEOUT_MS;
                     healthCheckParams.unhealthyMonitoringMs =
                             INCREMENTAL_STORAGE_UNHEALTHY_MONITORING_MS;
-                    mIncrementalManager.registerHealthListener(codePath,
-                            new StorageHealthCheckParams(), incrementalHealthListener);
+                    mIncrementalManager.registerHealthListener(codePath, healthCheckParams,
+                            incrementalHealthListener);
                 }
 
                 // Ensure that the uninstall reason is UNKNOWN for users with the package installed.
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index e99e301..3fcf02c 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -674,20 +674,6 @@
             return;
         }
 
-        if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
-            // If rollback is available for this session, notify the rollback
-            // manager of the apk session so it can properly enable rollback.
-            final RollbackManagerInternal rm =
-                    LocalServices.getService(RollbackManagerInternal.class);
-            try {
-                // TODO(b/136257624): extra apk session id in rollback is now redundant.
-                rm.notifyStagedApkSession(session.sessionId, session.sessionId);
-            } catch (RuntimeException re) {
-                Slog.e(TAG, "Failed to notifyStagedApkSession for session: "
-                        + session.sessionId, re);
-            }
-        }
-
         final LocalIntentReceiverSync receiver = new LocalIntentReceiverSync();
         session.installStagedSession(receiver.getIntentSender());
         final Intent result = receiver.getResult();
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 7f29cd9..24082b8 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3993,7 +3993,7 @@
     @Override
     public @UserManager.RemoveResult int removeUserOrSetEphemeral(@UserIdInt int userId) {
         Slog.i(LOG_TAG, "removeUserOrSetEphemeral u" + userId);
-        checkManageUsersPermission("Only the system can remove users");
+        checkManageOrCreateUsersPermission("Only the system can remove users");
         final String restriction = getUserRemovalRestriction(userId);
         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) {
             Slog.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled.");
diff --git a/services/core/java/com/android/server/pm/parsing/PackageCacher.java b/services/core/java/com/android/server/pm/parsing/PackageCacher.java
index 3463daf..74ec161 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageCacher.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageCacher.java
@@ -57,16 +57,7 @@
      * Returns the cache key for a specified {@code packageFile} and {@code flags}.
      */
     private String getCacheKey(File packageFile, int flags) {
-        StringBuilder sb = new StringBuilder();
-
-        // To support packages with the same file name across partitions, use the partition name
-        // as a prefix. The cache should only be used for cases where the file paths have been
-        // established using the unique partition names, without canonicalization, so any links
-        // which would point to the same partition name should be handled separately.
-        String cachePrefix = packageFile.toPath().getName(0).toString();
-        sb.append(cachePrefix);
-        sb.append('-');
-        sb.append(packageFile.getName());
+        StringBuilder sb = new StringBuilder(packageFile.getName());
         sb.append('-');
         sb.append(flags);
 
diff --git a/services/core/java/com/android/server/pm/parsing/PackageParser2.java b/services/core/java/com/android/server/pm/parsing/PackageParser2.java
index 46d31d9..851ddd1 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageParser2.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageParser2.java
@@ -135,7 +135,7 @@
     }
 
     /**
-     * TODO(b/155493909): Document new package parsing
+     * TODO(b/135203078): Document new package parsing
      */
     @AnyThread
     public ParsedPackage parsePackage(File packageFile, int flags, boolean useCaches)
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 1ae430a..bf5a50e 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -1272,7 +1272,12 @@
                     newFlags |= (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT);
 
                     // If we are allowlisting the permission, update the exempt flag before grant.
-                    if (whitelistRestrictedPermissions && pm.isPermissionRestricted(permission)) {
+                    // If the permission can't be allowlisted by an installer, skip it here because
+                    // this is where the platform takes the role of the installer for exempting
+                    // preinstalled apps.
+                    if (whitelistRestrictedPermissions && pm.isPermissionRestricted(permission)
+                            && !pm.getPermissionInfo(permission).isInstallerExemptIgnored()) {
+
                         pm.updatePermissionFlags(permission, pkg,
                                 PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT,
                                 PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, user);
diff --git a/services/core/java/com/android/server/pm/permission/Permission.java b/services/core/java/com/android/server/pm/permission/Permission.java
index 4e8ddac..0245b28 100644
--- a/services/core/java/com/android/server/pm/permission/Permission.java
+++ b/services/core/java/com/android/server/pm/permission/Permission.java
@@ -425,7 +425,7 @@
             permission = new Permission(permissionInfo.name, permissionInfo.packageName,
                     TYPE_MANIFEST);
         }
-        boolean wasNormal = permission.isNormal();
+        boolean wasNonRuntime = !permission.isRuntime();
         StringBuilder r = null;
         if (!permission.mReconciled) {
             if (permission.mPermissionInfo.packageName == null
@@ -465,8 +465,8 @@
             r.append("DUP:");
             r.append(permissionInfo.name);
         }
-        if (permission.isRuntime() && (ownerChanged || wasNormal)) {
-            // If this is a runtime permission and the owner has changed, or this was a normal
+        if (permission.isRuntime() && (ownerChanged || wasNonRuntime)) {
+            // If this is a runtime permission and the owner has changed, or this wasn't a runtime
             // permission, then permission state should be cleaned up
             permission.mDefinitionChanged = true;
         }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 84f9823..ff661a8 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -70,11 +70,16 @@
 import android.app.IActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
+import android.app.role.RoleManager;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledAfter;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.PermissionChecker;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.PermissionGroupInfoFlags;
 import android.content.pm.PackageManager.PermissionInfoFlags;
@@ -84,6 +89,7 @@
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
+import android.content.pm.UserInfo;
 import android.content.pm.parsing.component.ParsedPermission;
 import android.content.pm.parsing.component.ParsedPermissionGroup;
 import android.content.pm.permission.SplitPermissionInfoParcelable;
@@ -177,6 +183,7 @@
  */
 public class PermissionManagerService extends IPermissionManager.Stub {
     private static final String TAG = "PackageManager";
+    private static final String LOG_TAG = PermissionManagerService.class.getSimpleName();
 
     private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
 
@@ -417,6 +424,105 @@
                 new PermissionManagerServiceInternalImpl();
         LocalServices.addService(PermissionManagerServiceInternal.class, localService);
         LocalServices.addService(PermissionManagerInternal.class, localService);
+
+        context.getMainThreadHandler().post(() -> context.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (!Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+                    return;
+                }
+
+                try {
+                    fixBgMicCamera(context);
+                } catch (Throwable t) {
+                    // Don't crash the system if this fails for any reason. Any intermediate state
+                    // this can leave the permissions in is okay and in the worst case the state is
+                    // the same as before the user rebooted.
+                    Log.e(LOG_TAG, "Unable to fix background permissions", t);
+                }
+            }
+
+
+            private void fixBgMicCamera(Context context) {
+                PackageManager pm = context.getPackageManager();
+                for (UserInfo userInfo : context.getSystemService(UserManager.class).getUsers()) {
+                    UserHandle user = userInfo.getUserHandle();
+                    List<String> assistants = context.getSystemService(RoleManager.class)
+                            .getRoleHoldersAsUser(RoleManager.ROLE_ASSISTANT, user);
+                    List<PackageInfo> packages =
+                            pm.getInstalledPackagesAsUser(PackageManager.MATCH_SYSTEM_ONLY
+                                    | PackageManager.GET_PERMISSIONS, user.getIdentifier());
+                    for (PackageInfo packageInfo : packages) {
+                        String[] requestedPermissions = packageInfo.requestedPermissions;
+                        if (requestedPermissions == null) {
+                            continue;
+                        }
+                        for (String permName : requestedPermissions) {
+                            String pkg = packageInfo.packageName;
+                            switch (permName) {
+                                case Manifest.permission.BACKGROUND_CAMERA:
+                                    removeFromAllowlistsAndRevoke(pm, pkg, permName, user);
+                                    break;
+                                case Manifest.permission.RECORD_BACKGROUND_AUDIO:
+                                    if (assistants.contains(pkg)) {
+                                        removeFromAllowlistsAndRevokeForAssistant(pm, pkg, permName,
+                                                user);
+                                    } else {
+                                        removeFromAllowlistsAndRevoke(pm, pkg, permName, user);
+                                    }
+                                    break;
+                            }
+                        }
+                    }
+                }
+            }
+
+            private void removeFromAllowlistsAndRevoke(PackageManager pm, String pkg,
+                    String permName, UserHandle user) {
+                if ((pm.getPermissionFlags(permName, pkg, user)
+                        & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0) {
+                    Slog.i(LOG_TAG, "removing " + pkg + " " + permName + " from all allowlists");
+                    pm.removeWhitelistedRestrictedPermission(pkg, permName,
+                            FLAG_PERMISSION_WHITELIST_UPGRADE);
+                    pm.removeWhitelistedRestrictedPermission(pkg, permName,
+                            FLAG_PERMISSION_WHITELIST_SYSTEM);
+                    pm.removeWhitelistedRestrictedPermission(pkg, permName,
+                            FLAG_PERMISSION_WHITELIST_INSTALLER);
+                    pm.removeWhitelistedRestrictedPermission(pkg, permName,
+                            FLAG_PERMISSION_ALLOWLIST_ROLE);
+                }
+                if (pm.checkPermission(permName, pkg) == PackageManager.PERMISSION_GRANTED) {
+                    Slog.i(LOG_TAG, "revoking " + pkg + " " + permName);
+                    pm.revokeRuntimePermission(pkg, permName, user);
+                }
+            }
+
+            private void removeFromAllowlistsAndRevokeForAssistant(PackageManager pm, String pkg,
+                    String permName, UserHandle user) {
+                int anyNonRoleExempt =
+                        FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT
+                                | FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
+                                | FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+
+                if ((pm.getPermissionFlags(permName, pkg, user) & anyNonRoleExempt) != 0) {
+                    Slog.i(LOG_TAG, "removing " + pkg + " " + permName
+                            + " from all allowlists except role");
+                    pm.removeWhitelistedRestrictedPermission(pkg, permName,
+                            FLAG_PERMISSION_WHITELIST_UPGRADE);
+                    pm.removeWhitelistedRestrictedPermission(pkg, permName,
+                            FLAG_PERMISSION_WHITELIST_SYSTEM);
+                    pm.removeWhitelistedRestrictedPermission(pkg, permName,
+                            FLAG_PERMISSION_WHITELIST_INSTALLER);
+                }
+                if ((pm.getPermissionFlags(permName, pkg, user)
+                        & FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT) == 0) {
+                    Slog.i(LOG_TAG, "adding " + pkg + " " + permName
+                            + " to role allowlist");
+                    pm.addWhitelistedRestrictedPermission(pkg, permName,
+                            FLAG_PERMISSION_ALLOWLIST_ROLE);
+                }
+            }
+        }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED)));
     }
 
     @Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 8b677a9..25a0880 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -630,7 +630,6 @@
     private static final int MSG_SYSTEM_KEY_PRESS = 21;
     private static final int MSG_HANDLE_ALL_APPS = 22;
     private static final int MSG_LAUNCH_ASSIST = 23;
-    private static final int MSG_LAUNCH_ASSIST_LONG_PRESS = 24;
     private static final int MSG_POWER_VERY_LONG_PRESS = 25;
     private static final int MSG_RINGER_TOGGLE_CHORD = 26;
 
@@ -670,9 +669,6 @@
                     final String hint = (String) msg.obj;
                     launchAssistAction(hint, deviceId);
                     break;
-                case MSG_LAUNCH_ASSIST_LONG_PRESS:
-                    launchAssistLongPressAction();
-                    break;
                 case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK:
                     launchVoiceAssistWithWakeLock();
                     break;
@@ -2429,6 +2425,15 @@
             wm = (WindowManager) context.getSystemService(WINDOW_SERVICE);
             view = win.getDecorView();
 
+            // Ignore to show splash screen if the decorView is not opaque.
+            if (!view.isOpaque()) {
+                if (DEBUG_SPLASH_SCREEN) {
+                    Slog.d(TAG, "addSplashScreen: the view of " + packageName
+                            + " is not opaque, cancel it");
+                }
+                return null;
+            }
+
             if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "Adding splash screen window for "
                 + packageName + " / " + appToken + ": " + (view.getParent() != null ? view : null));
 
@@ -3249,28 +3254,6 @@
     // There are several different flavors of "assistant" that can be launched from
     // various parts of the UI.
 
-    /** starts ACTION_SEARCH_LONG_PRESS, usually a voice search prompt */
-    private void launchAssistLongPressAction() {
-        performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
-                "Assist - Long Press");
-        sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
-
-        // launch the search activity
-        Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        try {
-            // TODO: This only stops the factory-installed search manager.
-            // Need to formalize an API to handle others
-            SearchManager searchManager = getSearchManager();
-            if (searchManager != null) {
-                searchManager.stopSearch();
-            }
-            startActivityAsUser(intent, UserHandle.CURRENT);
-        } catch (ActivityNotFoundException e) {
-            Slog.w(TAG, "No activity to handle assist long press action.", e);
-        }
-    }
-
     /** Asks the status bar to startAssist(), usually a full "assistant" interface */
     private void launchAssistAction(String hint, int deviceId) {
         sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
@@ -3958,12 +3941,7 @@
             }
             case KeyEvent.KEYCODE_ASSIST: {
                 final boolean longPressed = event.getRepeatCount() > 0;
-                if (down && longPressed) {
-                    Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST_LONG_PRESS);
-                    msg.setAsynchronous(true);
-                    msg.sendToTarget();
-                }
-                if (!down && !longPressed) {
+                if (down && !longPressed) {
                     Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST, event.getDeviceId(),
                             0 /* unused */, null /* hint */);
                     msg.setAsynchronous(true);
@@ -5215,7 +5193,7 @@
                     final Intent dock = createHomeDockIntent();
                     if (dock != null) {
                         int result = ActivityTaskManager.getService()
-                                .startActivityAsUser(null, mContext.getBasePackageName(),
+                                .startActivityAsUser(null, mContext.getOpPackageName(),
                                         mContext.getAttributionTag(), dock,
                                         dock.resolveTypeIfNeeded(mContext.getContentResolver()),
                                         null, null, 0,
@@ -5227,7 +5205,7 @@
                     }
                 }
                 int result = ActivityTaskManager.getService()
-                        .startActivityAsUser(null, mContext.getBasePackageName(),
+                        .startActivityAsUser(null, mContext.getOpPackageName(),
                                 mContext.getAttributionTag(), mHomeIntent,
                                 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
                                 null, null, 0,
diff --git a/services/core/java/com/android/server/power/AmbientDisplaySuppressionController.java b/services/core/java/com/android/server/power/AmbientDisplaySuppressionController.java
index 3bb90ce..aad7b14 100644
--- a/services/core/java/com/android/server/power/AmbientDisplaySuppressionController.java
+++ b/services/core/java/com/android/server/power/AmbientDisplaySuppressionController.java
@@ -29,7 +29,9 @@
 import com.android.internal.statusbar.IStatusBarService;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -73,6 +75,24 @@
     }
 
     /**
+     * Returns the tokens used to suppress ambient display through
+     * {@link #suppress(String, int, boolean)}.
+     *
+     * @param callingUid The uid of the calling application.
+     */
+    List<String> getSuppressionTokens(int callingUid) {
+        List<String> result = new ArrayList<>();
+        synchronized (mSuppressionTokens) {
+            for (Pair<String, Integer> token : mSuppressionTokens) {
+                if (token.second == callingUid) {
+                    result.add(token.first);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
      * Returns whether ambient display is suppressed for the given token.
      *
      * @param token A persistible identifier for the ambient display suppression.
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 60da8e5..ccd659d 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -5500,6 +5500,22 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
+
+        /**
+         * Returns the tokens used to suppress ambient display by the calling app.
+         *
+         * <p>The calling app suppressed ambient display by calling
+         * {@link #suppressAmbientDisplay(String, boolean)}.
+         */
+        public List<String> getAmbientDisplaySuppressionTokens() {
+            final int uid = Binder.getCallingUid();
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return mAmbientDisplaySuppressionController.getSuppressionTokens(uid);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/power/PowerManagerShellCommand.java b/services/core/java/com/android/server/power/PowerManagerShellCommand.java
index ec5dcfa..a9b33ed 100644
--- a/services/core/java/com/android/server/power/PowerManagerShellCommand.java
+++ b/services/core/java/com/android/server/power/PowerManagerShellCommand.java
@@ -17,20 +17,20 @@
 package com.android.server.power;
 
 import android.content.Intent;
-import android.os.IPowerManager;
 import android.os.PowerManagerInternal;
 import android.os.RemoteException;
 import android.os.ShellCommand;
 
 import java.io.PrintWriter;
+import java.util.List;
 
 class PowerManagerShellCommand extends ShellCommand {
     private static final int LOW_POWER_MODE_ON = 1;
 
-    final IPowerManager mInterface;
+    final PowerManagerService.BinderService mService;
 
-    PowerManagerShellCommand(IPowerManager service) {
-        mInterface = service;
+    PowerManagerShellCommand(PowerManagerService.BinderService service) {
+        mService = service;
     }
 
     @Override
@@ -48,6 +48,10 @@
                     return runSetMode();
                 case "set-fixed-performance-mode-enabled":
                     return runSetFixedPerformanceModeEnabled();
+                case "suppress-ambient-display":
+                    return runSuppressAmbientDisplay();
+                case "list-ambient-display-suppression-tokens":
+                    return runListAmbientDisplaySuppressionTokens();
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -58,7 +62,7 @@
     }
 
     private int runSetAdaptiveEnabled() throws RemoteException {
-        mInterface.setAdaptivePowerSaveEnabled(Boolean.parseBoolean(getNextArgRequired()));
+        mService.setAdaptivePowerSaveEnabled(Boolean.parseBoolean(getNextArgRequired()));
         return 0;
     }
 
@@ -71,12 +75,12 @@
             pw.println("Error: " + ex.toString());
             return -1;
         }
-        mInterface.setPowerSaveModeEnabled(mode == LOW_POWER_MODE_ON);
+        mService.setPowerSaveModeEnabled(mode == LOW_POWER_MODE_ON);
         return 0;
     }
 
     private int runSetFixedPerformanceModeEnabled() throws RemoteException {
-        boolean success = mInterface.setPowerModeChecked(
+        boolean success = mService.setPowerModeChecked(
                 PowerManagerInternal.MODE_FIXED_PERFORMANCE,
                 Boolean.parseBoolean(getNextArgRequired()));
         if (!success) {
@@ -87,6 +91,32 @@
         return success ? 0 : -1;
     }
 
+    private int runSuppressAmbientDisplay() throws RemoteException {
+        final PrintWriter pw = getOutPrintWriter();
+
+        try {
+            String token = getNextArgRequired();
+            boolean enabled = Boolean.parseBoolean(getNextArgRequired());
+            mService.suppressAmbientDisplay(token, enabled);
+        } catch (RuntimeException ex) {
+            pw.println("Error: " + ex.toString());
+            return -1;
+        }
+
+        return 0;
+    }
+
+    private int runListAmbientDisplaySuppressionTokens() throws RemoteException {
+        final PrintWriter pw = getOutPrintWriter();
+        List<String> tokens = mService.getAmbientDisplaySuppressionTokens();
+        if (tokens.isEmpty()) {
+            pw.println("none");
+        } else {
+            pw.println(String.format("[%s]", String.join(", ", tokens)));
+        }
+
+        return 0;
+    }
     @Override
     public void onHelp() {
         final PrintWriter pw = getOutPrintWriter();
@@ -103,6 +133,11 @@
         pw.println("    enables or disables fixed performance mode");
         pw.println("    note: this will affect system performance and should only be used");
         pw.println("          during development");
+        pw.println("  suppress-ambient-display <token> [true|false]");
+        pw.println("    suppresses the current ambient display configuration and disables");
+        pw.println("    ambient display");
+        pw.println("  list-ambient-display-suppression-tokens");
+        pw.println("    prints the tokens used to suppress ambient display");
         pw.println();
         Intent.printIntentArgsHelp(pw , "");
     }
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index 2db6043..2d51cf9 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -146,11 +146,6 @@
     private @RollbackState int mState;
 
     /**
-     * The id of the post-reboot apk session for a staged install, if any.
-     */
-    private int mApkSessionId = -1;
-
-    /**
      * True if we are expecting the package manager to call restoreUserData
      * for this rollback because it has just been committed but the rollback
      * has not yet been fully applied.
@@ -236,7 +231,7 @@
      * Constructs a pre-populated Rollback instance.
      */
     Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
-            @RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress,
+            @RollbackState int state, boolean restoreUserDataInProgress,
             int userId, String installerPackageName, SparseIntArray extensionVersions) {
         this.info = info;
         mUserId = userId;
@@ -245,7 +240,6 @@
         mTimestamp = timestamp;
         mStagedSessionId = stagedSessionId;
         mState = state;
-        mApkSessionId = apkSessionId;
         mRestoreUserDataInProgress = restoreUserDataInProgress;
         mExtensionVersions = Objects.requireNonNull(extensionVersions);
         // TODO(b/120200473): Include this field during persistence. This field will be used to
@@ -727,25 +721,6 @@
     }
 
     /**
-     * Returns the id of the post-reboot apk session for a staged install, if any.
-     */
-    @WorkerThread
-    int getApkSessionId() {
-        assertInWorkerThread();
-        return mApkSessionId;
-    }
-
-    /**
-     * Sets the id of the post-reboot apk session for a staged install.
-     */
-    @WorkerThread
-    void setApkSessionId(int apkSessionId) {
-        assertInWorkerThread();
-        mApkSessionId = apkSessionId;
-        RollbackStore.saveRollback(this);
-    }
-
-    /**
      * Returns true if we are expecting the package manager to call restoreUserData for this
      * rollback because it has just been committed but the rollback has not yet been fully applied.
      */
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerInternal.java b/services/core/java/com/android/server/rollback/RollbackManagerInternal.java
index b473b8c..dbda4a8 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerInternal.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerInternal.java
@@ -53,13 +53,4 @@
      * @return The rollback id if rollback was enabled successfully, or -1 if not.
      */
     int notifyStagedSession(int sessionId);
-
-    /**
-     * Used by the staging manager to notify the RollbackManager of the apk
-     * session for a staged session.
-     *
-     * @param originalSessionId The original session ID where this apk session belongs
-     * @param apkSessionId The ID of this apk session
-     */
-    void notifyStagedApkSession(int originalSessionId, int apkSessionId);
 }
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 1e89e06..b34d46f 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -28,6 +28,7 @@
 import android.content.IntentFilter;
 import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ModuleInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
@@ -53,7 +54,6 @@
 import android.os.UserManager;
 import android.os.ext.SdkExtensions;
 import android.provider.DeviceConfig;
-import android.util.IntArray;
 import android.util.Log;
 import android.util.LongArrayQueue;
 import android.util.Slog;
@@ -151,10 +151,6 @@
     // Accessed on the handler thread only.
     private final List<Rollback> mRollbacks = new ArrayList<>();
 
-    // Apk sessions from a staged session with no matching rollback.
-    // Accessed on the handler thread only.
-    private final IntArray mOrphanedApkSessionIds = new IntArray();
-
     private final RollbackStore mRollbackStore;
 
     private final Context mContext;
@@ -646,8 +642,6 @@
                 onPackageReplaced(apexPackageName);
             }
 
-            mOrphanedApkSessionIds.clear();
-
             mPackageHealthObserver.onBootCompletedAsync();
         });
     }
@@ -782,25 +776,6 @@
             return false;
         }
 
-        // Check to see if this is the apk session for a staged session with
-        // rollback enabled.
-        for (int i = 0; i < mRollbacks.size(); ++i) {
-            Rollback rollback = mRollbacks.get(i);
-            if (rollback.getApkSessionId() == parentSession.getSessionId()) {
-                // This is the apk session for a staged session with rollback enabled. We do
-                // not need to create a new rollback for this session.
-                return true;
-            }
-        }
-
-        // Check to see if this is the apk session for a staged session for which rollback was
-        // cancelled.
-        if (mOrphanedApkSessionIds.indexOf(parentSession.getSessionId()) != -1) {
-            Slog.w(TAG, "Not enabling rollback for apk as no matching staged session "
-                    + "rollback exists");
-            return false;
-        }
-
         // See if we already have a Rollback that contains this package
         // session. If not, create a new Rollback for the parent session
         // that we will use for all the packages in the session.
@@ -1038,37 +1013,6 @@
         });
     }
 
-    @ExtThread
-    @Override
-    public void notifyStagedApkSession(int originalSessionId, int apkSessionId) {
-        assertNotInWorkerThread();
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("notifyStagedApkSession may only be called by the system.");
-        }
-        getHandler().post(() -> {
-            assertInWorkerThread();
-            Rollback rollback = null;
-            for (int i = 0; i < mRollbacks.size(); ++i) {
-                Rollback candidate = mRollbacks.get(i);
-                if (candidate.getStagedSessionId() == originalSessionId) {
-                    rollback = candidate;
-                    break;
-                }
-            }
-            if (rollback == null) {
-                // Did not find rollback matching originalSessionId.
-                Slog.e(TAG, "notifyStagedApkSession did not find rollback for session "
-                        + originalSessionId
-                        + ". Adding orphaned apk session " + apkSessionId);
-                mOrphanedApkSessionIds.add(apkSessionId);
-            }
-
-            if (rollback != null) {
-                rollback.setApkSessionId(apkSessionId);
-            }
-        });
-    }
-
     /**
      * Returns true if the installer is allowed to enable rollback for the
      * given named package, false otherwise.
@@ -1088,8 +1032,8 @@
                 Manifest.permission.TEST_MANAGE_ROLLBACKS,
                 installerPackageName) == PackageManager.PERMISSION_GRANTED;
 
-        // For now only allow rollbacks for allowlisted packages or for testing.
-        return (isRollbackAllowlisted(packageName) && manageRollbacksGranted)
+        // For now only allow rollbacks for modules, allowlisted packages, or for testing.
+        return (isRollbackAllowed(packageName) && manageRollbacksGranted)
             || testManageRollbacksGranted;
     }
 
@@ -1097,8 +1041,24 @@
      * Returns true is this package is eligible for enabling rollback.
      */
     @AnyThread
-    private boolean isRollbackAllowlisted(String packageName) {
-        return SystemConfig.getInstance().getRollbackWhitelistedPackages().contains(packageName);
+    private boolean isRollbackAllowed(String packageName) {
+        return SystemConfig.getInstance().getRollbackWhitelistedPackages().contains(packageName)
+                || isModule(packageName);
+    }
+    /**
+     * Returns true if the package name is the name of a module.
+     */
+    @AnyThread
+    private boolean isModule(String packageName) {
+        PackageManager pm = mContext.getPackageManager();
+        final ModuleInfo moduleInfo;
+        try {
+            moduleInfo = pm.getModuleInfo(packageName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+
+        return moduleInfo != null;
     }
 
     /**
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index ba1401d..1295b70 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -92,7 +92,7 @@
 
     @Override
     public int onHealthCheckFailed(@Nullable VersionedPackage failedPackage,
-            @FailureReasons int failureReason) {
+            @FailureReasons int failureReason, int mitigationCount) {
         // For native crashes, we will roll back any available rollbacks
         if (failureReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH
                 && !mContext.getSystemService(RollbackManager.class)
@@ -110,7 +110,7 @@
 
     @Override
     public boolean execute(@Nullable VersionedPackage failedPackage,
-            @FailureReasons int rollbackReason) {
+            @FailureReasons int rollbackReason, int mitigationCount) {
         if (rollbackReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
             mHandler.post(() -> rollbackAll());
             return true;
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 44a6336..2ee87e6 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -267,7 +267,6 @@
             dataJson.put("timestamp", rollback.getTimestamp().toString());
             dataJson.put("stagedSessionId", rollback.getStagedSessionId());
             dataJson.put("state", rollback.getStateAsString());
-            dataJson.put("apkSessionId", rollback.getApkSessionId());
             dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress());
             dataJson.put("userId", rollback.getUserId());
             dataJson.putOpt("installerPackageName", rollback.getInstallerPackageName());
@@ -319,7 +318,6 @@
                 Instant.parse(dataJson.getString("timestamp")),
                 dataJson.getInt("stagedSessionId"),
                 rollbackStateFromString(dataJson.getString("state")),
-                dataJson.getInt("apkSessionId"),
                 dataJson.getBoolean("restoreUserDataInProgress"),
                 dataJson.optInt("userId", UserHandle.SYSTEM.getIdentifier()),
                 dataJson.optString("installerPackageName", ""),
diff --git a/services/core/java/com/android/server/utils/Watchable.java b/services/core/java/com/android/server/utils/Watchable.java
new file mode 100644
index 0000000..7c99274
--- /dev/null
+++ b/services/core/java/com/android/server/utils/Watchable.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+package com.android.server.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * Notify registered {@link Watcher}s when the content changes.
+ */
+public interface Watchable {
+
+    /**
+     * Ensures an observer is in the list, exactly once. The observer cannot be null.  The
+     * function quietly returns if the observer is already in the list.
+     *
+     * @param observer The {@link Watcher} to be notified when the {@link Watchable} changes.
+     */
+    public void registerObserver(@NonNull Watcher observer);
+
+    /**
+     * Ensures an observer is not in the list. The observer must not be null.  The function
+     * quietly returns if the objserver is not in the list.
+     *
+     * @param observer The {@link Watcher} that should not be in the notification list.
+     */
+    public void unregisterObserver(@NonNull Watcher observer);
+
+    /**
+     * Invokes {@link Watcher#onChange} on each registered observer.  The method can be called
+     * with the {@link Watchable} that generated the event.  In a tree of {@link Watchable}s, this
+     * is generally the first (deepest) {@link Watchable} to detect a change.
+     *
+     * @param what The {@link Watchable} that generated the event.
+     */
+    public void dispatchChange(@Nullable Watchable what);
+}
diff --git a/services/core/java/com/android/server/utils/WatchableImpl.java b/services/core/java/com/android/server/utils/WatchableImpl.java
new file mode 100644
index 0000000..94ab1d4
--- /dev/null
+++ b/services/core/java/com/android/server/utils/WatchableImpl.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+package com.android.server.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+/**
+ * A concrete implementation of {@link Watchable}
+ */
+public class WatchableImpl implements Watchable {
+    /**
+     * The list of observers.
+     */
+    protected final ArrayList<Watcher> mObservers = new ArrayList<>();
+
+    /**
+     * Ensure the observer is the list. The observer cannot be null but it is okay if it
+     * is already in the list.
+     *
+     * @param observer The {@link} Watcher to be added to the notification list.
+     */
+    @Override
+    public void registerObserver(@NonNull Watcher observer) {
+        Objects.requireNonNull(observer, "observer may not be null");
+        synchronized (mObservers) {
+            if (!mObservers.contains(observer)) {
+                mObservers.add(observer);
+            }
+        }
+    }
+
+    /**
+     * Removes a previously registered observer. The observer must not be null and it
+     * must already have been registered.
+     *
+     * @param observer The {@link} Watcher to be removed from the notification list.
+     */
+    @Override
+    public void unregisterObserver(@NonNull Watcher observer) {
+        Objects.requireNonNull(observer, "observer may not be null");
+        synchronized (mObservers) {
+            mObservers.remove(observer);
+        }
+    }
+
+    /**
+     * Return the number of registered observers.
+     *
+     * @return The number of registered observers.
+     */
+    public int registeredObserverCount() {
+        return mObservers.size();
+    }
+
+    /**
+     * Invokes {@link Watcher#onChange} on each observer.
+     *
+     * @param what The {@link Watchable} that generated the event
+     */
+    @Override
+    public void dispatchChange(@Nullable Watchable what) {
+        synchronized (mObservers) {
+            final int end = mObservers.size();
+            for (int i = 0; i < end; i++) {
+                mObservers.get(i).onChange(what);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/utils/WatchedArrayMap.java b/services/core/java/com/android/server/utils/WatchedArrayMap.java
new file mode 100644
index 0000000..7b32980
--- /dev/null
+++ b/services/core/java/com/android/server/utils/WatchedArrayMap.java
@@ -0,0 +1,389 @@
+/*
+ * 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.
+ */
+
+package com.android.server.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * WatchedArrayMap is an {@link android.util.ArrayMap} that can report changes to itself.  If its
+ * values are {@link Watchable} then the WatchedArrayMap will also report changes to the values.
+ * A {@link Watchable} is notified only once, no matter how many times it is stored in the array.
+ */
+public class WatchedArrayMap<K, V> extends WatchableImpl implements Map<K, V> {
+
+    // The storage
+    private final ArrayMap<K, V> mStorage;
+
+    // If true, the array is watching its children
+    private boolean mWatching = false;
+
+    // The local observer
+    private final Watcher mObserver = new Watcher() {
+            @Override
+            public void onChange(@Nullable Watchable what) {
+                WatchedArrayMap.this.dispatchChange(what);
+            }
+        };
+
+    /**
+     * A convenience function called when the elements are added to or removed from the storage.
+     * The watchable is always {@link this}.
+     */
+    private void onChanged() {
+        dispatchChange(this);
+    }
+
+    /**
+     * A convenience function.  Register the object if it is {@link Watchable} and if the
+     * array is currently watching.  Note that the watching flag must be true if this
+     * function is to succeed.  Also note that if this is called with the same object
+     * twice, <this> is only registered once.
+     */
+    private void registerChild(Object o) {
+        if (mWatching && o instanceof Watchable) {
+            ((Watchable) o).registerObserver(mObserver);
+        }
+    }
+
+    /**
+     * A convenience function.  Unregister the object if it is {@link Watchable} and if the
+     * array is currently watching.  This unconditionally removes the object from the
+     * registered list.
+     */
+    private void unregisterChild(Object o) {
+        if (mWatching && o instanceof Watchable) {
+            ((Watchable) o).unregisterObserver(mObserver);
+        }
+    }
+
+    /**
+     * A convenience function.  Unregister the object if it is {@link Watchable}, if the
+     * array is currently watching, and if there are no other instances of this object in
+     * the storage.  Note that the watching flag must be true if this function is to
+     * succeed.  The object must already have been removed from the storage before this
+     * method is called.
+     */
+    private void unregisterChildIf(Object o) {
+        if (mWatching && o instanceof Watchable) {
+            if (!mStorage.containsValue(o)) {
+                ((Watchable) o).unregisterObserver(mObserver);
+            }
+        }
+    }
+
+    /**
+     * Register a {@link Watcher} with the array.  If this is the first Watcher than any
+     * array values that are {@link Watchable} are registered to the array itself.
+     */
+    @Override
+    public void registerObserver(@NonNull Watcher observer) {
+        super.registerObserver(observer);
+        if (registeredObserverCount() == 1) {
+            // The watching flag must be set true before any children are registered.
+            mWatching = true;
+            final int end = mStorage.size();
+            for (int i = 0; i < end; i++) {
+                registerChild(mStorage.valueAt(i));
+            }
+        }
+    }
+
+    /**
+     * Unregister a {@link Watcher} from the array.  If this is the last Watcher than any
+     * array values that are {@link Watchable} are unregistered to the array itself.
+     */
+    @Override
+    public void unregisterObserver(@NonNull Watcher observer) {
+        super.unregisterObserver(observer);
+        if (registeredObserverCount() == 0) {
+            final int end = mStorage.size();
+            for (int i = 0; i < end; i++) {
+                unregisterChild(mStorage.valueAt(i));
+            }
+            // The watching flag must be true while children are unregistered.
+            mWatching = false;
+        }
+    }
+
+    /**
+     * Create a new empty {@link WatchedArrayMap}.  The default capacity of an array map
+     * is 0, and will grow once items are added to it.
+     */
+    public WatchedArrayMap() {
+        this(0, false);
+    }
+
+    /**
+     * Create a new {@link WatchedArrayMap} with a given initial capacity.
+     */
+    public WatchedArrayMap(int capacity) {
+        this(capacity, false);
+    }
+
+    /** {@hide} */
+    public WatchedArrayMap(int capacity, boolean identityHashCode) {
+        mStorage = new ArrayMap<K, V>(capacity, identityHashCode);
+    }
+
+    /**
+     * Create a new {@link WatchedArrayMap} with the mappings from the given {@link Map}.
+     */
+    public WatchedArrayMap(@Nullable Map<? extends K, ? extends V> map) {
+        mStorage = new ArrayMap<K, V>();
+        if (map != null) {
+            putAll(map);
+        }
+    }
+
+    /**
+     * Return the underlying storage.  This breaks the wrapper but is necessary when
+     * passing the array to distant methods.
+     */
+    public ArrayMap untrackedMap() {
+        return mStorage;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        // The storage cannot be simply cleared.  Each element in the storage must be
+        // unregistered.  Deregistration is only needed if the array is actually
+        // watching.
+        if (mWatching) {
+            final int end = mStorage.size();
+            for (int i = 0; i < end; i++) {
+                unregisterChild(mStorage.valueAt(i));
+            }
+        }
+        mStorage.clear();
+        onChanged();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean containsKey(Object key) {
+        return mStorage.containsKey(key);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean containsValue(Object value) {
+        return mStorage.containsValue(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<Map.Entry<K, V>> entrySet() {
+        return Collections.unmodifiableSet(mStorage.entrySet());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof WatchedArrayMap) {
+            WatchedArrayMap w = (WatchedArrayMap) o;
+            return mStorage.equals(w.mStorage);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public V get(Object key) {
+        return mStorage.get(key);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        return mStorage.hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isEmpty() {
+        return mStorage.isEmpty();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<K> keySet() {
+        return Collections.unmodifiableSet(mStorage.keySet());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public V put(K key, V value) {
+        final V result = mStorage.put(key, value);
+        registerChild(value);
+        onChanged();
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void putAll(@NonNull Map<? extends K, ? extends V> map) {
+        for (Map.Entry<? extends K, ? extends V> element : map.entrySet()) {
+            put(element.getKey(), element.getValue());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public V remove(@NonNull Object key) {
+        final V result = mStorage.remove(key);
+        unregisterChildIf(result);
+        onChanged();
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int size() {
+        return mStorage.size();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Collection<V> values() {
+        return Collections.unmodifiableCollection(mStorage.values());
+    }
+
+    // Methods supported by ArrayMap that are not part of Map
+
+    /**
+     * Return the key at the given index in the array.
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, an
+     * {@link ArrayIndexOutOfBoundsException} is thrown.</p>
+     *
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @return Returns the key stored at the given index.
+     */
+    public K keyAt(int index) {
+        return mStorage.keyAt(index);
+    }
+
+    /**
+     * Return the value at the given index in the array.
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, an
+     * {@link ArrayIndexOutOfBoundsException} is thrown.</p>
+     *
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @return Returns the value stored at the given index.
+     */
+    public V valueAt(int index) {
+        return mStorage.valueAt(index);
+    }
+
+     /**
+     * Remove an existing key from the array map.
+     * @param key The key of the mapping to remove.
+     * @return Returns the value that was stored under the key, or null if there
+     * was no such key.
+     */
+    public int indexOfKey(K key) {
+        return mStorage.indexOfKey(key);
+    }
+
+    /**
+     * Returns an index for which {@link #valueAt} would return the
+     * specified value, or a negative number if no keys map to the
+     * specified value.
+     * Beware that this is a linear search, unlike lookups by key,
+     * and that multiple keys can map to the same value and this will
+     * find only one of them.
+     */
+    public int indexOfValue(V value) {
+        return mStorage.indexOfValue(value);
+    }
+
+    /**
+     * Set the value at a given index in the array.
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, an
+     * {@link ArrayIndexOutOfBoundsException} is thrown.</p>
+     *
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @param value The new value to store at this index.
+     * @return Returns the previous value at the given index.
+     */
+    public V setValueAt(int index, V value) {
+        final V result = mStorage.setValueAt(index, value);
+        if (value != result) {
+            unregisterChildIf(result);
+            registerChild(value);
+            onChanged();
+        }
+        return result;
+    }
+
+    /**
+     * Remove the key/value mapping at the given index.
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, an
+     * {@link ArrayIndexOutOfBoundsException} is thrown.</p>
+     *
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @return Returns the value that was stored at this index.
+     */
+    public V removeAt(int index) {
+        final V result = mStorage.removeAt(index);
+        unregisterChildIf(result);
+        onChanged();
+        return result;
+    }
+}
diff --git a/services/core/java/com/android/server/utils/WatchedSparseArray.java b/services/core/java/com/android/server/utils/WatchedSparseArray.java
new file mode 100644
index 0000000..4d43b68
--- /dev/null
+++ b/services/core/java/com/android/server/utils/WatchedSparseArray.java
@@ -0,0 +1,401 @@
+/*
+ * 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.
+ */
+
+package com.android.server.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+
+/**
+ * A watched variant of SparseArray.  If a {@link Watchable} is stored in the array, the
+ * array registers with the {@link Watchable}.  The array registers only once with each
+ * {@link Watchable} no matter how many times the {@link Watchable} is stored in the
+ * array.
+ */
+public class WatchedSparseArray<E> extends WatchableImpl {
+
+    // The storage
+    private final SparseArray<E> mStorage;
+
+    // If true, the array is watching its children
+    private boolean mWatching = false;
+
+    // The local observer
+    private final Watcher mObserver = new Watcher() {
+            @Override
+            public void onChange(@Nullable Watchable o) {
+                WatchedSparseArray.this.dispatchChange(o);
+            }
+        };
+
+    /**
+     * A private convenience function that notifies registered listeners that an element
+     * has been added to or removed from the array.  The what parameter is the array itself.
+     */
+    private void onChanged() {
+        dispatchChange(this);
+    }
+
+    /**
+     * A convenience function.  Register the object if it is {@link Watchable} and if the
+     * array is currently watching.  Note that the watching flag must be true if this
+     * function is to succeed.
+     */
+    private void registerChild(Object o) {
+        if (mWatching && o instanceof Watchable) {
+            ((Watchable) o).registerObserver(mObserver);
+        }
+    }
+
+    /**
+     * A convenience function.  Unregister the object if it is {@link Watchable} and if
+     * the array is currently watching.  Note that the watching flag must be true if this
+     * function is to succeed.
+     */
+    private void unregisterChild(Object o) {
+        if (mWatching && o instanceof Watchable) {
+            ((Watchable) o).unregisterObserver(mObserver);
+        }
+    }
+
+    /**
+     * A convenience function.  Unregister the object if it is {@link Watchable}, if the array is
+     * currently watching, and if the storage does not contain the object.  Note that the watching
+     * flag must be true if this function is to succeed.  This must be called after an object has
+     * been removed from the storage.
+     */
+    private void unregisterChildIf(Object o) {
+        if (mWatching && o instanceof Watchable) {
+            if (mStorage.indexOfValue((E) o) == -1) {
+                ((Watchable) o).unregisterObserver(mObserver);
+            }
+        }
+    }
+
+    /**
+     * Register a {@link Watcher} with the array.  If this is the first Watcher than any
+     * array values that are {@link Watchable} are registered to the array itself.
+     */
+    @Override
+    public void registerObserver(@NonNull Watcher observer) {
+        super.registerObserver(observer);
+        if (registeredObserverCount() == 1) {
+            // The watching flag must be set true before any children are registered.
+            mWatching = true;
+            final int end = mStorage.size();
+            for (int i = 0; i < end; i++) {
+                registerChild(mStorage.valueAt(i));
+            }
+        }
+    }
+
+    /**
+     * Unregister a {@link Watcher} from the array.  If this is the last Watcher than any
+     * array values that are {@link Watchable} are unregistered to the array itself.
+     */
+    @Override
+    public void unregisterObserver(@NonNull Watcher observer) {
+        super.unregisterObserver(observer);
+        if (registeredObserverCount() == 0) {
+            final int end = mStorage.size();
+            for (int i = 0; i < end; i++) {
+                unregisterChild(mStorage.valueAt(i));
+            }
+            // The watching flag must be true while children are unregistered.
+            mWatching = false;
+        }
+    }
+
+    /**
+     * Creates a new WatchedSparseArray containing no mappings.
+     */
+    public WatchedSparseArray() {
+        mStorage = new SparseArray();
+    }
+
+    /**
+     * Creates a new WatchedSparseArray containing no mappings that
+     * will not require any additional memory allocation to store the
+     * specified number of mappings.  If you supply an initial capacity of
+     * 0, the sparse array will be initialized with a light-weight
+     * representation not requiring any additional array allocations.
+     */
+    public WatchedSparseArray(int initialCapacity) {
+        mStorage = new SparseArray(initialCapacity);
+    }
+
+    /**
+     * The copy constructor does not copy the watcher data.
+     */
+    public WatchedSparseArray(@NonNull WatchedSparseArray<E> r) {
+        mStorage = r.mStorage.clone();
+    }
+
+    /**
+     * Returns true if the key exists in the array. This is equivalent to
+     * {@link #indexOfKey(int)} >= 0.
+     *
+     * @param key Potential key in the mapping
+     * @return true if the key is defined in the mapping
+     */
+    public boolean contains(int key) {
+        return mStorage.contains(key);
+    }
+
+    /**
+     * Gets the Object mapped from the specified key, or <code>null</code>
+     * if no such mapping has been made.
+     */
+    public E get(int key) {
+        return mStorage.get(key);
+    }
+
+    /**
+     * Gets the Object mapped from the specified key, or the specified Object
+     * if no such mapping has been made.
+     */
+    public E get(int key, E valueIfKeyNotFound) {
+        return mStorage.get(key, valueIfKeyNotFound);
+    }
+
+    /**
+     * Removes the mapping from the specified key, if there was any.
+     */
+    public void delete(int key) {
+        final E child = mStorage.get(key);
+        mStorage.delete(key);
+        unregisterChildIf(child);
+        onChanged();
+    }
+
+    /**
+     * @hide
+     * Removes the mapping from the specified key, if there was any, returning the old value.
+     */
+    public E removeReturnOld(int key) {
+        final E result = mStorage.removeReturnOld(key);
+        unregisterChildIf(result);
+        return result;
+    }
+
+    /**
+     * Alias for {@link #delete(int)}.
+     */
+    public void remove(int key) {
+        delete(key);
+    }
+
+    /**
+     * Removes the mapping at the specified index.
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, an
+     * {@link ArrayIndexOutOfBoundsException} is thrown.</p>
+     */
+    public void removeAt(int index) {
+        final E child = mStorage.valueAt(index);
+        mStorage.removeAt(index);
+        unregisterChildIf(child);
+        onChanged();
+    }
+
+    /**
+     * Remove a range of mappings as a batch.
+     *
+     * @param index Index to begin at
+     * @param size Number of mappings to remove
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>,
+     * the behavior is undefined.</p>
+     */
+    public void removeAtRange(int index, int size) {
+        final ArrayList<E> children = new ArrayList<>();
+        try {
+            for (int i = 0; i < size; i++) {
+                children.add(mStorage.valueAt(i + index));
+            }
+        } catch (Exception e) {
+            // Ignore any exception and proceed with removal.
+        }
+        try {
+            mStorage.removeAtRange(index, size);
+        } finally {
+            // Even on exception, make sure to deregister children that have been
+            // removed.
+            for (int i = 0; i < size; i++) {
+                unregisterChildIf(children.get(i));
+            }
+        }
+        onChanged();
+    }
+
+    /**
+     * Adds a mapping from the specified key to the specified value,
+     * replacing the previous mapping from the specified key if there
+     * was one.
+     */
+    public void put(int key, E value) {
+        final E old = mStorage.get(key);
+        mStorage.put(key, value);
+        unregisterChildIf(old);
+        registerChild(value);
+        onChanged();
+    }
+
+    /**
+     * Returns the number of key-value mappings that this SparseArray
+     * currently stores.
+     */
+    public int size() {
+        return mStorage.size();
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the key from the <code>index</code>th key-value mapping that this
+     * SparseArray stores.
+     *
+     * <p>The keys corresponding to indices in ascending order are guaranteed to
+     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
+     * smallest key and <code>keyAt(size()-1)</code> will return the largest
+     * key.</p>
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>,
+     * the behavior is undefined for apps targeting {@link android.os.Build.VERSION_CODES#P} and
+     * earlier, and an {@link ArrayIndexOutOfBoundsException} is thrown for apps targeting
+     * {@link android.os.Build.VERSION_CODES#Q} and later.</p>
+     */
+    public int keyAt(int index) {
+        return mStorage.keyAt(index);
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the value from the <code>index</code>th key-value mapping that this
+     * SparseArray stores.
+     *
+     * <p>The values corresponding to indices in ascending order are guaranteed
+     * to be associated with keys in ascending order, e.g.,
+     * <code>valueAt(0)</code> will return the value associated with the
+     * smallest key and <code>valueAt(size()-1)</code> will return the value
+     * associated with the largest key.</p>
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>,
+     * the behavior is undefined for apps targeting {@link android.os.Build.VERSION_CODES#P} and
+     * earlier, and an {@link ArrayIndexOutOfBoundsException} is thrown for apps targeting
+     * {@link android.os.Build.VERSION_CODES#Q} and later.</p>
+     */
+    public E valueAt(int index) {
+        return mStorage.valueAt(index);
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, sets a new
+     * value for the <code>index</code>th key-value mapping that this
+     * SparseArray stores.
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, the behavior is undefined for
+     * apps targeting {@link android.os.Build.VERSION_CODES#P} and earlier, and an
+     * {@link ArrayIndexOutOfBoundsException} is thrown for apps targeting
+     * {@link android.os.Build.VERSION_CODES#Q} and later.</p>
+     */
+    public void setValueAt(int index, E value) {
+        final E old = mStorage.valueAt(index);
+        mStorage.setValueAt(index, value);
+        if (value != old) {
+            unregisterChildIf(old);
+            registerChild(value);
+            onChanged();
+        }
+    }
+
+    /**
+     * Returns the index for which {@link #keyAt} would return the
+     * specified key, or a negative number if the specified
+     * key is not mapped.
+     */
+    public int indexOfKey(int key) {
+        return mStorage.indexOfKey(key);
+    }
+
+    /**
+     * Returns an index for which {@link #valueAt} would return the
+     * specified value, or a negative number if no keys map to the
+     * specified value.
+     * <p>Beware that this is a linear search, unlike lookups by key,
+     * and that multiple keys can map to the same value and this will
+     * find only one of them.
+     * <p>Note also that unlike most collections' {@code indexOf} methods,
+     * this method compares values using {@code ==} rather than {@code equals}.
+     */
+    public int indexOfValue(E value) {
+        return mStorage.indexOfValue(value);
+    }
+
+    /**
+     * Returns an index for which {@link #valueAt} would return the
+     * specified value, or a negative number if no keys map to the
+     * specified value.
+     * <p>Beware that this is a linear search, unlike lookups by key,
+     * and that multiple keys can map to the same value and this will
+     * find only one of them.
+     * <p>Note also that this method uses {@code equals} unlike {@code indexOfValue}.
+     * @hide
+     */
+    public int indexOfValueByValue(E value) {
+        return mStorage.indexOfValueByValue(value);
+    }
+
+    /**
+     * Removes all key-value mappings from this SparseArray.
+     */
+    public void clear() {
+        // The storage cannot be simply cleared.  Each element in the storage must be
+        // unregistered.  Deregistration is only needed if the array is actually
+        // watching.
+        if (mWatching) {
+            final int end = mStorage.size();
+            for (int i = 0; i < end; i++) {
+                unregisterChild(mStorage.valueAt(i));
+            }
+        }
+        mStorage.clear();
+        onChanged();
+    }
+
+    /**
+     * Puts a key/value pair into the array, optimizing for the case where
+     * the key is greater than all existing keys in the array.
+     */
+    public void append(int key, E value) {
+        mStorage.append(key, value);
+        registerChild(value);
+        onChanged();
+    }
+
+    /**
+     * <p>This implementation composes a string by iterating over its mappings. If
+     * this map contains itself as a value, the string "(this Map)"
+     * will appear in its place.
+     */
+    @Override
+    public String toString() {
+        return mStorage.toString();
+    }
+}
diff --git a/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java b/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java
new file mode 100644
index 0000000..edf7d27
--- /dev/null
+++ b/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java
@@ -0,0 +1,236 @@
+/*
+ * 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.
+ */
+
+package com.android.server.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import android.util.SparseBooleanArray;
+
+/**
+ * A watched variant of SparseBooleanArray.  Changes to the array are notified to
+ * registered {@link Watcher}s.
+ */
+public class WatchedSparseBooleanArray extends WatchableImpl {
+
+    // The storage
+    private final SparseBooleanArray mStorage;
+
+    // A private convenience function
+    private void dispatchChange() {
+        dispatchChange(this);
+    }
+
+    /**
+     * Creates a new WatchedSparseBooleanArray containing no mappings.
+     */
+    public WatchedSparseBooleanArray() {
+        mStorage = new SparseBooleanArray();
+    }
+
+    /**
+     * Creates a new WatchedSparseBooleanArray containing no mappings that
+     * will not require any additional memory allocation to store the
+     * specified number of mappings.  If you supply an initial capacity of
+     * 0, the sparse array will be initialized with a light-weight
+     * representation not requiring any additional array allocations.
+     */
+    public WatchedSparseBooleanArray(int initialCapacity) {
+        mStorage = new SparseBooleanArray(initialCapacity);
+    }
+
+    /**
+     * The copy constructor does not copy the watcher data.
+     */
+    public WatchedSparseBooleanArray(@NonNull WatchedSparseBooleanArray r) {
+        mStorage = r.mStorage.clone();
+    }
+
+    /**
+     * Gets the boolean mapped from the specified key, or <code>false</code>
+     * if no such mapping has been made.
+     */
+    public boolean get(int key) {
+        return mStorage.get(key);
+    }
+
+    /**
+     * Gets the boolean mapped from the specified key, or the specified value
+     * if no such mapping has been made.
+     */
+    public boolean get(int key, boolean valueIfKeyNotFound) {
+        return mStorage.get(key, valueIfKeyNotFound);
+    }
+
+    /**
+     * Removes the mapping from the specified key, if there was any.
+     */
+    public void delete(int key) {
+        mStorage.delete(key);
+        dispatchChange();
+    }
+
+    /**
+     * Removes the mapping at the specified index.
+     * <p>
+     * For indices outside of the range {@code 0...size()-1}, the behavior is undefined.
+     */
+    public void removeAt(int index) {
+        mStorage.removeAt(index);
+        dispatchChange();
+    }
+
+    /**
+     * Adds a mapping from the specified key to the specified value,
+     * replacing the previous mapping from the specified key if there
+     * was one.
+     */
+    public void put(int key, boolean value) {
+        if (mStorage.get(key) != value) {
+            mStorage.put(key, value);
+            dispatchChange();
+        }
+    }
+
+    /**
+     * Returns the number of key-value mappings that this SparseBooleanArray
+     * currently stores.
+     */
+    public int size() {
+        return mStorage.size();
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the key from the <code>index</code>th key-value mapping that this
+     * SparseBooleanArray stores.
+     *
+     * <p>The keys corresponding to indices in ascending order are guaranteed to
+     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
+     * smallest key and <code>keyAt(size()-1)</code> will return the largest
+     * key.</p>
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, the behavior is undefined for
+     * apps targeting {@link android.os.Build.VERSION_CODES#P} and earlier, and an
+     * {@link ArrayIndexOutOfBoundsException} is thrown for apps targeting
+     * {@link android.os.Build.VERSION_CODES#Q} and later.</p>
+     */
+    public int keyAt(int index) {
+        return mStorage.keyAt(index);
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the value from the <code>index</code>th key-value mapping that this
+     * SparseBooleanArray stores.
+     *
+     * <p>The values corresponding to indices in ascending order are guaranteed
+     * to be associated with keys in ascending order, e.g.,
+     * <code>valueAt(0)</code> will return the value associated with the
+     * smallest key and <code>valueAt(size()-1)</code> will return the value
+     * associated with the largest key.</p>
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, the behavior is undefined for
+     * apps targeting {@link android.os.Build.VERSION_CODES#P} and earlier, and an
+     * {@link ArrayIndexOutOfBoundsException} is thrown for apps targeting
+     * {@link android.os.Build.VERSION_CODES#Q} and later.</p>
+     */
+    public boolean valueAt(int index) {
+        return mStorage.valueAt(index);
+    }
+
+    /**
+     * Directly set the value at a particular index.
+     *
+     * <p>For indices outside of the range <code>0...size()-1</code>, the behavior is undefined for
+     * apps targeting {@link android.os.Build.VERSION_CODES#P} and earlier, and an
+     * {@link ArrayIndexOutOfBoundsException} is thrown for apps targeting
+     * {@link android.os.Build.VERSION_CODES#Q} and later.</p>
+     */
+    public void setValueAt(int index, boolean value) {
+        if (mStorage.valueAt(index) != value) {
+            mStorage.setValueAt(index, value);
+            dispatchChange();
+        }
+    }
+
+    /** @hide */
+    public void setKeyAt(int index, int key) {
+        if (mStorage.keyAt(index) != key) {
+            mStorage.setKeyAt(index, key);
+            dispatchChange();
+        }
+    }
+
+    /**
+     * Returns the index for which {@link #keyAt} would return the
+     * specified key, or a negative number if the specified
+     * key is not mapped.
+     */
+    public int indexOfKey(int key) {
+        return mStorage.indexOfKey(key);
+    }
+
+    /**
+     * Returns an index for which {@link #valueAt} would return the
+     * specified key, or a negative number if no keys map to the
+     * specified value.
+     * Beware that this is a linear search, unlike lookups by key,
+     * and that multiple keys can map to the same value and this will
+     * find only one of them.
+     */
+    public int indexOfValue(boolean value) {
+        return mStorage.indexOfValue(value);
+    }
+
+    /**
+     * Removes all key-value mappings from this SparseBooleanArray.
+     */
+    public void clear() {
+        mStorage.clear();
+        dispatchChange();
+    }
+
+    /**
+     * Puts a key/value pair into the array, optimizing for the case where
+     * the key is greater than all existing keys in the array.
+     */
+    public void append(int key, boolean value) {
+        mStorage.append(key, value);
+        dispatchChange();
+    }
+
+    @Override
+    public int hashCode() {
+        return mStorage.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        return this == that || mStorage.equals(that);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings.
+     */
+    @Override
+    public String toString() {
+        return mStorage.toString();
+    }
+}
diff --git a/services/core/java/com/android/server/utils/Watcher.java b/services/core/java/com/android/server/utils/Watcher.java
new file mode 100644
index 0000000..a9bfbfa
--- /dev/null
+++ b/services/core/java/com/android/server/utils/Watcher.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package com.android.server.utils;
+
+import android.annotation.Nullable;
+
+/**
+ * This class receives notifications when watched objects detect changes.
+ * Must be implemented by objects which are registered to a {@link Watchable}.
+ */
+public abstract class Watcher {
+
+    /**
+     * This method is called when {@link Watchable} detects a change.  The <what>
+     * parameter indicates what changed, but it may be null.  The parameter is intended
+     * for debugging.
+     *
+     * @param what The {@link Watchable} that changed.
+     */
+    public abstract void onChange(@Nullable Watchable what);
+}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 0a7f08b..bba645a7 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -194,7 +194,7 @@
 import static com.android.server.wm.Task.ActivityState.STARTED;
 import static com.android.server.wm.Task.ActivityState.STOPPED;
 import static com.android.server.wm.Task.ActivityState.STOPPING;
-import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE;
+import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE;
 import static com.android.server.wm.TaskPersister.DEBUG;
 import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
@@ -417,7 +417,7 @@
     // mOccludesParent field.
     final boolean hasWallpaper;
     // Input application handle used by the input dispatcher.
-    final InputApplicationHandle mInputApplicationHandle;
+    private InputApplicationHandle mInputApplicationHandle;
 
     final int launchedFromPid; // always the pid who started the activity.
     final int launchedFromUid; // always the uid who started the activity.
@@ -1506,7 +1506,6 @@
         info = aInfo;
         mUserId = UserHandle.getUserId(info.applicationInfo.uid);
         packageName = info.applicationInfo.packageName;
-        mInputApplicationHandle = new InputApplicationHandle(appToken);
         intent = _intent;
 
         // If the class name in the intent doesn't match that of the target, this is probably an
@@ -1693,6 +1692,21 @@
         return lockTaskLaunchMode;
     }
 
+    @NonNull InputApplicationHandle getInputApplicationHandle(boolean update) {
+        if (mInputApplicationHandle == null) {
+            mInputApplicationHandle = new InputApplicationHandle(appToken, toString(),
+                    mInputDispatchingTimeoutMillis);
+        } else if (update) {
+            final String name = toString();
+            if (mInputDispatchingTimeoutMillis != mInputApplicationHandle.dispatchingTimeoutMillis
+                    || !name.equals(mInputApplicationHandle.name)) {
+                mInputApplicationHandle = new InputApplicationHandle(appToken, name,
+                        mInputDispatchingTimeoutMillis);
+            }
+        }
+        return mInputApplicationHandle;
+    }
+
     @Override
     ActivityRecord asActivityRecord() {
         // I am an activity record!
@@ -4489,7 +4503,7 @@
             detachChildren();
         }
         if (app != null) {
-            app.invalidateOomScoreReferenceState(false /* computeNow */);
+            app.computeProcessActivityState();
         }
 
         switch (state) {
@@ -4881,7 +4895,7 @@
      */
     private boolean shouldBeResumed(ActivityRecord activeActivity) {
         return shouldMakeActive(activeActivity) && isFocusable()
-                && getTask().getVisibility(activeActivity) == STACK_VISIBILITY_VISIBLE
+                && getTask().getVisibility(activeActivity) == TASK_VISIBILITY_VISIBLE
                 && canResumeByCompat();
     }
 
@@ -6358,7 +6372,11 @@
         }
 
         final IBinder freezeToken = mayFreezeScreenLocked() ? appToken : null;
-        onDescendantOrientationChanged(freezeToken, this);
+        if (onDescendantOrientationChanged(freezeToken, this)) {
+            // The app is just becoming visible, and the parent Task has updated with the
+            // orientation request. Update the size compat mode.
+            updateSizeCompatMode();
+        }
     }
 
     /**
@@ -6524,6 +6542,13 @@
             return;
         }
 
+        if (task == null || (!handlesOrientationChangeFromDescendant()
+                && task.getLastTaskBoundsComputeActivity() != this)) {
+            // Don't compute when Task hasn't computed its bounds for this app, because the Task can
+            // be letterboxed, and its bounds may not be accurate until then.
+            return;
+        }
+
         Configuration overrideConfig = getRequestedOverrideConfiguration();
         final Configuration fullConfig = getConfiguration();
 
@@ -6548,20 +6573,14 @@
         mCompatDisplayInsets = new CompatDisplayInsets(mDisplayContent, this);
     }
 
-    void clearSizeCompatMode(boolean recomputeTask) {
+    @VisibleForTesting
+    void clearSizeCompatMode() {
         mSizeCompatScale = 1f;
         mSizeCompatBounds = null;
         mCompatDisplayInsets = null;
 
-        if (recomputeTask) {
-            // Recompute from Task because letterbox can also happen on Task level.
-            task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration());
-        }
-    }
-
-    @VisibleForTesting
-    void clearSizeCompatMode() {
-        clearSizeCompatMode(true /* recomputeTask */);
+        // Recompute from Task because letterbox can also happen on Task level.
+        task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index a068d2b..17209eb 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -50,12 +50,12 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IDLE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
@@ -63,17 +63,17 @@
 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
 import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISOR_STACK_MSG;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
-import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
-import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_ALLOWLISTED;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
+import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
+import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE;
 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.Task.ActivityState.PAUSED;
 import static com.android.server.wm.Task.ActivityState.PAUSING;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_ALLOWLISTED;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
-import static com.android.server.wm.Task.REPARENT_KEEP_STACK_AT_FRONT;
+import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT;
 import static com.android.server.wm.Task.TAG_CLEANUP;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -158,7 +158,7 @@
     private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
     private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
-    private static final String TAG_STACK = TAG + POSTFIX_STACK;
+    private static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK;
     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
     static final String TAG_TASKS = TAG + POSTFIX_TASKS;
 
@@ -526,7 +526,7 @@
         int candidateTaskId = nextTaskIdForUser(currentTaskId, userId);
         while (mRecentTasks.containsTaskId(candidateTaskId, userId)
                 || mRootWindowContainer.anyTaskForId(
-                        candidateTaskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) != null) {
+                        candidateTaskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS) != null) {
             candidateTaskId = nextTaskIdForUser(candidateTaskId, userId);
             if (candidateTaskId == currentTaskId) {
                 // Something wrong!
@@ -1360,8 +1360,8 @@
 
             if (stack != currentStack) {
                 moveHomeStackToFrontIfNeeded(flags, stack.getDisplayArea(), reason);
-                task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, DEFER_RESUME,
-                        reason);
+                task.reparent(stack, ON_TOP, REPARENT_KEEP_ROOT_TASK_AT_FRONT, !ANIMATE,
+                        DEFER_RESUME, reason);
                 currentStack = stack;
                 reparented = true;
                 // task.reparent() should already placed the task on top,
@@ -1385,7 +1385,7 @@
         currentStack.moveTaskToFront(task, false /* noAnimation */, options,
                 r == null ? null : r.appTimeTracker, reason);
 
-        if (DEBUG_STACK) Slog.d(TAG_STACK,
+        if (DEBUG_ROOT_TASK) Slog.d(TAG_ROOT_TASK,
                 "findTaskToMoveToFront: moved to front of stack=" + currentStack);
 
         handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
@@ -1502,7 +1502,7 @@
     boolean removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents,
             String reason) {
         final Task task =
-                mRootWindowContainer.anyTaskForId(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                mRootWindowContainer.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
         if (task != null) {
             removeTask(task, killProcess, removeFromRecents, reason);
             return true;
@@ -2478,7 +2478,7 @@
         mService.deferWindowLayout();
         try {
             task = mRootWindowContainer.anyTaskForId(taskId,
-                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, activityOptions, ON_TOP);
+                    MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, activityOptions, ON_TOP);
             if (task == null) {
                 mWindowManager.executeAppTransition();
                 throw new IllegalArgumentException(
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 910a1a2..33819a9 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -75,7 +75,7 @@
 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
 import static com.android.server.wm.Task.ActivityState.RESUMED;
-import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
+import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 import android.annotation.NonNull;
@@ -1665,11 +1665,6 @@
             final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                     ? mSourceRecord.getTask() : null;
             setNewTask(taskToAffiliate);
-            if (mService.getLockTaskController().isLockTaskModeViolation(
-                    mStartActivity.getTask())) {
-                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
-                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
-            }
         } else if (mAddingToTask) {
             addOrReparentStartingActivity(targetTask, "adding to task");
         }
@@ -1848,10 +1843,17 @@
         final boolean isNewClearTask =
                 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                         == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
-        if (!newTask && mService.getLockTaskController().isLockTaskModeViolation(targetTask,
-                isNewClearTask)) {
-            Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
-            return START_RETURN_LOCK_TASK_MODE_VIOLATION;
+        if (!newTask) {
+            if (mService.getLockTaskController().isLockTaskModeViolation(targetTask,
+                    isNewClearTask)) {
+                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
+                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
+            }
+        } else {
+            if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(mStartActivity)) {
+                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
+                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
+            }
         }
 
         return START_SUCCESS;
@@ -2530,8 +2532,8 @@
                             "bringingFoundTaskToFront");
                     mMovedToFront = !isSplitScreenTopStack;
                 } else {
-                    intentTask.reparent(launchStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE,
-                            DEFER_RESUME, "reparentToTargetStack");
+                    intentTask.reparent(launchStack, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT,
+                            ANIMATE, DEFER_RESUME, "reparentToTargetStack");
                     mMovedToFront = true;
                 }
                 mOptions = null;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
index b5675a9..33d1b44 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java
@@ -45,7 +45,7 @@
 
     static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
     static final boolean DEBUG_RECENTS_TRIM_TASKS = DEBUG_RECENTS || false;
-    static final boolean DEBUG_STACK = DEBUG_ALL || false;
+    static final boolean DEBUG_ROOT_TASK = DEBUG_ALL || false;
     public static final boolean DEBUG_SWITCH = DEBUG_ALL || false;
     static final boolean DEBUG_TRANSITION = DEBUG_ALL || false;
     static final boolean DEBUG_VISIBILITY = DEBUG_ALL || false;
@@ -73,7 +73,7 @@
     static final String POSTFIX_PAUSE = APPEND_CATEGORY_NAME ? "_Pause" : "";
     static final String POSTFIX_RECENTS = APPEND_CATEGORY_NAME ? "_Recents" : "";
     static final String POSTFIX_SAVED_STATE = APPEND_CATEGORY_NAME ? "_SavedState" : "";
-    static final String POSTFIX_STACK = APPEND_CATEGORY_NAME ? "_Stack" : "";
+    static final String POSTFIX_ROOT_TASK = APPEND_CATEGORY_NAME ? "_RootTask" : "";
     static final String POSTFIX_STATES = APPEND_CATEGORY_NAME ? "_States" : "";
     public static final String POSTFIX_SWITCH = APPEND_CATEGORY_NAME ? "_Switch" : "";
     static final String POSTFIX_TASKS = APPEND_CATEGORY_NAME ? "_Tasks" : "";
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index eb86d37..f649a2f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -533,9 +533,6 @@
     /** Flush recent tasks to disk. */
     public abstract void flushRecentTasks();
 
-    public abstract WindowProcessController getHomeProcess();
-    public abstract WindowProcessController getPreviousProcess();
-
     public abstract void clearLockedTasks(String reason);
     public abstract void updateUserConfiguration();
     public abstract boolean canShowErrorDialogs();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 608d373..73c4713 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -106,7 +106,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
@@ -117,14 +117,14 @@
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
 import static com.android.server.wm.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
 import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_DONT_LOCK;
 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
-import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_ONLY;
-import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_ONLY;
+import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
 import static com.android.server.wm.Task.ActivityState.DESTROYED;
 import static com.android.server.wm.Task.ActivityState.DESTROYING;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_DONT_LOCK;
-import static com.android.server.wm.Task.REPARENT_KEEP_STACK_AT_FRONT;
+import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
@@ -306,7 +306,7 @@
  */
 public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
-    static final String TAG_STACK = TAG + POSTFIX_STACK;
+    static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK;
     static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
@@ -2228,7 +2228,7 @@
         try {
             synchronized (mGlobalLock) {
                 final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_ONLY);
+                        MATCH_ATTACHED_TASK_ONLY);
                 if (task == null) {
                     return;
                 }
@@ -2266,7 +2266,7 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                        MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
                 if (task == null) {
                     Slog.w(TAG, "removeTask: No task remove with id=" + taskId);
                     return false;
@@ -2374,7 +2374,7 @@
         try {
             synchronized (mGlobalLock) {
                 final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                        MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
                 if (task == null) {
                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
                     return rect;
@@ -2397,7 +2397,7 @@
             enforceCallerIsRecentsOrHasPermission(
                     MANAGE_ACTIVITY_TASKS, "getTaskDescription()");
             final Task tr = mRootWindowContainer.anyTaskForId(id,
-                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                    MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
             if (tr != null) {
                 return tr.getTaskDescription();
             }
@@ -2418,7 +2418,7 @@
                     return setTaskWindowingModeSplitScreen(taskId, windowingMode, toTop);
                 }
                 final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_ONLY);
+                        MATCH_ATTACHED_TASK_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
                     return false;
@@ -2789,8 +2789,8 @@
                     throw new IllegalArgumentException("moveTaskToRootTask: Attempt to move task "
                             + taskId + " to rootTask " + rootTaskId);
                 }
-                task.reparent(rootTask, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
-                        "moveTaskToRootTask");
+                task.reparent(rootTask, toTop, REPARENT_KEEP_ROOT_TASK_AT_FRONT, ANIMATE,
+                        !DEFER_RESUME, "moveTaskToRootTask");
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2834,7 +2834,7 @@
         }
 
         final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                MATCH_TASK_IN_STACKS_ONLY);
+                MATCH_ATTACHED_TASK_ONLY);
         if (task == null) {
             Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
             return false;
@@ -3013,7 +3013,7 @@
         try {
             synchronized (mGlobalLock) {
                 final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_ONLY);
+                        MATCH_ATTACHED_TASK_ONLY);
                 if (task == null) {
                     return;
                 }
@@ -3361,7 +3361,7 @@
     public void setTaskResizeable(int taskId, int resizeableMode) {
         synchronized (mGlobalLock) {
             final Task task = mRootWindowContainer.anyTaskForId(
-                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                    taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
             if (task == null) {
                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
                 return;
@@ -3377,7 +3377,7 @@
         try {
             synchronized (mGlobalLock) {
                 final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_ONLY);
+                        MATCH_ATTACHED_TASK_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
                     return false;
@@ -4395,7 +4395,7 @@
         try {
             synchronized (mGlobalLock) {
                 final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_ONLY);
+                        MATCH_ATTACHED_TASK_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
                     return;
@@ -4423,7 +4423,7 @@
         final Task task;
         synchronized (mGlobalLock) {
             task = mRootWindowContainer.anyTaskForId(taskId,
-                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                    MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
             if (task == null) {
                 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
                 return null;
@@ -7324,20 +7324,6 @@
         }
 
         @Override
-        public WindowProcessController getHomeProcess() {
-            synchronized (mGlobalLock) {
-                return mHomeProcess;
-            }
-        }
-
-        @Override
-        public WindowProcessController getPreviousProcess() {
-            synchronized (mGlobalLock) {
-                return mPreviousProcess;
-            }
-        }
-
-        @Override
         public void clearLockedTasks(String reason) {
             synchronized (mGlobalLock) {
                 getLockTaskController().clearLockedTasks(reason);
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 3e79879..fbbda59 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -17,7 +17,7 @@
 package com.android.server.wm;
 
 import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
-import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
 
 import android.app.ActivityManager;
 import android.app.IAppTask;
@@ -79,7 +79,7 @@
             final long origId = Binder.clearCallingIdentity();
             try {
                 Task task = mService.mRootWindowContainer.anyTaskForId(mTaskId,
-                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                        MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
                 if (task == null) {
                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
                 }
@@ -136,7 +136,7 @@
         IApplicationThread appThread;
         synchronized (mService.mGlobalLock) {
             task = mService.mRootWindowContainer.anyTaskForId(mTaskId,
-                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                    MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
             if (task == null) {
                 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
             }
@@ -165,7 +165,7 @@
             final long origId = Binder.clearCallingIdentity();
             try {
                 Task task = mService.mRootWindowContainer.anyTaskForId(mTaskId,
-                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+                        MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
                 if (task == null) {
                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
                 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6453ddf..3a4eb09 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -88,7 +88,6 @@
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
 import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
 import static com.android.server.wm.DisplayContentProto.CAN_SHOW_IME;
 import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
@@ -238,7 +237,6 @@
  */
 class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
-    private static final String TAG_STACK = TAG + POSTFIX_STACK;
 
     /** The default scaling mode that scales content automatically. */
     static final int FORCE_SCALING_MODE_AUTO = 0;
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index f647bea..472678c 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -22,184 +22,41 @@
 
 import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_AUTO;
 import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_DISABLED;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
-import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.WindowConfiguration;
-import android.os.Environment;
-import android.os.FileUtils;
 import android.provider.Settings;
-import android.util.AtomicFile;
-import android.util.Slog;
-import android.util.Xml;
 import android.view.Display;
-import android.view.DisplayAddress;
 import android.view.DisplayInfo;
 import android.view.IWindowManager;
 import android.view.Surface;
 
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.XmlUtils;
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.wm.DisplayContent.ForceScalingMode;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
+import java.util.Objects;
 
 /**
- * Current persistent settings about a display
+ * Current persistent settings about a display. Provides policies for display settings and
+ * delegates the persistence and lookup of settings values to the supplied {@link SettingsProvider}.
  */
 class DisplayWindowSettings {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayWindowSettings" : TAG_WM;
-
-    private static final String SYSTEM_DIRECTORY = "system";
-    private static final String DISPLAY_SETTINGS_FILE_NAME = "display_settings.xml";
-    private static final String VENDOR_DISPLAY_SETTINGS_PATH = "etc/" + DISPLAY_SETTINGS_FILE_NAME;
-    private static final String WM_DISPLAY_COMMIT_TAG = "wm-displays";
-
-    private static final int IDENTIFIER_UNIQUE_ID = 0;
-    private static final int IDENTIFIER_PORT = 1;
-    @IntDef(prefix = { "IDENTIFIER_" }, value = {
-            IDENTIFIER_UNIQUE_ID,
-            IDENTIFIER_PORT,
-    })
-    @interface DisplayIdentifierType {}
-
     private final WindowManagerService mService;
-    private final HashMap<String, Entry> mEntries = new HashMap<>();
-    private final SettingPersister mStorage;
+    private final SettingsProvider mSettingsProvider;
 
-    /**
-     * The preferred type of a display identifier to use when storing and retrieving entries.
-     * {@link #getIdentifier(DisplayInfo)} must be used to get current preferred identifier for each
-     * display. It will fall back to using {@link #IDENTIFIER_UNIQUE_ID} if the currently selected
-     * one is not applicable to a particular display.
-     */
-    @DisplayIdentifierType
-    private int mIdentifier = IDENTIFIER_UNIQUE_ID;
-
-    /** Interface for persisting the display window settings. */
-    interface SettingPersister {
-        InputStream openRead() throws IOException;
-        OutputStream startWrite() throws IOException;
-        void finishWrite(OutputStream os, boolean success);
-    }
-
-    private static class Entry {
-        private final String mName;
-        private int mWindowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-        private int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
-        private int mUserRotation = Surface.ROTATION_0;
-        private int mForcedWidth;
-        private int mForcedHeight;
-        private int mForcedDensity;
-        private int mForcedScalingMode = FORCE_SCALING_MODE_AUTO;
-        private int mRemoveContentMode = REMOVE_CONTENT_MODE_UNDEFINED;
-        private boolean mShouldShowWithInsecureKeyguard = false;
-        private boolean mShouldShowSystemDecors = false;
-        private boolean mShouldShowIme = false;
-        private int mFixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
-        private boolean mIgnoreOrientationRequest = false;
-
-        private Entry(String name) {
-            mName = name;
-        }
-
-        private Entry(String name, Entry copyFrom) {
-            this(name);
-            mWindowingMode = copyFrom.mWindowingMode;
-            mUserRotationMode = copyFrom.mUserRotationMode;
-            mUserRotation = copyFrom.mUserRotation;
-            mForcedWidth = copyFrom.mForcedWidth;
-            mForcedHeight = copyFrom.mForcedHeight;
-            mForcedDensity = copyFrom.mForcedDensity;
-            mForcedScalingMode = copyFrom.mForcedScalingMode;
-            mRemoveContentMode = copyFrom.mRemoveContentMode;
-            mShouldShowWithInsecureKeyguard = copyFrom.mShouldShowWithInsecureKeyguard;
-            mShouldShowSystemDecors = copyFrom.mShouldShowSystemDecors;
-            mShouldShowIme = copyFrom.mShouldShowIme;
-            mFixedToUserRotation = copyFrom.mFixedToUserRotation;
-            mIgnoreOrientationRequest = copyFrom.mIgnoreOrientationRequest;
-        }
-
-        /** @return {@code true} if all values are default. */
-        private boolean isEmpty() {
-            return mWindowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED
-                    && mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
-                    && mUserRotation == Surface.ROTATION_0
-                    && mForcedWidth == 0 && mForcedHeight == 0 && mForcedDensity == 0
-                    && mForcedScalingMode == FORCE_SCALING_MODE_AUTO
-                    && mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED
-                    && !mShouldShowWithInsecureKeyguard
-                    && !mShouldShowSystemDecors
-                    && !mShouldShowIme
-                    && mFixedToUserRotation == IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT
-                    && !mIgnoreOrientationRequest;
-        }
-    }
-
-    DisplayWindowSettings(WindowManagerService service) {
-        this(service, new AtomicFileStorage());
-    }
-
-    @VisibleForTesting
-    DisplayWindowSettings(WindowManagerService service, SettingPersister storageImpl) {
+    DisplayWindowSettings(WindowManagerService service, SettingsProvider settingsProvider) {
         mService = service;
-        mStorage = storageImpl;
-        readSettings();
-    }
-
-    private @Nullable Entry getEntry(DisplayInfo displayInfo) {
-        final String identifier = getIdentifier(displayInfo);
-        Entry entry;
-        // Try to get corresponding entry using preferred identifier for the current config.
-        if ((entry = mEntries.get(identifier)) != null) {
-            return entry;
-        }
-        // Else, fall back to the display name.
-        if ((entry = mEntries.get(displayInfo.name)) != null) {
-            // Found an entry stored with old identifier - upgrade to the new type now.
-            return updateIdentifierForEntry(entry, displayInfo);
-        }
-        return null;
-    }
-
-    private Entry getOrCreateEntry(DisplayInfo displayInfo) {
-        final Entry entry = getEntry(displayInfo);
-        return entry != null ? entry : new Entry(getIdentifier(displayInfo));
-    }
-
-    /**
-     * Upgrades the identifier of a legacy entry. Does it by copying the data from the old record
-     * and clearing the old key in memory. The entry will be written to storage next time when a
-     * setting changes.
-     */
-    private Entry updateIdentifierForEntry(Entry entry, DisplayInfo displayInfo) {
-        final Entry newEntry = new Entry(getIdentifier(displayInfo), entry);
-        removeEntry(displayInfo);
-        mEntries.put(newEntry.mName, newEntry);
-        return newEntry;
+        mSettingsProvider = settingsProvider;
     }
 
     void setUserRotation(DisplayContent displayContent, int rotationMode, int rotation) {
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mUserRotationMode = rotationMode;
-        entry.mUserRotation = rotation;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mUserRotationMode = rotationMode;
+        overrideSettings.mUserRotation = rotation;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     void setForcedSize(DisplayContent displayContent, int width, int height) {
@@ -207,14 +64,14 @@
             final String sizeString = (width == 0 || height == 0) ? "" : (width + "," + height);
             Settings.Global.putString(mService.mContext.getContentResolver(),
                     Settings.Global.DISPLAY_SIZE_FORCED, sizeString);
-            return;
         }
 
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mForcedWidth = width;
-        entry.mForcedHeight = height;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mForcedWidth = width;
+        overrideSettings.mForcedHeight = height;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     void setForcedDensity(DisplayContent displayContent, int density, int userId) {
@@ -222,47 +79,47 @@
             final String densityString = density == 0 ? "" : Integer.toString(density);
             Settings.Secure.putStringForUser(mService.mContext.getContentResolver(),
                     Settings.Secure.DISPLAY_DENSITY_FORCED, densityString, userId);
-            return;
         }
 
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mForcedDensity = density;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mForcedDensity = density;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     void setForcedScalingMode(DisplayContent displayContent, @ForceScalingMode int mode) {
         if (displayContent.isDefaultDisplay) {
             Settings.Global.putInt(mService.mContext.getContentResolver(),
                     Settings.Global.DISPLAY_SCALING_FORCE, mode);
-            return;
         }
 
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mForcedScalingMode = mode;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mForcedScalingMode = mode;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     void setFixedToUserRotation(DisplayContent displayContent, int fixedToUserRotation) {
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mFixedToUserRotation = fixedToUserRotation;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mFixedToUserRotation = fixedToUserRotation;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     void setIgnoreOrientationRequest(
             DisplayContent displayContent, boolean ignoreOrientationRequest) {
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        if (entry.mIgnoreOrientationRequest == ignoreOrientationRequest) return;
-        entry.mIgnoreOrientationRequest = ignoreOrientationRequest;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mIgnoreOrientationRequest = ignoreOrientationRequest;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
-    private int getWindowingModeLocked(Entry entry, DisplayContent dc) {
-        int windowingMode = entry != null ? entry.mWindowingMode
-                : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+    private int getWindowingModeLocked(SettingsProvider.SettingsEntry settings, DisplayContent dc) {
+        int windowingMode = settings.mWindowingMode;
         // This display used to be in freeform, but we don't support freeform anymore, so fall
         // back to fullscreen.
         if (windowingMode == WindowConfiguration.WINDOWING_MODE_FREEFORM
@@ -281,22 +138,23 @@
 
     int getWindowingModeLocked(DisplayContent dc) {
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getEntry(displayInfo);
-        return getWindowingModeLocked(entry, dc);
+        final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
+        return getWindowingModeLocked(settings, dc);
     }
 
     void setWindowingModeLocked(DisplayContent dc, int mode) {
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mWindowingMode = mode;
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mWindowingMode = mode;
         dc.setWindowingMode(mode);
-        writeSettingsIfNeeded(entry, displayInfo);
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     int getRemoveContentModeLocked(DisplayContent dc) {
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getEntry(displayInfo);
-        if (entry == null || entry.mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED) {
+        final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
+        if (settings.mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED) {
             if (dc.isPrivate()) {
                 // For private displays by default content is destroyed on removal.
                 return REMOVE_CONTENT_MODE_DESTROY;
@@ -304,111 +162,110 @@
             // For other displays by default content is moved to primary on removal.
             return REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
         }
-        return entry.mRemoveContentMode;
+        return settings.mRemoveContentMode;
     }
 
     void setRemoveContentModeLocked(DisplayContent dc, int mode) {
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mRemoveContentMode = mode;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mRemoveContentMode = mode;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     boolean shouldShowWithInsecureKeyguardLocked(DisplayContent dc) {
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getEntry(displayInfo);
-        if (entry == null) {
-            return false;
-        }
-        return entry.mShouldShowWithInsecureKeyguard;
+        final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
+        return settings.mShouldShowWithInsecureKeyguard != null
+                ? settings.mShouldShowWithInsecureKeyguard : false;
     }
 
     void setShouldShowWithInsecureKeyguardLocked(DisplayContent dc, boolean shouldShow) {
         if (!dc.isPrivate() && shouldShow) {
-            Slog.e(TAG, "Public display can't be allowed to show content when locked");
-            return;
+            throw new IllegalArgumentException("Public display can't be allowed to show content"
+                    + " when locked");
         }
 
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mShouldShowWithInsecureKeyguard = shouldShow;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mShouldShowWithInsecureKeyguard = shouldShow;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     boolean shouldShowSystemDecorsLocked(DisplayContent dc) {
         if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
-            // For default display should show system decors.
+            // Default display should show system decors.
             return true;
         }
 
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getEntry(displayInfo);
-        if (entry == null) {
-            return false;
-        }
-        return entry.mShouldShowSystemDecors;
+        final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
+        return settings.mShouldShowSystemDecors != null ? settings.mShouldShowSystemDecors : false;
     }
 
     void setShouldShowSystemDecorsLocked(DisplayContent dc, boolean shouldShow) {
-        if (dc.getDisplayId() == Display.DEFAULT_DISPLAY && !shouldShow) {
-            Slog.e(TAG, "Default display should show system decors");
-            return;
-        }
-
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mShouldShowSystemDecors = shouldShow;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mShouldShowSystemDecors = shouldShow;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     boolean shouldShowImeLocked(DisplayContent dc) {
         if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
-            // For default display should shows IME.
+            // Default display should show IME.
             return true;
         }
 
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getEntry(displayInfo);
-        if (entry == null) {
-            return false;
-        }
-        return entry.mShouldShowIme;
+        final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
+        return settings.mShouldShowIme != null ? settings.mShouldShowIme : false;
     }
 
     void setShouldShowImeLocked(DisplayContent dc, boolean shouldShow) {
-        if (dc.getDisplayId() == Display.DEFAULT_DISPLAY && !shouldShow) {
-            Slog.e(TAG, "Default display should show IME");
-            return;
-        }
-
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
-        entry.mShouldShowIme = shouldShow;
-        writeSettingsIfNeeded(entry, displayInfo);
+        final SettingsProvider.SettingsEntry overrideSettings =
+                mSettingsProvider.getOverrideSettings(displayInfo);
+        overrideSettings.mShouldShowIme = shouldShow;
+        mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
     }
 
     void applySettingsToDisplayLocked(DisplayContent dc) {
         final DisplayInfo displayInfo = dc.getDisplayInfo();
-        final Entry entry = getOrCreateEntry(displayInfo);
+        final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
 
         // Setting windowing mode first, because it may override overscan values later.
-        dc.setWindowingMode(getWindowingModeLocked(entry, dc));
+        final int windowingMode = getWindowingModeLocked(settings, dc);
+        dc.setWindowingMode(windowingMode);
 
-        dc.getDisplayRotation().restoreSettings(entry.mUserRotationMode,
-                entry.mUserRotation, entry.mFixedToUserRotation);
+        final int userRotationMode = settings.mUserRotationMode != null
+                ? settings.mUserRotationMode : WindowManagerPolicy.USER_ROTATION_FREE;
+        final int userRotation = settings.mUserRotation != null
+                ? settings.mUserRotation : Surface.ROTATION_0;
+        final int mFixedToUserRotation = settings.mFixedToUserRotation != null
+                ? settings.mFixedToUserRotation : IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
+        dc.getDisplayRotation().restoreSettings(userRotationMode, userRotation,
+                mFixedToUserRotation);
 
-        final boolean hasDensityOverride = entry.mForcedDensity != 0;
-        final boolean hasSizeOverride = entry.mForcedWidth != 0 && entry.mForcedHeight != 0;
+        final boolean hasDensityOverride = settings.mForcedDensity != 0;
+        final boolean hasSizeOverride = settings.mForcedWidth != 0 && settings.mForcedHeight != 0;
         dc.mIsDensityForced = hasDensityOverride;
         dc.mIsSizeForced = hasSizeOverride;
-        dc.setIgnoreOrientationRequest(entry.mIgnoreOrientationRequest);
 
-        final int width = hasSizeOverride ? entry.mForcedWidth : dc.mBaseDisplayWidth;
-        final int height = hasSizeOverride ? entry.mForcedHeight : dc.mBaseDisplayHeight;
-        final int density = hasDensityOverride ? entry.mForcedDensity : dc.mBaseDisplayDensity;
+        final boolean ignoreOrientationRequest = settings.mIgnoreOrientationRequest != null
+                ? settings.mIgnoreOrientationRequest : false;
+        dc.setIgnoreOrientationRequest(ignoreOrientationRequest);
+
+        final int width = hasSizeOverride ? settings.mForcedWidth : dc.mInitialDisplayWidth;
+        final int height = hasSizeOverride ? settings.mForcedHeight : dc.mInitialDisplayHeight;
+        final int density = hasDensityOverride ? settings.mForcedDensity
+                : dc.mInitialDisplayDensity;
         dc.updateBaseDisplayMetrics(width, height, density);
 
-        dc.mDisplayScalingDisabled = entry.mForcedScalingMode == FORCE_SCALING_MODE_DISABLED;
+        final int forcedScalingMode = settings.mForcedScalingMode != null
+                ? settings.mForcedScalingMode : FORCE_SCALING_MODE_AUTO;
+        dc.mDisplayScalingDisabled = forcedScalingMode == FORCE_SCALING_MODE_DISABLED;
     }
 
     /**
@@ -429,291 +286,281 @@
         return false;
     }
 
-    private void readSettings() {
-        InputStream stream;
-        try {
-            stream = mStorage.openRead();
-        } catch (IOException e) {
-            Slog.i(TAG, "No existing display settings, starting empty");
-            return;
-        }
-        boolean success = false;
-        try {
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(stream, StandardCharsets.UTF_8.name());
-            int type;
-            while ((type = parser.next()) != XmlPullParser.START_TAG
-                    && type != XmlPullParser.END_DOCUMENT) {
-                // Do nothing.
-            }
-
-            if (type != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("no start tag found");
-            }
-
-            int outerDepth = parser.getDepth();
-            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
-                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                    continue;
-                }
-
-                String tagName = parser.getName();
-                if (tagName.equals("display")) {
-                    readDisplay(parser);
-                } else if (tagName.equals("config")) {
-                    readConfig(parser);
-                } else {
-                    Slog.w(TAG, "Unknown element under <display-settings>: "
-                            + parser.getName());
-                    XmlUtils.skipCurrentTag(parser);
-                }
-            }
-            success = true;
-        } catch (IllegalStateException e) {
-            Slog.w(TAG, "Failed parsing " + e);
-        } catch (NullPointerException e) {
-            Slog.w(TAG, "Failed parsing " + e);
-        } catch (NumberFormatException e) {
-            Slog.w(TAG, "Failed parsing " + e);
-        } catch (XmlPullParserException e) {
-            Slog.w(TAG, "Failed parsing " + e);
-        } catch (IOException e) {
-            Slog.w(TAG, "Failed parsing " + e);
-        } catch (IndexOutOfBoundsException e) {
-            Slog.w(TAG, "Failed parsing " + e);
-        } finally {
-            if (!success) {
-                mEntries.clear();
-            }
-            try {
-                stream.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    private int getIntAttribute(XmlPullParser parser, String name) {
-        return getIntAttribute(parser, name, 0 /* defaultValue */);
-    }
-
-    private int getIntAttribute(XmlPullParser parser, String name, int defaultValue) {
-        try {
-            final String str = parser.getAttributeValue(null, name);
-            return str != null ? Integer.parseInt(str) : defaultValue;
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    private boolean getBooleanAttribute(XmlPullParser parser, String name) {
-        return getBooleanAttribute(parser, name, false /* defaultValue */);
-    }
-
-    private boolean getBooleanAttribute(XmlPullParser parser, String name, boolean defaultValue) {
-        try {
-            final String str = parser.getAttributeValue(null, name);
-            return str != null ? Boolean.parseBoolean(str) : defaultValue;
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    private void readDisplay(XmlPullParser parser) throws NumberFormatException,
-            XmlPullParserException, IOException {
-        String name = parser.getAttributeValue(null, "name");
-        if (name != null) {
-            Entry entry = new Entry(name);
-            entry.mWindowingMode = getIntAttribute(parser, "windowingMode",
-                    WindowConfiguration.WINDOWING_MODE_UNDEFINED);
-            entry.mUserRotationMode = getIntAttribute(parser, "userRotationMode",
-                    WindowManagerPolicy.USER_ROTATION_FREE);
-            entry.mUserRotation = getIntAttribute(parser, "userRotation",
-                    Surface.ROTATION_0);
-            entry.mForcedWidth = getIntAttribute(parser, "forcedWidth");
-            entry.mForcedHeight = getIntAttribute(parser, "forcedHeight");
-            entry.mForcedDensity = getIntAttribute(parser, "forcedDensity");
-            entry.mForcedScalingMode = getIntAttribute(parser, "forcedScalingMode",
-                    FORCE_SCALING_MODE_AUTO);
-            entry.mRemoveContentMode = getIntAttribute(parser, "removeContentMode",
-                    REMOVE_CONTENT_MODE_UNDEFINED);
-            entry.mShouldShowWithInsecureKeyguard = getBooleanAttribute(parser,
-                    "shouldShowWithInsecureKeyguard");
-            entry.mShouldShowSystemDecors = getBooleanAttribute(parser, "shouldShowSystemDecors");
-            entry.mShouldShowIme = getBooleanAttribute(parser, "shouldShowIme");
-            entry.mFixedToUserRotation = getIntAttribute(parser, "fixedToUserRotation");
-            entry.mIgnoreOrientationRequest
-                    = getBooleanAttribute(parser, "ignoreOrientationRequest");
-            mEntries.put(name, entry);
-        }
-        XmlUtils.skipCurrentTag(parser);
-    }
-
-    private void readConfig(XmlPullParser parser) throws NumberFormatException,
-            XmlPullParserException, IOException {
-        mIdentifier = getIntAttribute(parser, "identifier");
-        XmlUtils.skipCurrentTag(parser);
-    }
-
-    private void writeSettingsIfNeeded(Entry changedEntry, DisplayInfo displayInfo) {
-        if (changedEntry.isEmpty() && !removeEntry(displayInfo)) {
-            // The entry didn't exist so nothing is changed and no need to update the file.
-            return;
-        }
-
-        mEntries.put(getIdentifier(displayInfo), changedEntry);
-        writeSettings();
-    }
-
-    private void writeSettings() {
-        OutputStream stream;
-        try {
-            stream = mStorage.startWrite();
-        } catch (IOException e) {
-            Slog.w(TAG, "Failed to write display settings: " + e);
-            return;
-        }
-
-        try {
-            XmlSerializer out = new FastXmlSerializer();
-            out.setOutput(stream, StandardCharsets.UTF_8.name());
-            out.startDocument(null, true);
-
-            out.startTag(null, "display-settings");
-
-            out.startTag(null, "config");
-            out.attribute(null, "identifier", Integer.toString(mIdentifier));
-            out.endTag(null, "config");
-
-            for (Entry entry : mEntries.values()) {
-                out.startTag(null, "display");
-                out.attribute(null, "name", entry.mName);
-                if (entry.mWindowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
-                    out.attribute(null, "windowingMode", Integer.toString(entry.mWindowingMode));
-                }
-                if (entry.mUserRotationMode != WindowManagerPolicy.USER_ROTATION_FREE) {
-                    out.attribute(null, "userRotationMode",
-                            Integer.toString(entry.mUserRotationMode));
-                }
-                if (entry.mUserRotation != Surface.ROTATION_0) {
-                    out.attribute(null, "userRotation", Integer.toString(entry.mUserRotation));
-                }
-                if (entry.mForcedWidth != 0 && entry.mForcedHeight != 0) {
-                    out.attribute(null, "forcedWidth", Integer.toString(entry.mForcedWidth));
-                    out.attribute(null, "forcedHeight", Integer.toString(entry.mForcedHeight));
-                }
-                if (entry.mForcedDensity != 0) {
-                    out.attribute(null, "forcedDensity", Integer.toString(entry.mForcedDensity));
-                }
-                if (entry.mForcedScalingMode != FORCE_SCALING_MODE_AUTO) {
-                    out.attribute(null, "forcedScalingMode",
-                            Integer.toString(entry.mForcedScalingMode));
-                }
-                if (entry.mRemoveContentMode != REMOVE_CONTENT_MODE_UNDEFINED) {
-                    out.attribute(null, "removeContentMode",
-                            Integer.toString(entry.mRemoveContentMode));
-                }
-                if (entry.mShouldShowWithInsecureKeyguard) {
-                    out.attribute(null, "shouldShowWithInsecureKeyguard",
-                            Boolean.toString(entry.mShouldShowWithInsecureKeyguard));
-                }
-                if (entry.mShouldShowSystemDecors) {
-                    out.attribute(null, "shouldShowSystemDecors",
-                            Boolean.toString(entry.mShouldShowSystemDecors));
-                }
-                if (entry.mShouldShowIme) {
-                    out.attribute(null, "shouldShowIme", Boolean.toString(entry.mShouldShowIme));
-                }
-                if (entry.mFixedToUserRotation != IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT) {
-                    out.attribute(null, "fixedToUserRotation",
-                            Integer.toString(entry.mFixedToUserRotation));
-                }
-                if (entry.mIgnoreOrientationRequest) {
-                    out.attribute(null, "ignoreOrientationRequest",
-                            Boolean.toString(entry.mIgnoreOrientationRequest));
-                }
-                out.endTag(null, "display");
-            }
-
-            out.endTag(null, "display-settings");
-            out.endDocument();
-            mStorage.finishWrite(stream, true /* success */);
-        } catch (IOException e) {
-            Slog.w(TAG, "Failed to write display window settings.", e);
-            mStorage.finishWrite(stream, false /* success */);
-        }
-    }
-
     /**
-     * Removes an entry from {@link #mEntries} cache. Looks up by new and previously used
-     * identifiers.
+     * Provides the functionality to lookup the {@link SettingsEntry settings} for a given
+     * {@link DisplayInfo}.
+     * <p>
+     * NOTE: All interactions with implementations of this provider <b>must</b> be thread-safe
+     * externally.
      */
-    private boolean removeEntry(DisplayInfo displayInfo) {
-        // Remove entry based on primary identifier.
-        boolean removed = mEntries.remove(getIdentifier(displayInfo)) != null;
-        // Ensure that legacy entries are cleared as well.
-        removed |= mEntries.remove(displayInfo.uniqueId) != null;
-        removed |= mEntries.remove(displayInfo.name) != null;
-        return removed;
-    }
+    interface SettingsProvider {
+        /**
+         * Returns the {@link SettingsEntry} for a given {@link DisplayInfo}. The values for the
+         * returned settings are guaranteed to match those previously set with
+         * {@link #updateOverrideSettings(DisplayInfo, SettingsEntry)} with all other values left
+         * to the implementation to determine.
+         */
+        @NonNull
+        SettingsEntry getSettings(@NonNull DisplayInfo info);
 
-    /** Gets the identifier of choice for the current config. */
-    private String getIdentifier(DisplayInfo displayInfo) {
-        if (mIdentifier == IDENTIFIER_PORT && displayInfo.address != null) {
-            // Config suggests using port as identifier for physical displays.
-            if (displayInfo.address instanceof DisplayAddress.Physical) {
-                return "port:" + ((DisplayAddress.Physical) displayInfo.address).getPort();
+        /**
+         * Returns the existing override settings for the given {@link DisplayInfo}. All calls to
+         * {@link #getSettings(DisplayInfo)} for the provided {@code info} are required to have
+         * their values overridden with all set values from the returned {@link SettingsEntry}.
+         *
+         * @see #getSettings(DisplayInfo)
+         * @see #updateOverrideSettings(DisplayInfo, SettingsEntry)
+         */
+        @NonNull
+        SettingsEntry getOverrideSettings(@NonNull DisplayInfo info);
+
+        /**
+         * Updates the override settings for a given {@link DisplayInfo}. All subsequent calls to
+         * {@link #getSettings(DisplayInfo)} for the provided {@link DisplayInfo} are required to
+         * have their values match all set values in {@code overrides}.
+         *
+         * @see #getSettings(DisplayInfo)
+         */
+        void updateOverrideSettings(@NonNull DisplayInfo info, @NonNull SettingsEntry overrides);
+
+        /**
+         * Settings for a display.
+         */
+        class SettingsEntry {
+            int mWindowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+            @Nullable
+            Integer mUserRotationMode;
+            @Nullable
+            Integer mUserRotation;
+            int mForcedWidth;
+            int mForcedHeight;
+            int mForcedDensity;
+            @Nullable
+            Integer mForcedScalingMode;
+            int mRemoveContentMode = REMOVE_CONTENT_MODE_UNDEFINED;
+            @Nullable
+            Boolean mShouldShowWithInsecureKeyguard;
+            @Nullable
+            Boolean mShouldShowSystemDecors;
+            @Nullable
+            Boolean mShouldShowIme;
+            @Nullable
+            Integer mFixedToUserRotation;
+            @Nullable
+            Boolean mIgnoreOrientationRequest;
+
+            SettingsEntry() {}
+
+            SettingsEntry(SettingsEntry copyFrom) {
+                setTo(copyFrom);
             }
-        }
-        return displayInfo.uniqueId;
-    }
 
-    private static class AtomicFileStorage implements SettingPersister {
-        private final AtomicFile mAtomicFile;
-
-        AtomicFileStorage() {
-            final File folder = new File(Environment.getDataDirectory(), SYSTEM_DIRECTORY);
-            final File settingsFile = new File(folder, DISPLAY_SETTINGS_FILE_NAME);
-            // If display_settings.xml doesn't exist, try to copy the vendor's one instead
-            // in order to provide the vendor specific initialization.
-            if (!settingsFile.exists()) {
-                copyVendorSettings(settingsFile);
-            }
-            mAtomicFile = new AtomicFile(settingsFile, WM_DISPLAY_COMMIT_TAG);
-        }
-
-        private static void copyVendorSettings(File target) {
-            final File vendorFile = new File(Environment.getVendorDirectory(),
-                    VENDOR_DISPLAY_SETTINGS_PATH);
-            if (vendorFile.canRead()) {
-                try {
-                    FileUtils.copy(vendorFile, target);
-                } catch (IOException e) {
-                    Slog.e(TAG, "Failed to copy vendor display_settings.xml");
+            /**
+             * Copies all fields from {@code delta} into this {@link SettingsEntry} object, keeping
+             * track of whether a change has occurred.
+             *
+             * @return {@code true} if this settings have changed as a result of the copy,
+             *         {@code false} otherwise.
+             *
+             * @see #updateFrom(SettingsEntry)
+             */
+            boolean setTo(@NonNull SettingsEntry other) {
+                boolean changed = false;
+                if (other.mWindowingMode != mWindowingMode) {
+                    mWindowingMode = other.mWindowingMode;
+                    changed = true;
                 }
+                if (!Objects.equals(other.mUserRotationMode, mUserRotationMode)) {
+                    mUserRotationMode = other.mUserRotationMode;
+                    changed = true;
+                }
+                if (!Objects.equals(other.mUserRotation, mUserRotation)) {
+                    mUserRotation = other.mUserRotation;
+                    changed = true;
+                }
+                if (other.mForcedWidth != mForcedWidth) {
+                    mForcedWidth = other.mForcedWidth;
+                    changed = true;
+                }
+                if (other.mForcedHeight != mForcedHeight) {
+                    mForcedHeight = other.mForcedHeight;
+                    changed = true;
+                }
+                if (other.mForcedDensity != mForcedDensity) {
+                    mForcedDensity = other.mForcedDensity;
+                    changed = true;
+                }
+                if (!Objects.equals(other.mForcedScalingMode, mForcedScalingMode)) {
+                    mForcedScalingMode = other.mForcedScalingMode;
+                    changed = true;
+                }
+                if (other.mRemoveContentMode != mRemoveContentMode) {
+                    mRemoveContentMode = other.mRemoveContentMode;
+                    changed = true;
+                }
+                if (other.mShouldShowWithInsecureKeyguard != mShouldShowWithInsecureKeyguard) {
+                    mShouldShowWithInsecureKeyguard = other.mShouldShowWithInsecureKeyguard;
+                    changed = true;
+                }
+                if (other.mShouldShowSystemDecors != mShouldShowSystemDecors) {
+                    mShouldShowSystemDecors = other.mShouldShowSystemDecors;
+                    changed = true;
+                }
+                if (other.mShouldShowIme != mShouldShowIme) {
+                    mShouldShowIme = other.mShouldShowIme;
+                    changed = true;
+                }
+                if (!Objects.equals(other.mFixedToUserRotation, mFixedToUserRotation)) {
+                    mFixedToUserRotation = other.mFixedToUserRotation;
+                    changed = true;
+                }
+                if (other.mIgnoreOrientationRequest != mIgnoreOrientationRequest) {
+                    mIgnoreOrientationRequest = other.mIgnoreOrientationRequest;
+                    changed = true;
+                }
+                return changed;
             }
-        }
 
-        @Override
-        public InputStream openRead() throws FileNotFoundException {
-            return mAtomicFile.openRead();
-        }
-
-        @Override
-        public OutputStream startWrite() throws IOException {
-            return mAtomicFile.startWrite();
-        }
-
-        @Override
-        public void finishWrite(OutputStream os, boolean success) {
-            if (!(os instanceof FileOutputStream)) {
-                throw new IllegalArgumentException("Unexpected OutputStream as argument: " + os);
+            /**
+             * Copies the fields from {@code delta} into this {@link SettingsEntry} object, keeping
+             * track of whether a change has occurred. Any undefined fields in {@code delta} are
+             * ignored and not copied into the current {@link SettingsEntry}.
+             *
+             * @return {@code true} if this settings have changed as a result of the copy,
+             *         {@code false} otherwise.
+             *
+             * @see #setTo(SettingsEntry)
+             */
+            boolean updateFrom(@NonNull SettingsEntry delta) {
+                boolean changed = false;
+                if (delta.mWindowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED
+                        && delta.mWindowingMode != mWindowingMode) {
+                    mWindowingMode = delta.mWindowingMode;
+                    changed = true;
+                }
+                if (delta.mUserRotationMode != null
+                        && !Objects.equals(delta.mUserRotationMode, mUserRotationMode)) {
+                    mUserRotationMode = delta.mUserRotationMode;
+                    changed = true;
+                }
+                if (delta.mUserRotation != null
+                        && !Objects.equals(delta.mUserRotation, mUserRotation)) {
+                    mUserRotation = delta.mUserRotation;
+                    changed = true;
+                }
+                if (delta.mForcedWidth != 0 && delta.mForcedWidth != mForcedWidth) {
+                    mForcedWidth = delta.mForcedWidth;
+                    changed = true;
+                }
+                if (delta.mForcedHeight != 0 && delta.mForcedHeight != mForcedHeight) {
+                    mForcedHeight = delta.mForcedHeight;
+                    changed = true;
+                }
+                if (delta.mForcedDensity != 0 && delta.mForcedDensity != mForcedDensity) {
+                    mForcedDensity = delta.mForcedDensity;
+                    changed = true;
+                }
+                if (delta.mForcedScalingMode != null
+                        && !Objects.equals(delta.mForcedScalingMode, mForcedScalingMode)) {
+                    mForcedScalingMode = delta.mForcedScalingMode;
+                    changed = true;
+                }
+                if (delta.mRemoveContentMode != REMOVE_CONTENT_MODE_UNDEFINED
+                        && delta.mRemoveContentMode != mRemoveContentMode) {
+                    mRemoveContentMode = delta.mRemoveContentMode;
+                    changed = true;
+                }
+                if (delta.mShouldShowWithInsecureKeyguard != null
+                        && delta.mShouldShowWithInsecureKeyguard
+                        != mShouldShowWithInsecureKeyguard) {
+                    mShouldShowWithInsecureKeyguard = delta.mShouldShowWithInsecureKeyguard;
+                    changed = true;
+                }
+                if (delta.mShouldShowSystemDecors != null
+                        && delta.mShouldShowSystemDecors != mShouldShowSystemDecors) {
+                    mShouldShowSystemDecors = delta.mShouldShowSystemDecors;
+                    changed = true;
+                }
+                if (delta.mShouldShowIme != null
+                        && delta.mShouldShowIme != mShouldShowIme) {
+                    mShouldShowIme = delta.mShouldShowIme;
+                    changed = true;
+                }
+                if (delta.mFixedToUserRotation != null
+                        && !Objects.equals(delta.mFixedToUserRotation, mFixedToUserRotation)) {
+                    mFixedToUserRotation = delta.mFixedToUserRotation;
+                    changed = true;
+                }
+                if (delta.mIgnoreOrientationRequest != null
+                        && delta.mIgnoreOrientationRequest != mIgnoreOrientationRequest) {
+                    mIgnoreOrientationRequest = delta.mIgnoreOrientationRequest;
+                    changed = true;
+                }
+                return changed;
             }
-            FileOutputStream fos = (FileOutputStream) os;
-            if (success) {
-                mAtomicFile.finishWrite(fos);
-            } else {
-                mAtomicFile.failWrite(fos);
+
+            /** @return {@code true} if all values are unset. */
+            boolean isEmpty() {
+                return mWindowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED
+                        && mUserRotationMode == null
+                        && mUserRotation == null
+                        && mForcedWidth == 0 && mForcedHeight == 0 && mForcedDensity == 0
+                        && mForcedScalingMode == null
+                        && mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED
+                        && mShouldShowWithInsecureKeyguard == null
+                        && mShouldShowSystemDecors == null
+                        && mShouldShowIme == null
+                        && mFixedToUserRotation == null
+                        && mIgnoreOrientationRequest == null;
+            }
+
+            @Override
+            public boolean equals(@Nullable Object o) {
+                if (this == o) return true;
+                if (o == null || getClass() != o.getClass()) return false;
+                SettingsEntry that = (SettingsEntry) o;
+                return mWindowingMode == that.mWindowingMode
+                        && mForcedWidth == that.mForcedWidth
+                        && mForcedHeight == that.mForcedHeight
+                        && mForcedDensity == that.mForcedDensity
+                        && mRemoveContentMode == that.mRemoveContentMode
+                        && Objects.equals(mUserRotationMode, that.mUserRotationMode)
+                        && Objects.equals(mUserRotation, that.mUserRotation)
+                        && Objects.equals(mForcedScalingMode, that.mForcedScalingMode)
+                        && Objects.equals(mShouldShowWithInsecureKeyguard,
+                                that.mShouldShowWithInsecureKeyguard)
+                        && Objects.equals(mShouldShowSystemDecors, that.mShouldShowSystemDecors)
+                        && Objects.equals(mShouldShowIme, that.mShouldShowIme)
+                        && Objects.equals(mFixedToUserRotation, that.mFixedToUserRotation)
+                        && Objects.equals(mIgnoreOrientationRequest,
+                                that.mIgnoreOrientationRequest);
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(mWindowingMode, mUserRotationMode, mUserRotation, mForcedWidth,
+                        mForcedHeight, mForcedDensity, mForcedScalingMode, mRemoveContentMode,
+                        mShouldShowWithInsecureKeyguard, mShouldShowSystemDecors, mShouldShowIme,
+                        mFixedToUserRotation, mIgnoreOrientationRequest);
+            }
+
+            @Override
+            public String toString() {
+                return "SettingsEntry{"
+                        + "mWindowingMode=" + mWindowingMode
+                        + ", mUserRotationMode=" + mUserRotationMode
+                        + ", mUserRotation=" + mUserRotation
+                        + ", mForcedWidth=" + mForcedWidth
+                        + ", mForcedHeight=" + mForcedHeight
+                        + ", mForcedDensity=" + mForcedDensity
+                        + ", mForcedScalingMode=" + mForcedScalingMode
+                        + ", mRemoveContentMode=" + mRemoveContentMode
+                        + ", mShouldShowWithInsecureKeyguard=" + mShouldShowWithInsecureKeyguard
+                        + ", mShouldShowSystemDecors=" + mShouldShowSystemDecors
+                        + ", mShouldShowIme=" + mShouldShowIme
+                        + ", mFixedToUserRotation=" + mFixedToUserRotation
+                        + ", mIgnoreOrientationRequest=" + mIgnoreOrientationRequest
+                        + '}';
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
new file mode 100644
index 0000000..a7f7c48
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
@@ -0,0 +1,549 @@
+/*
+ * 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.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
+
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.WindowConfiguration;
+import android.os.Environment;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.Xml;
+import android.view.DisplayAddress;
+import android.view.DisplayInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
+import com.android.server.wm.DisplayWindowSettings.SettingsProvider;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implementation of {@link SettingsProvider} that reads the base settings provided in a display
+ * settings file stored in /vendor/etc and then overlays those values with the settings provided in
+ * /data/system.
+ *
+ * @see DisplayWindowSettings
+ */
+class DisplayWindowSettingsProvider implements SettingsProvider {
+    private static final String TAG = TAG_WITH_CLASS_NAME
+            ? "DisplayWindowSettingsProvider" : TAG_WM;
+
+    private static final String DATA_DISPLAY_SETTINGS_FILE_PATH = "system/display_settings.xml";
+    private static final String VENDOR_DISPLAY_SETTINGS_PATH = "etc/display_settings.xml";
+    private static final String WM_DISPLAY_COMMIT_TAG = "wm-displays";
+
+    private static final int IDENTIFIER_UNIQUE_ID = 0;
+    private static final int IDENTIFIER_PORT = 1;
+    @IntDef(prefix = { "IDENTIFIER_" }, value = {
+            IDENTIFIER_UNIQUE_ID,
+            IDENTIFIER_PORT,
+    })
+    @interface DisplayIdentifierType {}
+
+    /** Interface that allows reading the display window settings. */
+    interface ReadableSettingsStorage {
+        InputStream openRead() throws IOException;
+    }
+
+    /** Interface that allows reading and writing the display window settings. */
+    interface WritableSettingsStorage extends ReadableSettingsStorage {
+        OutputStream startWrite() throws IOException;
+        void finishWrite(OutputStream os, boolean success);
+    }
+
+    private final ReadableSettingsStorage mVendorSettingsStorage;
+    /**
+     * The preferred type of a display identifier to use when storing and retrieving entries from
+     * the base (vendor) settings file.
+     *
+     * @see #getIdentifier(DisplayInfo, int)
+     */
+    @DisplayIdentifierType
+    private int mVendorIdentifierType;
+    private final Map<String, SettingsEntry> mVendorSettings = new HashMap<>();
+
+    private final WritableSettingsStorage mOverrideSettingsStorage;
+    /**
+     * The preferred type of a display identifier to use when storing and retrieving entries from
+     * the data (override) settings file.
+     *
+     * @see #getIdentifier(DisplayInfo, int)
+     */
+    @DisplayIdentifierType
+    private int mOverrideIdentifierType;
+    private final Map<String, SettingsEntry> mOverrideSettings = new HashMap<>();
+
+    /**
+     * Enables or disables settings provided from the vendor settings storage.
+     *
+     * @see #setVendorSettingsIgnored(boolean)
+     */
+    private boolean mIgnoreVendorSettings = true;
+
+    DisplayWindowSettingsProvider() {
+        this(new AtomicFileStorage(getVendorSettingsFile()),
+                new AtomicFileStorage(getOverrideSettingsFile()));
+    }
+
+    @VisibleForTesting
+    DisplayWindowSettingsProvider(@NonNull ReadableSettingsStorage vendorSettingsStorage,
+            @NonNull WritableSettingsStorage overrideSettingsStorage) {
+        mVendorSettingsStorage = vendorSettingsStorage;
+        mOverrideSettingsStorage = overrideSettingsStorage;
+        readSettings();
+    }
+
+    /**
+     * Enables or disables settings provided from the vendor settings storage. If {@code true}, the
+     * vendor settings will be ignored and only the override settings will be returned from
+     * {@link #getSettings(DisplayInfo)}. If {@code false}, settings returned from
+     * {@link #getSettings(DisplayInfo)} will be a merged result of the vendor settings and the
+     * override settings.
+     */
+    void setVendorSettingsIgnored(boolean ignored) {
+        mIgnoreVendorSettings = ignored;
+    }
+
+    /**
+     * Returns whether or not the vendor settings are being ignored.
+     *
+     * @see #setVendorSettingsIgnored(boolean)
+     */
+    @VisibleForTesting
+    boolean getVendorSettingsIgnored() {
+        return mIgnoreVendorSettings;
+    }
+
+    @Override
+    @NonNull
+    public SettingsEntry getSettings(@NonNull DisplayInfo info) {
+        SettingsEntry vendorSettings = getVendorSettingsEntry(info);
+        SettingsEntry overrideSettings = getOrCreateOverrideSettingsEntry(info);
+        if (vendorSettings == null) {
+            return new SettingsEntry(overrideSettings);
+        } else {
+            SettingsEntry mergedSettings = new SettingsEntry(vendorSettings);
+            mergedSettings.updateFrom(overrideSettings);
+            return mergedSettings;
+        }
+    }
+
+    @Override
+    @NonNull
+    public SettingsEntry getOverrideSettings(@NonNull DisplayInfo info) {
+        return new SettingsEntry(getOrCreateOverrideSettingsEntry(info));
+    }
+
+    @Override
+    public void updateOverrideSettings(@NonNull DisplayInfo info,
+            @NonNull SettingsEntry overrides) {
+        final SettingsEntry overrideSettings = getOrCreateOverrideSettingsEntry(info);
+        boolean changed = overrideSettings.setTo(overrides);
+        if (changed) {
+            writeOverrideSettings();
+        }
+    }
+
+    @Nullable
+    private SettingsEntry getVendorSettingsEntry(DisplayInfo info) {
+        if (mIgnoreVendorSettings) {
+            return null;
+        }
+
+        final String identifier = getIdentifier(info, mVendorIdentifierType);
+        SettingsEntry settings;
+        // Try to get corresponding settings using preferred identifier for the current config.
+        if ((settings = mVendorSettings.get(identifier)) != null) {
+            return settings;
+        }
+        // Else, fall back to the display name.
+        if ((settings = mVendorSettings.get(info.name)) != null) {
+            // Found an entry stored with old identifier.
+            mVendorSettings.remove(info.name);
+            mVendorSettings.put(identifier, settings);
+            return settings;
+        }
+        return null;
+    }
+
+    @NonNull
+    private SettingsEntry getOrCreateOverrideSettingsEntry(DisplayInfo info) {
+        final String identifier = getIdentifier(info, mOverrideIdentifierType);
+        SettingsEntry settings;
+        // Try to get corresponding settings using preferred identifier for the current config.
+        if ((settings = mOverrideSettings.get(identifier)) != null) {
+            return settings;
+        }
+        // Else, fall back to the display name.
+        if ((settings = mOverrideSettings.get(info.name)) != null) {
+            // Found an entry stored with old identifier.
+            mOverrideSettings.remove(info.name);
+            mOverrideSettings.put(identifier, settings);
+            writeOverrideSettings();
+            return settings;
+        }
+
+        settings = new SettingsEntry();
+        mOverrideSettings.put(identifier, settings);
+        return settings;
+    }
+
+    private void readSettings() {
+        FileData vendorFileData = readSettings(mVendorSettingsStorage);
+        if (vendorFileData != null) {
+            mVendorIdentifierType = vendorFileData.mIdentifierType;
+            mVendorSettings.putAll(vendorFileData.mSettings);
+        }
+
+        FileData overrideFileData = readSettings(mOverrideSettingsStorage);
+        if (overrideFileData != null) {
+            mOverrideIdentifierType = overrideFileData.mIdentifierType;
+            mOverrideSettings.putAll(overrideFileData.mSettings);
+        }
+    }
+
+    private void writeOverrideSettings() {
+        FileData fileData = new FileData();
+        fileData.mIdentifierType = mOverrideIdentifierType;
+        fileData.mSettings.putAll(mOverrideSettings);
+        writeSettings(mOverrideSettingsStorage, fileData);
+    }
+
+    /** Gets the identifier of choice for the current config. */
+    private static String getIdentifier(DisplayInfo displayInfo, @DisplayIdentifierType int type) {
+        if (type == IDENTIFIER_PORT && displayInfo.address != null) {
+            // Config suggests using port as identifier for physical displays.
+            if (displayInfo.address instanceof DisplayAddress.Physical) {
+                return "port:" + ((DisplayAddress.Physical) displayInfo.address).getPort();
+            }
+        }
+        return displayInfo.uniqueId;
+    }
+
+    @NonNull
+    private static AtomicFile getVendorSettingsFile() {
+        final File vendorFile = new File(Environment.getVendorDirectory(),
+                VENDOR_DISPLAY_SETTINGS_PATH);
+        return new AtomicFile(vendorFile, WM_DISPLAY_COMMIT_TAG);
+    }
+
+    @NonNull
+    private static AtomicFile getOverrideSettingsFile() {
+        final File overrideSettingsFile = new File(Environment.getDataDirectory(),
+                DATA_DISPLAY_SETTINGS_FILE_PATH);
+        return new AtomicFile(overrideSettingsFile, WM_DISPLAY_COMMIT_TAG);
+    }
+
+    @Nullable
+    private static FileData readSettings(ReadableSettingsStorage storage) {
+        InputStream stream;
+        try {
+            stream = storage.openRead();
+        } catch (IOException e) {
+            Slog.i(TAG, "No existing display settings, starting empty");
+            return null;
+        }
+        FileData fileData = new FileData();
+        boolean success = false;
+        try {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(stream, StandardCharsets.UTF_8.name());
+            int type;
+            while ((type = parser.next()) != XmlPullParser.START_TAG
+                    && type != XmlPullParser.END_DOCUMENT) {
+                // Do nothing.
+            }
+
+            if (type != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("no start tag found");
+            }
+
+            int outerDepth = parser.getDepth();
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                    continue;
+                }
+
+                String tagName = parser.getName();
+                if (tagName.equals("display")) {
+                    readDisplay(parser, fileData);
+                } else if (tagName.equals("config")) {
+                    readConfig(parser, fileData);
+                } else {
+                    Slog.w(TAG, "Unknown element under <display-settings>: "
+                            + parser.getName());
+                    XmlUtils.skipCurrentTag(parser);
+                }
+            }
+            success = true;
+        } catch (IllegalStateException e) {
+            Slog.w(TAG, "Failed parsing " + e);
+        } catch (NullPointerException e) {
+            Slog.w(TAG, "Failed parsing " + e);
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Failed parsing " + e);
+        } catch (XmlPullParserException e) {
+            Slog.w(TAG, "Failed parsing " + e);
+        } catch (IOException e) {
+            Slog.w(TAG, "Failed parsing " + e);
+        } catch (IndexOutOfBoundsException e) {
+            Slog.w(TAG, "Failed parsing " + e);
+        } finally {
+            try {
+                stream.close();
+            } catch (IOException ignored) {
+            }
+        }
+        if (!success) {
+            fileData.mSettings.clear();
+        }
+        return fileData;
+    }
+
+    private static int getIntAttribute(XmlPullParser parser, String name, int defaultValue) {
+        try {
+            final String str = parser.getAttributeValue(null, name);
+            return str != null ? Integer.parseInt(str) : defaultValue;
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Failed to parse display window settings attribute: " + name, e);
+            return defaultValue;
+        }
+    }
+
+    @Nullable
+    private static Integer getIntegerAttribute(XmlPullParser parser, String name,
+            @Nullable Integer defaultValue) {
+        try {
+            final String str = parser.getAttributeValue(null, name);
+            return str != null ? Integer.valueOf(str) : defaultValue;
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Failed to parse display window settings attribute: " + name, e);
+            return defaultValue;
+        }
+    }
+
+    @Nullable
+    private static Boolean getBooleanAttribute(XmlPullParser parser, String name,
+            @Nullable Boolean defaultValue) {
+        final String str = parser.getAttributeValue(null, name);
+        return str != null ? Boolean.valueOf(str) : defaultValue;
+    }
+
+    private static void readDisplay(XmlPullParser parser, FileData fileData)
+            throws NumberFormatException, XmlPullParserException, IOException {
+        String name = parser.getAttributeValue(null, "name");
+        if (name != null) {
+            SettingsEntry settingsEntry = new SettingsEntry();
+            settingsEntry.mWindowingMode = getIntAttribute(parser, "windowingMode",
+                    WindowConfiguration.WINDOWING_MODE_UNDEFINED /* defaultValue */);
+            settingsEntry.mUserRotationMode = getIntegerAttribute(parser, "userRotationMode",
+                    null /* defaultValue */);
+            settingsEntry.mUserRotation = getIntegerAttribute(parser, "userRotation",
+                    null /* defaultValue */);
+            settingsEntry.mForcedWidth = getIntAttribute(parser, "forcedWidth",
+                    0 /* defaultValue */);
+            settingsEntry.mForcedHeight = getIntAttribute(parser, "forcedHeight",
+                    0 /* defaultValue */);
+            settingsEntry.mForcedDensity = getIntAttribute(parser, "forcedDensity",
+                    0 /* defaultValue */);
+            settingsEntry.mForcedScalingMode = getIntegerAttribute(parser, "forcedScalingMode",
+                    null /* defaultValue */);
+            settingsEntry.mRemoveContentMode = getIntAttribute(parser, "removeContentMode",
+                    REMOVE_CONTENT_MODE_UNDEFINED /* defaultValue */);
+            settingsEntry.mShouldShowWithInsecureKeyguard = getBooleanAttribute(parser,
+                    "shouldShowWithInsecureKeyguard", null /* defaultValue */);
+            settingsEntry.mShouldShowSystemDecors = getBooleanAttribute(parser,
+                    "shouldShowSystemDecors", null /* defaultValue */);
+            settingsEntry.mShouldShowIme = getBooleanAttribute(parser, "shouldShowIme",
+                    null /* defaultValue */);
+            settingsEntry.mFixedToUserRotation = getIntegerAttribute(parser, "fixedToUserRotation",
+                    null /* defaultValue */);
+            settingsEntry.mIgnoreOrientationRequest = getBooleanAttribute(parser,
+                    "ignoreOrientationRequest", null /* defaultValue */);
+            fileData.mSettings.put(name, settingsEntry);
+        }
+        XmlUtils.skipCurrentTag(parser);
+    }
+
+    private static void readConfig(XmlPullParser parser, FileData fileData)
+            throws NumberFormatException,
+            XmlPullParserException, IOException {
+        fileData.mIdentifierType = getIntAttribute(parser, "identifier",
+                IDENTIFIER_UNIQUE_ID);
+        XmlUtils.skipCurrentTag(parser);
+    }
+
+    private static void writeSettings(WritableSettingsStorage storage, FileData data) {
+        OutputStream stream;
+        try {
+            stream = storage.startWrite();
+        } catch (IOException e) {
+            Slog.w(TAG, "Failed to write display settings: " + e);
+            return;
+        }
+
+        boolean success = false;
+        try {
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(stream, StandardCharsets.UTF_8.name());
+            out.startDocument(null, true);
+
+            out.startTag(null, "display-settings");
+
+            out.startTag(null, "config");
+            out.attribute(null, "identifier",
+                    Integer.toString(data.mIdentifierType));
+            out.endTag(null, "config");
+
+            for (Map.Entry<String, SettingsEntry> entry
+                    : data.mSettings.entrySet()) {
+                String displayIdentifier = entry.getKey();
+                SettingsEntry settingsEntry = entry.getValue();
+                if (settingsEntry.isEmpty()) {
+                    continue;
+                }
+
+                out.startTag(null, "display");
+                out.attribute(null, "name", displayIdentifier);
+                if (settingsEntry.mWindowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
+                    out.attribute(null, "windowingMode",
+                            Integer.toString(settingsEntry.mWindowingMode));
+                }
+                if (settingsEntry.mUserRotationMode != null) {
+                    out.attribute(null, "userRotationMode",
+                            settingsEntry.mUserRotationMode.toString());
+                }
+                if (settingsEntry.mUserRotation != null) {
+                    out.attribute(null, "userRotation",
+                            settingsEntry.mUserRotation.toString());
+                }
+                if (settingsEntry.mForcedWidth != 0 && settingsEntry.mForcedHeight != 0) {
+                    out.attribute(null, "forcedWidth",
+                            Integer.toString(settingsEntry.mForcedWidth));
+                    out.attribute(null, "forcedHeight",
+                            Integer.toString(settingsEntry.mForcedHeight));
+                }
+                if (settingsEntry.mForcedDensity != 0) {
+                    out.attribute(null, "forcedDensity",
+                            Integer.toString(settingsEntry.mForcedDensity));
+                }
+                if (settingsEntry.mForcedScalingMode != null) {
+                    out.attribute(null, "forcedScalingMode",
+                            settingsEntry.mForcedScalingMode.toString());
+                }
+                if (settingsEntry.mRemoveContentMode != REMOVE_CONTENT_MODE_UNDEFINED) {
+                    out.attribute(null, "removeContentMode",
+                            Integer.toString(settingsEntry.mRemoveContentMode));
+                }
+                if (settingsEntry.mShouldShowWithInsecureKeyguard != null) {
+                    out.attribute(null, "shouldShowWithInsecureKeyguard",
+                            settingsEntry.mShouldShowWithInsecureKeyguard.toString());
+                }
+                if (settingsEntry.mShouldShowSystemDecors != null) {
+                    out.attribute(null, "shouldShowSystemDecors",
+                            settingsEntry.mShouldShowSystemDecors.toString());
+                }
+                if (settingsEntry.mShouldShowIme != null) {
+                    out.attribute(null, "shouldShowIme",
+                            settingsEntry.mShouldShowIme.toString());
+                }
+                if (settingsEntry.mFixedToUserRotation != null) {
+                    out.attribute(null, "fixedToUserRotation",
+                            settingsEntry.mFixedToUserRotation.toString());
+                }
+                if (settingsEntry.mIgnoreOrientationRequest != null) {
+                    out.attribute(null, "ignoreOrientationRequest",
+                            settingsEntry.mIgnoreOrientationRequest.toString());
+                }
+                out.endTag(null, "display");
+            }
+
+            out.endTag(null, "display-settings");
+            out.endDocument();
+            success = true;
+        } catch (IOException e) {
+            Slog.w(TAG, "Failed to write display window settings.", e);
+        } finally {
+            storage.finishWrite(stream, success);
+        }
+    }
+
+    private static final class FileData {
+        int mIdentifierType;
+        final Map<String, SettingsEntry> mSettings = new HashMap<>();
+
+        @Override
+        public String toString() {
+            return "FileData{"
+                    + "mIdentifierType=" + mIdentifierType
+                    + ", mSettings=" + mSettings
+                    + '}';
+        }
+    }
+
+    private static final class AtomicFileStorage implements WritableSettingsStorage {
+        private final AtomicFile mAtomicFile;
+
+        AtomicFileStorage(@NonNull AtomicFile atomicFile) {
+            mAtomicFile = atomicFile;
+        }
+
+        @Override
+        public InputStream openRead() throws FileNotFoundException {
+            return mAtomicFile.openRead();
+        }
+
+        @Override
+        public OutputStream startWrite() throws IOException {
+            return mAtomicFile.startWrite();
+        }
+
+        @Override
+        public void finishWrite(OutputStream os, boolean success) {
+            if (!(os instanceof FileOutputStream)) {
+                throw new IllegalArgumentException("Unexpected OutputStream as argument: " + os);
+            }
+            FileOutputStream fos = (FileOutputStream) os;
+            if (success) {
+                mAtomicFile.finishWrite(fos);
+            } else {
+                mAtomicFile.failWrite(fos);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 2ea4b57..8c80205 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -277,9 +277,8 @@
             mInputEventReceiver = new DragInputEventReceiver(mClientChannel,
                     mService.mH.getLooper(), mDragDropController);
 
-            mDragApplicationHandle = new InputApplicationHandle(new Binder());
-            mDragApplicationHandle.name = "drag";
-            mDragApplicationHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+            mDragApplicationHandle = new InputApplicationHandle(new Binder(), "drag",
+                    DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
 
             mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle,
                     display.getDisplayId());
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 3b89a24..b08d6e1 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -175,11 +175,11 @@
 
         InputApplicationHandle getApplicationHandle() {
             if (mHostWindowState == null
-                    || mHostWindowState.mInputWindowHandle.inputApplicationHandle == null) {
+                    || mHostWindowState.mInputWindowHandle.getInputApplicationHandle() == null) {
                 return null;
             }
             return new InputApplicationHandle(
-                    mHostWindowState.mInputWindowHandle.inputApplicationHandle);
+                    mHostWindowState.mInputWindowHandle.getInputApplicationHandle());
         }
 
         InputChannel openInputChannel() {
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 0813b4f..818d96c 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -16,11 +16,14 @@
 
 package com.android.server.wm;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
 import static com.android.server.wm.ImeInsetsSourceProviderProto.IME_TARGET_FROM_IME;
 import static com.android.server.wm.ImeInsetsSourceProviderProto.INSETS_SOURCE_PROVIDER;
 import static com.android.server.wm.ImeInsetsSourceProviderProto.IS_IME_LAYOUT_DRAWN;
 
+import android.os.Trace;
 import android.util.proto.ProtoOutputStream;
 import android.view.InsetsSource;
 import android.view.WindowInsets;
@@ -79,6 +82,7 @@
                 ProtoLog.i(WM_DEBUG_IME, "call showInsets(ime) on %s",
                         target.getWindow() != null ? target.getWindow().getName() : "");
                 target.showInsets(WindowInsets.Type.ime(), true /* fromIme */);
+                Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "WMS.showImePostLayout", 0);
                 if (target != mImeTargetFromIme && mImeTargetFromIme != null) {
                     ProtoLog.w(WM_DEBUG_IME,
                             "showInsets(ime) was requested by different window: %s ",
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index edb5e85..e35621a 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -63,9 +63,8 @@
             mClientChannel.copyTo(inputChannel);
         }
 
-        mApplicationHandle = new InputApplicationHandle(new Binder());
-        mApplicationHandle.name = name;
-        mApplicationHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+        mApplicationHandle = new InputApplicationHandle(new Binder(), name,
+                DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
 
         mWindowHandle = new InputWindowHandle(mApplicationHandle, displayId);
         mWindowHandle.name = name;
@@ -160,9 +159,11 @@
     public void binderDied() {
         synchronized (mService.getWindowManagerLock()) {
             // Clean up the input consumer
-            final InputMonitor inputMonitor =
-                    mService.mRoot.getDisplayContent(mWindowHandle.displayId).getInputMonitor();
-            inputMonitor.destroyInputConsumer(mName);
+            final DisplayContent dc = mService.mRoot.getDisplayContent(mWindowHandle.displayId);
+            if (dc == null) {
+                return;
+            }
+            dc.getInputMonitor().destroyInputConsumer(mName);
             unlinkFromDeathRecipient();
         }
     }
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 4a54196..086513b 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -48,6 +48,7 @@
 import static com.android.server.wm.WindowManagerService.LOGTAG_INPUT_FOCUS;
 
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -57,12 +58,12 @@
 import android.util.ArrayMap;
 import android.util.EventLog;
 import android.util.Slog;
-import android.view.InputApplicationHandle;
 import android.view.InputChannel;
 import android.view.InputEventReceiver;
 import android.view.InputWindowHandle;
 import android.view.SurfaceControl;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
 
 import java.io.PrintWriter;
@@ -81,7 +82,7 @@
     private boolean mUpdateInputWindowsImmediately;
 
     private boolean mDisableWallpaperTouchEvents;
-    private final Rect mTmpRect = new Rect();
+    private final Region mTmpRegion = new Region();
     private final UpdateInputForAllWindowsConsumer mUpdateInputForAllWindowsConsumer;
 
     private final int mDisplayId;
@@ -276,66 +277,67 @@
         addInputConsumer(name, consumer);
     }
 
-
-    void populateInputWindowHandle(final InputWindowHandle inputWindowHandle,
-            final WindowState child, int flags, final int type, final boolean isVisible,
-            final boolean focusable, final boolean hasWallpaper) {
+    @VisibleForTesting
+    void populateInputWindowHandle(final InputWindowHandleWrapper inputWindowHandle,
+            final WindowState w) {
         // Add a window to our list of input windows.
-        inputWindowHandle.name = child.toString();
-        flags = child.getSurfaceTouchableRegion(inputWindowHandle, flags);
-        inputWindowHandle.layoutParamsFlags = flags;
-        inputWindowHandle.layoutParamsType = type;
-        inputWindowHandle.dispatchingTimeoutMillis = child.getInputDispatchingTimeoutMillis();
-        inputWindowHandle.visible = isVisible;
-        inputWindowHandle.focusable = focusable;
-        inputWindowHandle.touchOcclusionMode = child.getTouchOcclusionMode();
-        inputWindowHandle.hasWallpaper = hasWallpaper;
-        inputWindowHandle.paused = child.mActivityRecord != null ? child.mActivityRecord.paused : false;
-        inputWindowHandle.ownerPid = child.mSession.mPid;
-        inputWindowHandle.ownerUid = child.mSession.mUid;
-        inputWindowHandle.packageName = child.getOwningPackage();
-        inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;
-        inputWindowHandle.displayId = child.getDisplayId();
+        inputWindowHandle.setInputApplicationHandle(w.mActivityRecord != null
+                ? w.mActivityRecord.getInputApplicationHandle(false /* update */) : null);
+        inputWindowHandle.setToken(w.mInputChannelToken);
+        inputWindowHandle.setDispatchingTimeoutMillis(w.getInputDispatchingTimeoutMillis());
+        inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
+        inputWindowHandle.setInputFeatures(w.mAttrs.inputFeatures);
+        inputWindowHandle.setPaused(w.mActivityRecord != null && w.mActivityRecord.paused);
+        inputWindowHandle.setVisible(w.isVisible());
 
-        final Rect frame = child.getFrame();
-        inputWindowHandle.frameLeft = frame.left;
-        inputWindowHandle.frameTop = frame.top;
-        inputWindowHandle.frameRight = frame.right;
-        inputWindowHandle.frameBottom = frame.bottom;
+        final boolean focusable = w.canReceiveKeys()
+                && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());
+        inputWindowHandle.setFocusable(focusable);
+
+        final boolean hasWallpaper = mDisplayContent.mWallpaperController.isWallpaperTarget(w)
+                && !mService.mPolicy.isKeyguardShowing()
+                && !mDisableWallpaperTouchEvents;
+        inputWindowHandle.setHasWallpaper(hasWallpaper);
+
+        final Rect frame = w.getFrame();
+        inputWindowHandle.setFrame(frame.left, frame.top, frame.right, frame.bottom);
 
         // Surface insets are hardcoded to be the same in all directions
         // and we could probably deprecate the "left/right/top/bottom" concept.
         // we avoid reintroducing this concept by just choosing one of them here.
-        inputWindowHandle.surfaceInset = child.getAttrs().surfaceInsets.left;
+        inputWindowHandle.setSurfaceInset(w.mAttrs.surfaceInsets.left);
 
-        /**
-         * If the window is in a TaskManaged by a TaskOrganizer then most cropping
-         * will be applied using the SurfaceControl hierarchy from the Organizer.
-         * This means we need to make sure that these changes in crop are reflected
-         * in the input windows, and so ensure this flag is set so that
-         * the input crop always reflects the surface hierarchy.
-         *
-         * TODO(b/168252846): we have some issues with modal-windows, so we need to
-         * cross that bridge now that we organize full-screen Tasks.
-         */
-        if (child.getTask() != null
-                && child.getTask().isOrganized()
-                && child.getTask().getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
-            inputWindowHandle.replaceTouchableRegionWithCrop(null /* Use this surfaces crop */);
+        // If we are scaling the window, input coordinates need to be inversely scaled to map from
+        // what is on screen to what is actually being touched in the UI.
+        inputWindowHandle.setScaleFactor(w.mGlobalScale != 1f ? (1f / w.mGlobalScale) : 1f);
+
+        final int flags = w.getSurfaceTouchableRegion(mTmpRegion, w.mAttrs.flags);
+        inputWindowHandle.setTouchableRegion(mTmpRegion);
+        inputWindowHandle.setLayoutParamsFlags(flags);
+
+        boolean useSurfaceCrop = false;
+        final Task task = w.getTask();
+        if (task != null) {
+            if (task.isOrganized() && task.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
+                // If the window is in a TaskManaged by a TaskOrganizer then most cropping will
+                // be applied using the SurfaceControl hierarchy from the Organizer. This means
+                // we need to make sure that these changes in crop are reflected in the input
+                // windows, and so ensure this flag is set so that the input crop always reflects
+                // the surface hierarchy.
+                // TODO(b/168252846): we have some issues with modal-windows, so we need to cross
+                // that bridge now that we organize full-screen Tasks.
+                inputWindowHandle.setTouchableRegionCrop(null /* Use this surfaces crop */);
+                inputWindowHandle.setReplaceTouchableRegionWithCrop(true);
+                useSurfaceCrop = true;
+            } else if (task.cropWindowsToStackBounds() && !w.inFreeformWindowingMode()) {
+                inputWindowHandle.setTouchableRegionCrop(task.getRootTask().getSurfaceControl());
+                inputWindowHandle.setReplaceTouchableRegionWithCrop(false);
+                useSurfaceCrop = true;
+            }
         }
-
-        if (child.mGlobalScale != 1) {
-            // If we are scaling the window, input coordinates need
-            // to be inversely scaled to map from what is on screen
-            // to what is actually being touched in the UI.
-            inputWindowHandle.scaleFactor = 1.0f/child.mGlobalScale;
-        } else {
-            inputWindowHandle.scaleFactor = 1;
-        }
-
-        if (DEBUG_INPUT) {
-            Slog.d(TAG_WM, "addInputWindowHandle: "
-                    + child + ", " + inputWindowHandle);
+        if (!useSurfaceCrop) {
+            inputWindowHandle.setReplaceTouchableRegionWithCrop(false);
+            inputWindowHandle.setTouchableRegionCrop(null);
         }
     }
 
@@ -401,15 +403,8 @@
 
     public void setFocusedAppLw(ActivityRecord newApp) {
         // Focused app has changed.
-        if (newApp == null) {
-            mService.mInputManager.setFocusedApplication(mDisplayId, null);
-        } else {
-            final InputApplicationHandle handle = newApp.mInputApplicationHandle;
-            handle.name = newApp.toString();
-            handle.dispatchingTimeoutMillis = newApp.mInputDispatchingTimeoutMillis;
-
-            mService.mInputManager.setFocusedApplication(mDisplayId, handle);
-        }
+        mService.mInputManager.setFocusedApplication(mDisplayId,
+                newApp != null ? newApp.getInputApplicationHandle(true /* update */) : null);
     }
 
     public void pauseDispatchingLw(WindowToken window) {
@@ -456,10 +451,6 @@
         private boolean mAddRecentsAnimationInputConsumerHandle;
 
         boolean mInDrag;
-        WallpaperController mWallpaperController;
-
-        // An invalid window handle that tells SurfaceFlinger not update the input info.
-        final InputWindowHandle mInvalidInputWindow = new InputWindowHandle(null, mDisplayId);
 
         private void updateInputWindows(boolean inDrag) {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateInputWindows");
@@ -474,10 +465,8 @@
             mAddWallpaperInputConsumerHandle = mWallpaperInputConsumer != null;
             mAddRecentsAnimationInputConsumerHandle = mRecentsAnimationInputConsumer != null;
 
-            mTmpRect.setEmpty();
             mDisableWallpaperTouchEvents = false;
             mInDrag = inDrag;
-            mWallpaperController = mDisplayContent.mWallpaperController;
 
             resetInputConsumers(mInputTransaction);
 
@@ -499,7 +488,7 @@
             }
 
             final WindowState focus = mDisplayContent.mCurrentFocus;
-            if (focus == null || focus.mInputWindowHandle.token == null) {
+            if (focus == null || focus.mInputChannelToken == null) {
                 mDisplayContent.mLastRequestedFocus = focus;
                 return;
             }
@@ -510,7 +499,7 @@
                 return;
             }
 
-            mInputTransaction.setFocusedWindow(focus.mInputWindowHandle.token, mDisplayId);
+            mInputTransaction.setFocusedWindow(focus.mInputChannelToken, mDisplayId);
             EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
                     "Focus request " + focus, "reason=UpdateInputWindows");
             mDisplayContent.mLastRequestedFocus = focus;
@@ -519,33 +508,26 @@
 
         @Override
         public void accept(WindowState w) {
-            final InputChannel inputChannel = w.mInputChannel;
-            final InputWindowHandle inputWindowHandle = w.mInputWindowHandle;
+            final InputWindowHandleWrapper inputWindowHandle = w.mInputWindowHandle;
             final RecentsAnimationController recentsAnimationController =
                     mService.getRecentsAnimationController();
             final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null
                     && recentsAnimationController.shouldApplyInputConsumer(w.mActivityRecord);
-            final int type = w.mAttrs.type;
-            final boolean isVisible = w.isVisibleLw();
-            if (inputChannel == null || inputWindowHandle == null || w.mRemoved
+            if (w.mInputChannelToken == null || w.mRemoved
                     || (!w.canReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) {
                 if (w.mWinAnimator.hasSurface()) {
                     // Assign an InputInfo with type to the overlay window which can't receive input
                     // event. This is used to omit Surfaces from occlusion detection.
-                    populateOverlayInputInfo(mInvalidInputWindow, w.getName(), type, isVisible);
-                    mInputTransaction.setInputWindowInfo(
-                            w.mWinAnimator.mSurfaceController.mSurfaceControl,
-                            mInvalidInputWindow);
+                    populateOverlayInputInfo(inputWindowHandle, w.isVisible());
+                    setInputWindowInfoIfNeeded(mInputTransaction,
+                            w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);
                     return;
                 }
                 // Skip this window because it cannot possibly receive input.
                 return;
             }
 
-            final int flags = w.mAttrs.flags;
             final int privateFlags = w.mAttrs.privateFlags;
-            final boolean focusable = w.canReceiveKeys()
-                    && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());
 
             if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
                 if (recentsAnimationController.updateInputConsumerForApp(
@@ -584,47 +566,53 @@
             if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) {
                 mDisableWallpaperTouchEvents = true;
             }
-            final boolean hasWallpaper = mWallpaperController.isWallpaperTarget(w)
-                    && !mService.mPolicy.isKeyguardShowing()
-                    && !mDisableWallpaperTouchEvents;
 
             // If there's a drag in progress and 'child' is a potential drop target,
             // make sure it's been told about the drag
-            if (mInDrag && isVisible && w.getDisplayContent().isDefaultDisplay) {
+            if (mInDrag && w.isVisible() && w.getDisplayContent().isDefaultDisplay) {
                 mService.mDragDropController.sendDragStartedIfNeededLocked(w);
             }
 
-            populateInputWindowHandle(
-                    inputWindowHandle, w, flags, type, isVisible, focusable, hasWallpaper);
-
             // register key interception info
-            mService.mKeyInterceptionInfoForToken.put(inputWindowHandle.token,
+            mService.mKeyInterceptionInfoForToken.put(w.mInputChannelToken,
                     w.getKeyInterceptionInfo());
 
             if (w.mWinAnimator.hasSurface()) {
-                mInputTransaction.setInputWindowInfo(
+                populateInputWindowHandle(inputWindowHandle, w);
+                setInputWindowInfoIfNeeded(mInputTransaction,
                         w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);
             }
         }
     }
 
+    @VisibleForTesting
+    static void setInputWindowInfoIfNeeded(SurfaceControl.Transaction t, SurfaceControl sc,
+            InputWindowHandleWrapper inputWindowHandle) {
+        if (DEBUG_INPUT) {
+            Slog.d(TAG_WM, "Update InputWindowHandle: " + inputWindowHandle);
+        }
+        if (inputWindowHandle.isChanged()) {
+            inputWindowHandle.applyChangesToSurface(t, sc);
+        }
+    }
+
     // This would reset InputWindowHandle fields to prevent it could be found by input event.
     // We need to check if any new field of InputWindowHandle could impact the result.
-    private static void populateOverlayInputInfo(final InputWindowHandle inputWindowHandle,
-            final String name, final int type, final boolean isVisible) {
-        inputWindowHandle.name = name;
-        inputWindowHandle.layoutParamsType = type;
-        inputWindowHandle.dispatchingTimeoutMillis = 0; // it should never receive input
-        inputWindowHandle.visible = isVisible;
-        inputWindowHandle.focusable = false;
-        inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL;
-        inputWindowHandle.scaleFactor = 1;
-        inputWindowHandle.layoutParamsFlags =
-                FLAG_NOT_TOUCH_MODAL | FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE;
-        inputWindowHandle.portalToDisplayId = INVALID_DISPLAY;
-        inputWindowHandle.touchableRegion.setEmpty();
+    @VisibleForTesting
+    static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle,
+            boolean isVisible) {
+        inputWindowHandle.setDispatchingTimeoutMillis(0); // It should never receive input.
+        inputWindowHandle.setVisible(isVisible);
+        inputWindowHandle.setFocusable(false);
+        inputWindowHandle.setInputFeatures(INPUT_FEATURE_NO_INPUT_CHANNEL);
+        // The input window handle without input channel must not have a token.
+        inputWindowHandle.setToken(null);
+        inputWindowHandle.setScaleFactor(1f);
+        inputWindowHandle.setLayoutParamsFlags(
+                FLAG_NOT_TOUCH_MODAL | FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE);
+        inputWindowHandle.setPortalToDisplayId(INVALID_DISPLAY);
+        inputWindowHandle.clearTouchableRegion();
         inputWindowHandle.setTouchableRegionCrop(null);
-        inputWindowHandle.trustedOverlay = isTrustedOverlay(type);
     }
 
     /**
@@ -635,9 +623,13 @@
      */
     static void setTrustedOverlayInputInfo(SurfaceControl sc, SurfaceControl.Transaction t,
             int displayId, String name) {
-        InputWindowHandle inputWindowHandle = new InputWindowHandle(null, displayId);
-        populateOverlayInputInfo(inputWindowHandle, name, TYPE_SECURE_SYSTEM_OVERLAY, true);
-        t.setInputWindowInfo(sc, inputWindowHandle);
+        final InputWindowHandleWrapper inputWindowHandle = new InputWindowHandleWrapper(
+                new InputWindowHandle(null /* inputApplicationHandle */, displayId));
+        inputWindowHandle.setName(name);
+        inputWindowHandle.setLayoutParamsType(TYPE_SECURE_SYSTEM_OVERLAY);
+        inputWindowHandle.setTrustedOverlay(true);
+        populateOverlayInputInfo(inputWindowHandle, true /* isVisible */);
+        setInputWindowInfoIfNeeded(t, sc, inputWindowHandle);
     }
 
     static boolean isTrustedOverlay(int type) {
diff --git a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
new file mode 100644
index 0000000..9339f34
--- /dev/null
+++ b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+package com.android.server.wm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.view.InputApplicationHandle;
+import android.view.InputWindowHandle;
+import android.view.SurfaceControl;
+
+import java.util.Objects;
+
+/**
+ * The wrapper of {@link InputWindowHandle} with field change detection to reduce unnecessary
+ * updates to surface, e.g. if there are no changes, then skip invocation of
+ * {@link SurfaceControl.Transaction#setInputWindowInfo(SurfaceControl, InputWindowHandle)}.
+ */
+class InputWindowHandleWrapper {
+    /** The wrapped handle should not be directly exposed to avoid untracked changes. */
+    private final @NonNull InputWindowHandle mHandle;
+
+    /** Whether the {@link #mHandle} is changed. */
+    private boolean mChanged = true;
+
+    InputWindowHandleWrapper(@NonNull InputWindowHandle handle) {
+        mHandle = handle;
+    }
+
+    /**
+     * Returns {@code true} if the input window handle has changed since the last invocation of
+     * {@link #applyChangesToSurface(SurfaceControl.Transaction, SurfaceControl)}}
+     */
+    boolean isChanged() {
+        return mChanged;
+    }
+
+    void forceChange() {
+        mChanged = true;
+    }
+
+    void applyChangesToSurface(@NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl sc) {
+        t.setInputWindowInfo(sc, mHandle);
+        mChanged = false;
+    }
+
+    int getDisplayId() {
+        return mHandle.displayId;
+    }
+
+    InputApplicationHandle getInputApplicationHandle() {
+        return mHandle.inputApplicationHandle;
+    }
+
+    void setInputApplicationHandle(InputApplicationHandle handle) {
+        if (mHandle.inputApplicationHandle == handle) {
+            return;
+        }
+        mHandle.inputApplicationHandle = handle;
+        mChanged = true;
+    }
+
+    void setToken(IBinder token) {
+        if (mHandle.token == token) {
+            return;
+        }
+        mHandle.token = token;
+        mChanged = true;
+    }
+
+    void setName(String name) {
+        if (Objects.equals(mHandle.name, name)) {
+            return;
+        }
+        mHandle.name = name;
+        mChanged = true;
+    }
+
+    void setLayoutParamsFlags(int flags) {
+        if (mHandle.layoutParamsFlags == flags) {
+            return;
+        }
+        mHandle.layoutParamsFlags = flags;
+        mChanged = true;
+    }
+
+    void setLayoutParamsType(int type) {
+        if (mHandle.layoutParamsType == type) {
+            return;
+        }
+        mHandle.layoutParamsType = type;
+        mChanged = true;
+    }
+
+    void setDispatchingTimeoutMillis(long timeout) {
+        if (mHandle.dispatchingTimeoutMillis == timeout) {
+            return;
+        }
+        mHandle.dispatchingTimeoutMillis = timeout;
+        mChanged = true;
+    }
+
+    void setTouchableRegion(Region region) {
+        if (mHandle.touchableRegion.equals(region)) {
+            return;
+        }
+        mHandle.touchableRegion.set(region);
+        mChanged = true;
+    }
+
+    void clearTouchableRegion() {
+        if (mHandle.touchableRegion.isEmpty()) {
+            return;
+        }
+        mHandle.touchableRegion.setEmpty();
+        mChanged = true;
+    }
+
+    void setVisible(boolean visible) {
+        if (mHandle.visible == visible) {
+            return;
+        }
+        mHandle.visible = visible;
+        mChanged = true;
+    }
+
+    void setFocusable(boolean focusable) {
+        if (mHandle.focusable == focusable) {
+            return;
+        }
+        mHandle.focusable = focusable;
+        mChanged = true;
+    }
+
+    void setTouchOcclusionMode(int mode) {
+        if (mHandle.touchOcclusionMode == mode) {
+            return;
+        }
+        mHandle.touchOcclusionMode = mode;
+        mChanged = true;
+    }
+
+    void setHasWallpaper(boolean hasWallpaper) {
+        if (mHandle.hasWallpaper == hasWallpaper) {
+            return;
+        }
+        mHandle.hasWallpaper = hasWallpaper;
+        mChanged = true;
+    }
+
+    void setPaused(boolean paused) {
+        if (mHandle.paused == paused) {
+            return;
+        }
+        mHandle.paused = paused;
+        mChanged = true;
+    }
+
+    void setTrustedOverlay(boolean trustedOverlay) {
+        if (mHandle.trustedOverlay == trustedOverlay) {
+            return;
+        }
+        mHandle.trustedOverlay = trustedOverlay;
+        mChanged = true;
+    }
+
+    void setOwnerPid(int pid) {
+        if (mHandle.ownerPid == pid) {
+            return;
+        }
+        mHandle.ownerPid = pid;
+        mChanged = true;
+    }
+
+    void setOwnerUid(int uid) {
+        if (mHandle.ownerUid == uid) {
+            return;
+        }
+        mHandle.ownerUid = uid;
+        mChanged = true;
+    }
+
+    void setPackageName(String packageName) {
+        if (Objects.equals(mHandle.packageName, packageName)) {
+            return;
+        }
+        mHandle.packageName = packageName;
+        mChanged = true;
+    }
+
+    void setInputFeatures(int features) {
+        if (mHandle.inputFeatures == features) {
+            return;
+        }
+        mHandle.inputFeatures = features;
+        mChanged = true;
+    }
+
+    void setDisplayId(int displayId) {
+        if (mHandle.displayId == displayId) {
+            return;
+        }
+        mHandle.displayId = displayId;
+        mChanged = true;
+    }
+
+    void setPortalToDisplayId(int displayId) {
+        if (mHandle.portalToDisplayId == displayId) {
+            return;
+        }
+        mHandle.portalToDisplayId = displayId;
+        mChanged = true;
+    }
+
+    void setFrame(int left, int top, int right, int bottom) {
+        if (mHandle.frameLeft == left && mHandle.frameTop == top && mHandle.frameRight == right
+                && mHandle.frameBottom == bottom) {
+            return;
+        }
+        mHandle.frameLeft = left;
+        mHandle.frameTop = top;
+        mHandle.frameRight = right;
+        mHandle.frameBottom = bottom;
+        mChanged = true;
+    }
+
+    void setSurfaceInset(int inset) {
+        if (mHandle.surfaceInset == inset) {
+            return;
+        }
+        mHandle.surfaceInset = inset;
+        mChanged = true;
+    }
+
+    void setScaleFactor(float scale) {
+        if (mHandle.scaleFactor == scale) {
+            return;
+        }
+        mHandle.scaleFactor = scale;
+        mChanged = true;
+    }
+
+    void setTouchableRegionCrop(@Nullable SurfaceControl bounds) {
+        if (mHandle.touchableRegionSurfaceControl.get() == bounds) {
+            return;
+        }
+        mHandle.setTouchableRegionCrop(bounds);
+        mChanged = true;
+    }
+
+    void setReplaceTouchableRegionWithCrop(boolean replace) {
+        if (mHandle.replaceTouchableRegionWithCrop == replace) {
+            return;
+        }
+        mHandle.replaceTouchableRegionWithCrop = replace;
+        mChanged = true;
+    }
+
+    @Override
+    public String toString() {
+        return mHandle + ", changed=" + mChanged;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index e7f140f..773bf54 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -18,6 +18,7 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.InsetsState.ITYPE_CAPTION_BAR;
 import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
 import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
@@ -35,6 +36,7 @@
 import android.annotation.Nullable;
 import android.app.WindowConfiguration;
 import android.app.WindowConfiguration.WindowingMode;
+import android.os.Trace;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.SparseArray;
@@ -281,6 +283,7 @@
      * Called when a layout pass has occurred.
      */
     void onPostLayout() {
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "ISC.onPostLayout");
         for (int i = mProviders.size() - 1; i >= 0; i--) {
             mProviders.valueAt(i).onPostLayout();
         }
@@ -297,6 +300,7 @@
             }
         }
         winInsetsChanged.clear();
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
 
     void onInsetsModified(InsetsControlTarget caller) {
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 79b88d8..de2164d 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -167,7 +167,8 @@
 
         if (keyguardChanged) {
             // Irrelevant to AOD.
-            dismissMultiWindowModeForTaskIfNeeded(null /* currentTaskControllsingOcclusion */);
+            dismissMultiWindowModeForTaskIfNeeded(null /* currentTaskControllsingOcclusion */,
+                    false /* turningScreenOn */);
             setKeyguardGoingAway(false);
             if (keyguardShowing) {
                 mDismissalRequested = false;
@@ -369,7 +370,6 @@
                 mService.continueWindowLayout();
             }
         }
-        dismissMultiWindowModeForTaskIfNeeded(currentTaskControllingOcclusion);
     }
 
     /**
@@ -398,6 +398,21 @@
         }
     }
 
+    /**
+     * Called when somebody wants to turn screen on.
+     */
+    private void handleTurnScreenOn(int displayId) {
+        if (displayId != DEFAULT_DISPLAY) {
+            return;
+        }
+
+        mStackSupervisor.wakeUp("handleTurnScreenOn");
+        if (mKeyguardShowing && canDismissKeyguard()) {
+            mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
+            mDismissalRequested = true;
+        }
+    }
+
     boolean isDisplayOccluded(int displayId) {
         return getDisplayState(displayId).mOccluded;
     }
@@ -433,14 +448,15 @@
     }
 
     private void dismissMultiWindowModeForTaskIfNeeded(
-            @Nullable Task currentTaskControllingOcclusion) {
+            @Nullable Task currentTaskControllingOcclusion, boolean turningScreenOn) {
+        // If turningScreenOn is true, it means that the visibility state has changed from
+        // currentTaskControllingOcclusion and we should update windowing mode.
         // TODO(b/113840485): Handle docked stack for individual display.
-        if (!mKeyguardShowing || !isDisplayOccluded(DEFAULT_DISPLAY)) {
+        if (!turningScreenOn && (!mKeyguardShowing || !isDisplayOccluded(DEFAULT_DISPLAY))) {
             return;
         }
 
         // Dismiss split screen
-
         // The lock screen is currently showing, but is occluded by a window that can
         // show on top of the lock screen. In this can we want to dismiss the docked
         // stack since it will be complicated/risky to try to put the activity on top
@@ -579,17 +595,26 @@
                     && controller.mWindowManager.isKeyguardSecure(
                     controller.mService.getCurrentUserId());
 
+            boolean occludingChange = false;
+            boolean turningScreenOn = false;
             if (mTopTurnScreenOnActivity != lastTurnScreenOnActivity
                     && mTopTurnScreenOnActivity != null
                     && !mService.mWindowManager.mPowerManager.isInteractive()
-                    && (mRequestDismissKeyguard || occludedByActivity)) {
-                controller.mStackSupervisor.wakeUp("handleTurnScreenOn");
+                    && (mRequestDismissKeyguard || occludedByActivity
+                        || controller.canDismissKeyguard())) {
+                turningScreenOn = true;
+                controller.handleTurnScreenOn(mDisplayId);
                 mTopTurnScreenOnActivity.setCurrentLaunchCanTurnScreenOn(false);
             }
 
             if (lastOccluded != mOccluded) {
+                occludingChange = true;
                 controller.handleOccludedChanged(mDisplayId, task);
             }
+
+            if (occludingChange || turningScreenOn) {
+                controller.dismissMultiWindowModeForTaskIfNeeded(task, turningScreenOn);
+            }
         }
 
         /**
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index b33c2f2..5b7b5a1 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -24,6 +24,8 @@
 import static android.content.Context.STATUS_BAR_SERVICE;
 import static android.content.Intent.ACTION_CALL_EMERGENCY;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
+import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
 import static android.os.UserHandle.USER_ALL;
 import static android.os.UserHandle.USER_CURRENT;
@@ -33,11 +35,6 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_ALLOWLISTED;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_DONT_LOCK;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
-import static com.android.server.wm.Task.LOCK_TASK_AUTH_PINNABLE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -129,6 +126,18 @@
     /** Tag used for disabling of keyguard */
     private static final String LOCK_TASK_TAG = "Lock-to-App";
 
+    /** Can't be put in lockTask mode. */
+    static final int LOCK_TASK_AUTH_DONT_LOCK = 0;
+    /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
+    static final int LOCK_TASK_AUTH_PINNABLE = 1;
+    /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
+    static final int LOCK_TASK_AUTH_LAUNCHABLE = 2;
+    /** Can enter lockTask without user approval. Can start over existing lockTask task. */
+    static final int LOCK_TASK_AUTH_ALLOWLISTED = 3;
+    /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
+     * lockTask task. */
+    static final int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
+
     private final IBinder mToken = new LockTaskToken();
     private final ActivityStackSupervisor mSupervisor;
     private final Context mContext;
@@ -265,11 +274,10 @@
     }
 
     /**
-     * @return whether the requested task is allowed to be locked (either allowlisted, or declares
-     * lockTaskMode="always" in the manifest).
+     * @return whether the requested task auth is allowed to be locked.
      */
-    boolean isTaskAllowlisted(Task task) {
-        switch(task.mLockTaskAuth) {
+    static boolean isTaskAuthAllowlisted(int lockTaskAuth) {
+        switch(lockTaskAuth) {
             case LOCK_TASK_AUTH_ALLOWLISTED:
             case LOCK_TASK_AUTH_LAUNCHABLE:
             case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
@@ -293,7 +301,30 @@
      * @return whether the requested task is disallowed to be launched.
      */
     boolean isLockTaskModeViolation(Task task, boolean isNewClearTask) {
-        if (isLockTaskModeViolationInternal(task, isNewClearTask)) {
+        // TODO: Double check what's going on here. If the task is already in lock task mode, it's
+        // likely allowlisted, so will return false below.
+        if (isTaskLocked(task) && !isNewClearTask) {
+            // If the task is already at the top and won't be cleared, then allow the operation
+        } else if (isLockTaskModeViolationInternal(task, task.mUserId, task.intent,
+                task.mLockTaskAuth)) {
+            showLockTaskToast();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @param activity an activity that is going to be started in a new task as the root activity.
+     * @return whether the given activity is allowed to be launched.
+     */
+    boolean isNewTaskLockTaskModeViolation(ActivityRecord activity) {
+        // Use the belong task (if any) to perform the lock task checks
+        if (activity.getTask() != null) {
+            return isLockTaskModeViolation(activity.getTask());
+        }
+
+        int auth = getLockTaskAuth(activity, null /* task */);
+        if (isLockTaskModeViolationInternal(activity, activity.mUserId, activity.intent, auth)) {
             showLockTaskToast();
             return true;
         }
@@ -310,25 +341,19 @@
         return mLockTaskModeTasks.get(0);
     }
 
-    private boolean isLockTaskModeViolationInternal(Task task, boolean isNewClearTask) {
-        // TODO: Double check what's going on here. If the task is already in lock task mode, it's
-        // likely allowlisted, so will return false below.
-        if (isTaskLocked(task) && !isNewClearTask) {
-            // If the task is already at the top and won't be cleared, then allow the operation
-            return false;
-        }
-
+    private boolean isLockTaskModeViolationInternal(WindowContainer wc, int userId,
+            Intent intent, int taskAuth) {
         // Allow recents activity if enabled by policy
-        if (task.isActivityTypeRecents() && isRecentsAllowed(task.mUserId)) {
+        if (wc.isActivityTypeRecents() && isRecentsAllowed(userId)) {
             return false;
         }
 
         // Allow emergency calling when the device is protected by a locked keyguard
-        if (isKeyguardAllowed(task.mUserId) && isEmergencyCallTask(task)) {
+        if (isKeyguardAllowed(userId) && isEmergencyCallIntent(intent)) {
             return false;
         }
 
-        return !(isTaskAllowlisted(task) || mLockTaskModeTasks.isEmpty());
+        return !(isTaskAuthAllowlisted(taskAuth) || mLockTaskModeTasks.isEmpty());
     }
 
     private boolean isRecentsAllowed(int userId) {
@@ -360,8 +385,7 @@
         return isPackageAllowlisted(userId, packageName);
     }
 
-    private boolean isEmergencyCallTask(Task task) {
-        final Intent intent = task.intent;
+    private boolean isEmergencyCallIntent(Intent intent) {
         if (intent == null) {
             return false;
         }
@@ -697,6 +721,40 @@
         }
     }
 
+    int getLockTaskAuth(@Nullable ActivityRecord rootActivity, @Nullable Task task) {
+        if (rootActivity == null && task == null) {
+            return LOCK_TASK_AUTH_DONT_LOCK;
+        }
+        if (rootActivity == null) {
+            return LOCK_TASK_AUTH_PINNABLE;
+        }
+
+        final String pkg = (task == null || task.realActivity == null) ? null
+                : task.realActivity.getPackageName();
+        final int userId = task != null ? task.mUserId : rootActivity.mUserId;
+        int lockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
+        switch (rootActivity.lockTaskLaunchMode) {
+            case LOCK_TASK_LAUNCH_MODE_DEFAULT:
+                lockTaskAuth = isPackageAllowlisted(userId, pkg)
+                        ? LOCK_TASK_AUTH_ALLOWLISTED : LOCK_TASK_AUTH_PINNABLE;
+                break;
+
+            case LOCK_TASK_LAUNCH_MODE_NEVER:
+                lockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
+                break;
+
+            case LOCK_TASK_LAUNCH_MODE_ALWAYS:
+                lockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
+                break;
+
+            case LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED:
+                lockTaskAuth = isPackageAllowlisted(userId, pkg)
+                        ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
+                break;
+        }
+        return lockTaskAuth;
+    }
+
     boolean isPackageAllowlisted(int userId, String pkg) {
         if (pkg == null) {
             return false;
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 0503c0d..45cd359 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -658,8 +658,8 @@
         }
         for (int i = mTasks.size() - 1; i >= 0; --i) {
             final Task task = mTasks.get(i);
-            if (task.mUserId == userId
-                    && !mService.getLockTaskController().isTaskAllowlisted(task)) {
+            if (task.mUserId == userId && !mService.getLockTaskController().isTaskAuthAllowlisted(
+                    task.mLockTaskAuth)) {
                 remove(task);
             }
         }
@@ -1874,11 +1874,23 @@
      * Creates a new RecentTaskInfo from a Task.
      */
     ActivityManager.RecentTaskInfo createRecentTaskInfo(Task tr, boolean stripExtras) {
-        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
+        final ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
         tr.fillTaskInfo(rti, stripExtras);
-        // Fill in some deprecated values
+        // Fill in some deprecated values.
         rti.id = rti.isRunning ? rti.taskId : INVALID_TASK_ID;
         rti.persistentId = rti.taskId;
+
+        // Fill in organized child task info for the task created by organizer.
+        if (tr.mCreatedByOrganizer) {
+            for (int i = tr.getChildCount() - 1; i >= 0; i--) {
+                final Task childTask = tr.getChildAt(i).asTask();
+                if (childTask != null && childTask.isOrganized()) {
+                    final ActivityManager.RecentTaskInfo cti = new ActivityManager.RecentTaskInfo();
+                    childTask.fillTaskInfo(cti);
+                    rti.childrenTaskInfos.add(cti);
+                }
+            }
+        }
         return rti;
     }
 
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 04b3030..2749cc9 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -59,7 +59,7 @@
 import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
@@ -76,9 +76,9 @@
 import static com.android.server.wm.Task.ActivityState.RESUMED;
 import static com.android.server.wm.Task.ActivityState.STOPPED;
 import static com.android.server.wm.Task.ActivityState.STOPPING;
-import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
-import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
-import static com.android.server.wm.Task.STACK_VISIBILITY_INVISIBLE;
+import static com.android.server.wm.Task.REPARENT_LEAVE_ROOT_TASK_IN_PLACE;
+import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT;
+import static com.android.server.wm.Task.TASK_VISIBILITY_INVISIBLE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
@@ -232,20 +232,19 @@
      */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
-            MATCH_TASK_IN_STACKS_ONLY,
-            MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
-            MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
+            MATCH_ATTACHED_TASK_ONLY,
+            MATCH_ATTACHED_TASK_OR_RECENT_TASKS,
+            MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE
     })
     public @interface AnyTaskForIdMatchTaskMode {
     }
 
-    // Match only tasks in the current stacks
-    static final int MATCH_TASK_IN_STACKS_ONLY = 0;
-    // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
-    static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
-    // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
-    // provided stack id
-    static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
+    // Match only tasks that are attached to the hierarchy
+    static final int MATCH_ATTACHED_TASK_ONLY = 0;
+    // Match either attached tasks, or in the recent tasks if the tasks are detached
+    static final int MATCH_ATTACHED_TASK_OR_RECENT_TASKS = 1;
+    // Match either attached tasks, or in the recent tasks, restoring it to the provided task id
+    static final int MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE = 2;
 
     ActivityTaskManagerService mService;
     ActivityStackSupervisor mStackSupervisor;
@@ -1953,7 +1952,7 @@
 
                 for (int taskNdx = displayArea.getStackCount() - 1; taskNdx >= 0; --taskNdx) {
                     final Task rootTask = displayArea.getStackAt(taskNdx);
-                    if (rootTask.getVisibility(null /*starting*/) == STACK_VISIBILITY_INVISIBLE) {
+                    if (rootTask.getVisibility(null /*starting*/) == TASK_VISIBILITY_INVISIBLE) {
                         break;
                     }
 
@@ -2556,7 +2555,7 @@
 
     @Override
     public void onDisplayAdded(int displayId) {
-        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
+        if (DEBUG_ROOT_TASK) Slog.v(TAG, "Display added displayId=" + displayId);
         synchronized (mService.mGlobalLock) {
             final DisplayContent display = getDisplayContentOrCreate(displayId);
             if (display == null) {
@@ -2578,7 +2577,7 @@
 
     @Override
     public void onDisplayRemoved(int displayId) {
-        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
+        if (DEBUG_ROOT_TASK) Slog.v(TAG, "Display removed displayId=" + displayId);
         if (displayId == DEFAULT_DISPLAY) {
             throw new IllegalArgumentException("Can't remove the primary display.");
         }
@@ -2595,7 +2594,7 @@
 
     @Override
     public void onDisplayChanged(int displayId) {
-        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
+        if (DEBUG_ROOT_TASK) Slog.v(TAG, "Display changed displayId=" + displayId);
         synchronized (mService.mGlobalLock) {
             final DisplayContent displayContent = getDisplayContent(displayId);
             if (displayContent != null) {
@@ -2728,8 +2727,7 @@
         }, true /* traverseTopToBottom */);
 
         for (int i = mTmpTaskLayerChangedProcs.size() - 1; i >= 0; i--) {
-            mTmpTaskLayerChangedProcs.valueAt(i).invalidateOomScoreReferenceState(
-                    true /* computeNow */);
+            mTmpTaskLayerChangedProcs.valueAt(i).computeProcessActivityState();
         }
         mTmpTaskLayerChangedProcs.clear();
     }
@@ -2889,7 +2887,7 @@
             // Temporarily set the task id to invalid in case in re-entry.
             options.setLaunchTaskId(INVALID_TASK_ID);
             final Task task = anyTaskForId(taskId,
-                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
+                    MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
             options.setLaunchTaskId(taskId);
             if (task != null) {
                 return task.getRootTask();
@@ -3445,7 +3443,7 @@
     }
 
     Task anyTaskForId(int id) {
-        return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE);
+        return anyTaskForId(id, MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE);
     }
 
     Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode) {
@@ -3463,7 +3461,7 @@
     Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode,
             @Nullable ActivityOptions aOptions, boolean onTop) {
         // If options are set, ensure that we are attempting to actually restore a task
-        if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
+        if (matchMode != MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) {
             throw new IllegalArgumentException("Should not specify activity options for non-restore"
                     + " lookup");
         }
@@ -3481,7 +3479,7 @@
                         getLaunchStack(null, aOptions, task, onTop);
                 if (launchStack != null && task.getRootTask() != launchStack) {
                     final int reparentMode = onTop
-                            ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
+                            ? REPARENT_MOVE_ROOT_TASK_TO_FRONT : REPARENT_LEAVE_ROOT_TASK_IN_PLACE;
                     task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
                             "anyTaskForId");
                 }
@@ -3490,7 +3488,7 @@
         }
 
         // If we are matching stack tasks only, return now
-        if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
+        if (matchMode == MATCH_ATTACHED_TASK_ONLY) {
             return null;
         }
 
@@ -3507,11 +3505,11 @@
             return null;
         }
 
-        if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
+        if (matchMode == MATCH_ATTACHED_TASK_OR_RECENT_TASKS) {
             return task;
         }
 
-        // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
+        // Implicitly, this case is MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE
         if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) {
             if (DEBUG_RECENTS) {
                 Slog.w(TAG_RECENTS,
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 6fbd351..b46e796 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -24,6 +24,7 @@
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
 import static android.content.Intent.EXTRA_SHORTCUT_ID;
 import static android.content.Intent.EXTRA_TASK_ID;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -43,6 +44,7 @@
 import android.content.ClipDescription;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ShortcutServiceInternal;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -288,7 +290,8 @@
     public IBinder performDrag(IWindow window, int flags, SurfaceControl surface, int touchSource,
             float touchX, float touchY, float thumbCenterX, float thumbCenterY, ClipData data) {
         // Validate and resolve ClipDescription data before clearing the calling identity
-        validateAndResolveDragMimeTypeExtras(data, Binder.getCallingUid());
+        validateAndResolveDragMimeTypeExtras(data, Binder.getCallingUid(), Binder.getCallingPid(),
+                mPackageName);
         final long ident = Binder.clearCallingIdentity();
         try {
             return mDragDropController.performDrag(mPid, mUid, window, flags, surface, touchSource,
@@ -302,8 +305,9 @@
      * Validates the given drag data.
      */
     @VisibleForTesting
-    public void validateAndResolveDragMimeTypeExtras(ClipData data, int callingUid) {
-        if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+    void validateAndResolveDragMimeTypeExtras(ClipData data, int callingUid, int callingPid,
+            String callingPackage) {
+        if (callingUid == Process.SYSTEM_UID) {
             throw new IllegalStateException("Need to validate before calling identify is cleared");
         }
         final ClipDescription desc = data != null ? data.getDescription() : null;
@@ -358,26 +362,58 @@
                 Binder.restoreCallingIdentity(origId);
             }
         } else if (hasShortcut) {
+            // Restrict who can start a shortcut drag since it will start the shortcut as the
+            // target shortcut package
             mService.mAtmService.enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
                     "performDrag");
             for (int i = 0; i < data.getItemCount(); i++) {
-                final Intent intent = data.getItemAt(i).getIntent();
+                final ClipData.Item item = data.getItemAt(i);
+                final Intent intent = item.getIntent();
+                final String shortcutId = intent.getStringExtra(EXTRA_SHORTCUT_ID);
+                final String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
                 final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
-                if (!intent.hasExtra(EXTRA_SHORTCUT_ID)
-                        || TextUtils.isEmpty(intent.getStringExtra(EXTRA_SHORTCUT_ID))
+                if (TextUtils.isEmpty(shortcutId)
+                        || TextUtils.isEmpty(packageName)
                         || user == null) {
-                    throw new IllegalArgumentException("Clip item must include the shortcut id and "
-                            + "the user to launch for.");
+                    throw new IllegalArgumentException("Clip item must include the package name, "
+                            + "shortcut id, and the user to launch for.");
                 }
+                final ShortcutServiceInternal shortcutService =
+                        LocalServices.getService(ShortcutServiceInternal.class);
+                final Intent[] shortcutIntents = shortcutService.createShortcutIntents(
+                        callingUid, callingPackage, packageName, shortcutId,
+                        user.getIdentifier(), callingPid, callingUid);
+                if (shortcutIntents == null || shortcutIntents.length == 0) {
+                    throw new IllegalArgumentException("Invalid shortcut id");
+                }
+                final ActivityInfo info = mService.mAtmService.resolveActivityInfoForIntent(
+                        shortcutIntents[0], null /* resolvedType */, user.getIdentifier(),
+                        callingUid);
+                item.setActivityInfo(info);
             }
         } else if (hasTask) {
+            // TODO(b/169894807): Consider opening this up for tasks from the same app as the caller
             mService.mAtmService.enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
                     "performDrag");
             for (int i = 0; i < data.getItemCount(); i++) {
-                final Intent intent = data.getItemAt(i).getIntent();
-                if (intent.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID) == INVALID_TASK_ID) {
+                final ClipData.Item item = data.getItemAt(i);
+                final Intent intent = item.getIntent();
+                final int taskId = intent.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID);
+                if (taskId == INVALID_TASK_ID) {
                     throw new IllegalArgumentException("Clip item must include the task id.");
                 }
+                final Task task = mService.mRoot.anyTaskForId(taskId);
+                if (task == null) {
+                    throw new IllegalArgumentException("Invalid task id.");
+                }
+                if (task.getRootActivity() != null) {
+                    item.setActivityInfo(task.getRootActivity().info);
+                } else {
+                    // Resolve the activity info manually if the task was restored after reboot
+                    final ActivityInfo info = mService.mAtmService.resolveActivityInfoForIntent(
+                            task.intent, null /* resolvedType */, task.mUserId, callingUid);
+                    item.setActivityInfo(info);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 9273bf7..0b2ba87 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -43,10 +43,6 @@
 import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
-import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
-import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
-import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED;
-import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
@@ -107,7 +103,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
@@ -120,6 +116,11 @@
 import static com.android.server.wm.IdentifierProto.HASH_CODE;
 import static com.android.server.wm.IdentifierProto.TITLE;
 import static com.android.server.wm.IdentifierProto.USER_ID;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_ALLOWLISTED;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_DONT_LOCK;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_PINNABLE;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 import static com.android.server.wm.Task.ActivityState.PAUSED;
 import static com.android.server.wm.Task.ActivityState.PAUSING;
@@ -145,7 +146,7 @@
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowContainerChildProto.TASK;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.MIN_TASK_LETTERBOX_ASPECT_RATIO;
@@ -251,7 +252,7 @@
     static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
     private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
     private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
-    private static final String TAG_STACK = TAG + POSTFIX_STACK;
+    private static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK;
     private static final String TAG_STATES = TAG + POSTFIX_STATES;
     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
     private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
@@ -308,38 +309,37 @@
     private float mShadowRadius = 0;
 
     /**
-     * The modes to control how the stack is moved to the front when calling {@link Task#reparent}.
+     * The modes to control how root task is moved to the front when calling {@link Task#reparent}.
      */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
-            REPARENT_MOVE_STACK_TO_FRONT,
-            REPARENT_KEEP_STACK_AT_FRONT,
-            REPARENT_LEAVE_STACK_IN_PLACE
+            REPARENT_MOVE_ROOT_TASK_TO_FRONT,
+            REPARENT_KEEP_ROOT_TASK_AT_FRONT,
+            REPARENT_LEAVE_ROOT_TASK_IN_PLACE
     })
-    @interface ReparentMoveStackMode {}
-    // Moves the stack to the front if it was not at the front
-    static final int REPARENT_MOVE_STACK_TO_FRONT = 0;
-    // Only moves the stack to the front if it was focused or front most already
-    static final int REPARENT_KEEP_STACK_AT_FRONT = 1;
-    // Do not move the stack as a part of reparenting
-    static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
+    @interface ReparentMoveRootTaskMode {}
+    // Moves the root task to the front if it was not at the front
+    static final int REPARENT_MOVE_ROOT_TASK_TO_FRONT = 0;
+    // Only moves the root task to the front if it was focused or front most already
+    static final int REPARENT_KEEP_ROOT_TASK_AT_FRONT = 1;
+    // Do not move the root task as a part of reparenting
+    static final int REPARENT_LEAVE_ROOT_TASK_IN_PLACE = 2;
 
-    // TODO (b/157876447): switch to Task related name
-    @IntDef(prefix = {"STACK_VISIBILITY"}, value = {
-            STACK_VISIBILITY_VISIBLE,
-            STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
-            STACK_VISIBILITY_INVISIBLE,
+    @IntDef(prefix = {"TASK_VISIBILITY"}, value = {
+            TASK_VISIBILITY_VISIBLE,
+            TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+            TASK_VISIBILITY_INVISIBLE,
     })
-    @interface StackVisibility {}
+    @interface TaskVisibility {}
 
-    /** Stack is visible. No other stacks on top that fully or partially occlude it. */
-    static final int STACK_VISIBILITY_VISIBLE = 0;
+    /** Task is visible. No other tasks on top that fully or partially occlude it. */
+    static final int TASK_VISIBILITY_VISIBLE = 0;
 
-    /** Stack is partially occluded by other translucent stack(s) on top of it. */
-    static final int STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT = 1;
+    /** Task is partially occluded by other translucent task(s) on top of it. */
+    static final int TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT = 1;
 
-    /** Stack is completely invisible. */
-    static final int STACK_VISIBILITY_INVISIBLE = 2;
+    /** Task is completely invisible. */
+    static final int TASK_VISIBILITY_INVISIBLE = 2;
 
     enum ActivityState {
         INITIALIZING,
@@ -407,17 +407,6 @@
     boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
                                 // was changed.
 
-    /** Can't be put in lockTask mode. */
-    final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
-    /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
-    final static int LOCK_TASK_AUTH_PINNABLE = 1;
-    /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
-    final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
-    /** Can enter lockTask without user approval. Can start over existing lockTask task. */
-    final static int LOCK_TASK_AUTH_ALLOWLISTED = 3;
-    /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing
-     * lockTask task. */
-    final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4;
     int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
 
     int mLockTaskUid = -1;  // The uid of the application that called startLockTask().
@@ -582,6 +571,10 @@
     /** Current activity that is resumed, or null if there is none. */
     ActivityRecord mResumedActivity = null;
 
+    /** Last activity that is used to compute the Task bounds. */
+    @Nullable
+    private ActivityRecord mLastTaskBoundsComputeActivity;
+
     private boolean mForceShowForAllUsers;
 
     /** When set, will force the task to report as invisible. */
@@ -964,7 +957,7 @@
             mAtmService.getLockTaskController().clearLockedTask(this);
         }
         if (shouldDeferRemoval()) {
-            if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + mTaskId);
+            if (DEBUG_ROOT_TASK) Slog.i(TAG, "removeTask: deferring removing taskId=" + mTaskId);
             return;
         }
         removeImmediately();
@@ -1056,7 +1049,7 @@
 
     /** Convenience method to reparent a task to the top or bottom position of the stack. */
     boolean reparent(Task preferredStack, boolean toTop,
-            @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
+            @ReparentMoveRootTaskMode int moveStackMode, boolean animate, boolean deferResume,
             String reason) {
         return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate, deferResume,
                 true /* schedulePictureInPictureModeChange */, reason);
@@ -1067,7 +1060,7 @@
      * an option to skip scheduling the picture-in-picture mode change.
      */
     boolean reparent(Task preferredStack, boolean toTop,
-            @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
+            @ReparentMoveRootTaskMode int moveStackMode, boolean animate, boolean deferResume,
             boolean schedulePictureInPictureModeChange, String reason) {
         return reparent(preferredStack, toTop ? MAX_VALUE : 0, moveStackMode, animate,
                 deferResume, schedulePictureInPictureModeChange, reason);
@@ -1075,7 +1068,7 @@
 
     /** Convenience method to reparent a task to a specific position of the stack. */
     boolean reparent(Task preferredStack, int position,
-            @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
+            @ReparentMoveRootTaskMode int moveStackMode, boolean animate, boolean deferResume,
             String reason) {
         return reparent(preferredStack, position, moveStackMode, animate, deferResume,
                 true /* schedulePictureInPictureModeChange */, reason);
@@ -1101,7 +1094,7 @@
     // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs.
     // re-parenting the task. Can only be done when we are no longer using static stack Ids.
     boolean reparent(Task preferredStack, int position,
-            @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
+            @ReparentMoveRootTaskMode int moveStackMode, boolean animate, boolean deferResume,
             boolean schedulePictureInPictureModeChange, String reason) {
         final ActivityStackSupervisor supervisor = mStackSupervisor;
         final RootWindowContainer root = mRootWindowContainer;
@@ -1156,8 +1149,9 @@
             final boolean wasFront = r != null && sourceStack.isTopStackInDisplayArea()
                     && (sourceStack.topRunningActivity() == r);
 
-            final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
-                    || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
+            final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_ROOT_TASK_TO_FRONT
+                    || (moveStackMode == REPARENT_KEEP_ROOT_TASK_AT_FRONT
+                            && (wasFocused || wasFront));
 
             reparent(toStack, position, moveStackToFront, reason);
 
@@ -1181,7 +1175,7 @@
             toStack.prepareFreezingTaskBounds();
 
             if (toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                    && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
+                    && moveStackMode == REPARENT_KEEP_ROOT_TASK_AT_FRONT) {
                 // Move recents to front so it is not behind home stack when going into docked
                 // mode
                 mStackSupervisor.moveRecentsStackToFront(reason);
@@ -1506,6 +1500,11 @@
     }
 
     void cleanUpActivityReferences(ActivityRecord r) {
+        // mLastTaskBoundsComputeActivity is set at leaf Task
+        if (mLastTaskBoundsComputeActivity == r) {
+            mLastTaskBoundsComputeActivity = null;
+        }
+
         final WindowContainer parent = getParent();
         if (parent != null && parent.asTask() != null) {
             parent.asTask().cleanUpActivityReferences(r);
@@ -1532,7 +1531,7 @@
             return;
         }
 
-        if (ActivityTaskManagerDebugConfig.DEBUG_STACK) Slog.d(TAG_STACK,
+        if (ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK) Slog.d(TAG_ROOT_TASK,
                 "setResumedActivity stack:" + this + " + from: "
                 + mResumedActivity + " to:" + r + " reason:" + reason);
         mResumedActivity = r;
@@ -1941,32 +1940,7 @@
     }
 
     private void setLockTaskAuth(@Nullable ActivityRecord r) {
-        if (r == null) {
-            mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
-            return;
-        }
-
-        final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
-        final LockTaskController lockTaskController = mAtmService.getLockTaskController();
-        switch (r.lockTaskLaunchMode) {
-            case LOCK_TASK_LAUNCH_MODE_DEFAULT:
-                mLockTaskAuth = lockTaskController.isPackageAllowlisted(mUserId, pkg)
-                        ? LOCK_TASK_AUTH_ALLOWLISTED : LOCK_TASK_AUTH_PINNABLE;
-                break;
-
-            case LOCK_TASK_LAUNCH_MODE_NEVER:
-                mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK;
-                break;
-
-            case LOCK_TASK_LAUNCH_MODE_ALWAYS:
-                mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
-                break;
-
-            case LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED:
-                mLockTaskAuth = lockTaskController.isPackageAllowlisted(mUserId, pkg)
-                        ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
-                break;
-        }
+        mLockTaskAuth = mAtmService.getLockTaskController().getLockTaskAuth(r, this);
         ProtoLog.d(WM_DEBUG_LOCKTASK, "setLockTaskAuth: task=%s mLockTaskAuth=%s", this,
                 lockTaskAuthToString());
     }
@@ -2210,8 +2184,8 @@
         }
 
         if (state == RESUMED) {
-            if (ActivityTaskManagerDebugConfig.DEBUG_STACK) {
-                Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:" + reason);
+            if (ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK) {
+                Slog.v(TAG_ROOT_TASK, "set resumed activity to:" + record + " reason:" + reason);
             }
             setResumedActivity(record, reason + " - onActivityStateChanged");
             if (record == mRootWindowContainer.getTopResumedActivity()) {
@@ -2868,6 +2842,8 @@
 
     private void resolveLeafOnlyOverrideConfigs(Configuration newParentConfig,
             Rect previousBounds) {
+        mLastTaskBoundsComputeActivity = getTopNonFinishingActivity(false /* includeOverlays */);
+
         int windowingMode =
                 getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode();
         if (windowingMode == WINDOWING_MODE_UNDEFINED) {
@@ -2998,6 +2974,11 @@
         return bounds;
     }
 
+    @Nullable
+    ActivityRecord getLastTaskBoundsComputeActivity() {
+        return mLastTaskBoundsComputeActivity;
+    }
+
     /** Updates the task's bounds and override configuration to match what is expected for the
      * input stack. */
     void updateOverrideConfigurationForStack(Task inStack) {
@@ -3265,7 +3246,7 @@
 
     @Override
     void removeImmediately() {
-        if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + mTaskId);
+        if (DEBUG_ROOT_TASK) Slog.i(TAG, "removeTask: removing taskId=" + mTaskId);
         EventLogTags.writeWmTaskRemoved(mTaskId, "removeTask");
 
         // If applicable let the TaskOrganizer know the Task is vanishing.
@@ -3276,7 +3257,7 @@
 
     // TODO: Consolidate this with Task.reparent()
     void reparent(Task stack, int position, boolean moveParents, String reason) {
-        if (DEBUG_STACK) Slog.i(TAG, "reParentTask: removing taskId=" + mTaskId
+        if (DEBUG_ROOT_TASK) Slog.i(TAG, "reParentTask: removing taskId=" + mTaskId
                 + " from stack=" + getRootTask());
         EventLogTags.writeWmTaskRemoved(mTaskId, "reParentTask:" + reason);
 
@@ -3342,18 +3323,6 @@
         // No one in higher hierarchy handles this request, let's adjust our bounds to fulfill
         // it if possible.
         if (getParent() != null) {
-            final ActivityRecord activity = requestingContainer.asActivityRecord();
-            if (activity != null) {
-                // Clear the size compat cache to recompute the bounds for requested orientation;
-                // otherwise when Task#computeFullscreenBounds(), it will not try to do Task level
-                // letterboxing because app may prefer to keep its original size (size compat).
-                //
-                // Normally, ActivityRecord#clearSizeCompatMode() recomputes from its parent Task,
-                // which is the leaf Task. However, because this orientation request is new to all
-                // Tasks, pass false to clearSizeCompatMode, and trigger onConfigurationChanged from
-                // here (root Task) to make sure all Tasks are up-to-date.
-                activity.clearSizeCompatMode(false /* recomputeTask */);
-            }
             onConfigurationChanged(getParent().getConfiguration());
             return true;
         }
@@ -4180,7 +4149,7 @@
      * @param starting The currently starting activity or null if there is none.
      */
     boolean shouldBeVisible(ActivityRecord starting) {
-        return getVisibility(starting) != STACK_VISIBILITY_INVISIBLE;
+        return getVisibility(starting) != TASK_VISIBILITY_INVISIBLE;
     }
 
     /**
@@ -4188,14 +4157,14 @@
      *
      * @param starting The currently starting activity or null if there is none.
      */
-    @Task.StackVisibility
+    @TaskVisibility
     int getVisibility(ActivityRecord starting) {
         if (!isAttached() || isForceHidden()) {
-            return STACK_VISIBILITY_INVISIBLE;
+            return TASK_VISIBILITY_INVISIBLE;
         }
 
         if (isTopActivityLaunchedBehind()) {
-            return STACK_VISIBILITY_VISIBLE;
+            return TASK_VISIBILITY_VISIBLE;
         }
 
         boolean gotSplitScreenStack = false;
@@ -4211,10 +4180,10 @@
         final WindowContainer parent = getParent();
         if (parent.asTask() != null) {
             final int parentVisibility = parent.asTask().getVisibility(starting);
-            if (parentVisibility == STACK_VISIBILITY_INVISIBLE) {
+            if (parentVisibility == TASK_VISIBILITY_INVISIBLE) {
                 // Can't be visible if parent isn't visible
-                return STACK_VISIBILITY_INVISIBLE;
-            } else if (parentVisibility == STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT) {
+                return TASK_VISIBILITY_INVISIBLE;
+            } else if (parentVisibility == TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT) {
                 // Parent is behind a translucent container so the highest visibility this container
                 // can get is that.
                 gotTranslucentFullscreen = true;
@@ -4249,7 +4218,7 @@
                     gotTranslucentFullscreen = true;
                     continue;
                 }
-                return STACK_VISIBILITY_INVISIBLE;
+                return TASK_VISIBILITY_INVISIBLE;
             } else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
                     && !gotOpaqueSplitScreenPrimary) {
                 gotSplitScreenStack = true;
@@ -4258,7 +4227,7 @@
                 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
                         && gotOpaqueSplitScreenPrimary) {
                     // Can not be visible behind another opaque stack in split-screen-primary mode.
-                    return STACK_VISIBILITY_INVISIBLE;
+                    return TASK_VISIBILITY_INVISIBLE;
                 }
             } else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
                     && !gotOpaqueSplitScreenSecondary) {
@@ -4268,24 +4237,24 @@
                 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
                         && gotOpaqueSplitScreenSecondary) {
                     // Can not be visible behind another opaque stack in split-screen-secondary mode.
-                    return STACK_VISIBILITY_INVISIBLE;
+                    return TASK_VISIBILITY_INVISIBLE;
                 }
             }
             if (gotOpaqueSplitScreenPrimary && gotOpaqueSplitScreenSecondary) {
                 // Can not be visible if we are in split-screen windowing mode and both halves of
                 // the screen are opaque.
-                return STACK_VISIBILITY_INVISIBLE;
+                return TASK_VISIBILITY_INVISIBLE;
             }
             if (isAssistantType && gotSplitScreenStack) {
                 // Assistant stack can't be visible behind split-screen. In addition to this not
                 // making sense, it also works around an issue here we boost the z-order of the
                 // assistant window surfaces in window manager whenever it is visible.
-                return STACK_VISIBILITY_INVISIBLE;
+                return TASK_VISIBILITY_INVISIBLE;
             }
         }
 
         if (!shouldBeVisible) {
-            return STACK_VISIBILITY_INVISIBLE;
+            return TASK_VISIBILITY_INVISIBLE;
         }
 
         // Handle cases when there can be a translucent split-screen stack on top.
@@ -4293,26 +4262,26 @@
             case WINDOWING_MODE_FULLSCREEN:
                 if (gotTranslucentSplitScreenPrimary || gotTranslucentSplitScreenSecondary) {
                     // At least one of the split-screen stacks that covers this one is translucent.
-                    return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+                    return TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
                 }
                 break;
             case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
                 if (gotTranslucentSplitScreenPrimary) {
                     // Covered by translucent primary split-screen on top.
-                    return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+                    return TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
                 }
                 break;
             case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
                 if (gotTranslucentSplitScreenSecondary) {
                     // Covered by translucent secondary split-screen on top.
-                    return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+                    return TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
                 }
                 break;
         }
 
         // Lastly - check if there is a translucent fullscreen stack on top.
-        return gotTranslucentFullscreen ? STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT
-                : STACK_VISIBILITY_VISIBLE;
+        return gotTranslucentFullscreen ? TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT
+                : TASK_VISIBILITY_VISIBLE;
     }
 
     private boolean isTopActivityLaunchedBehind() {
@@ -7326,7 +7295,7 @@
         boolean toTop = position >= getChildCount();
         boolean includingParents = toTop || getDisplayArea().getNextFocusableStack(this,
                 true /* ignoreCurrent */) == null;
-        if (WindowManagerDebugConfig.DEBUG_STACK) {
+        if (WindowManagerDebugConfig.DEBUG_ROOT_TASK) {
             Slog.i(TAG_WM, "positionChildAt: positioning task=" + task + " at " + position);
         }
         positionChildAt(position, task, includingParents);
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index e721319..9d14e0d 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -37,11 +37,11 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
-import static com.android.server.wm.ActivityTaskManagerService.TAG_STACK;
+import static com.android.server.wm.ActivityTaskManagerService.TAG_ROOT_TASK;
 import static com.android.server.wm.DisplayContent.alwaysCreateStack;
 import static com.android.server.wm.Task.ActivityState.RESUMED;
-import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.annotation.Nullable;
@@ -311,7 +311,7 @@
 
     @Override
     void addChild(Task task, int position) {
-        if (DEBUG_STACK) Slog.d(TAG_WM, "Set task=" + task + " on taskDisplayArea=" + this);
+        if (DEBUG_ROOT_TASK) Slog.d(TAG_WM, "Set task=" + task + " on taskDisplayArea=" + this);
 
         addStackReferenceIfNeeded(task);
         position = findPositionForStack(position, task, true /* adding */);
@@ -831,8 +831,8 @@
     }
 
     void onStackRemoved(Task stack) {
-        if (ActivityTaskManagerDebugConfig.DEBUG_STACK) {
-            Slog.v(TAG_STACK, "removeStack: detaching " + stack + " from displayId="
+        if (ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK) {
+            Slog.v(TAG_ROOT_TASK, "removeStack: detaching " + stack + " from displayId="
                     + mDisplayContent.mDisplayId);
         }
         if (mPreferredTopFocusableStack == stack) {
@@ -870,7 +870,7 @@
             homeParentTask.positionChildAtBottom(task);
         } else {
             task.reparent(homeParentTask, false /* toTop */,
-                    Task.REPARENT_LEAVE_STACK_IN_PLACE, false /* animate */,
+                    Task.REPARENT_LEAVE_ROOT_TASK_IN_PLACE, false /* animate */,
                     false /* deferResume */, "positionTaskBehindHome");
         }
     }
@@ -1205,8 +1205,8 @@
             }
         }
         final Task currentFocusedStack = getFocusedStack();
-        if (ActivityTaskManagerDebugConfig.DEBUG_STACK) {
-            Slog.d(TAG_STACK, "allResumedActivitiesComplete: mLastFocusedStack changing from="
+        if (ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK) {
+            Slog.d(TAG_ROOT_TASK, "allResumedActivitiesComplete: mLastFocusedStack changing from="
                     + mLastFocusedStack + " to=" + currentFocusedStack);
         }
         mLastFocusedStack = currentFocusedStack;
@@ -1230,7 +1230,7 @@
             final Task stack = getStackAt(stackNdx);
             final ActivityRecord resumedActivity = stack.getResumedActivity();
             if (resumedActivity != null
-                    && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE
+                    && (stack.getVisibility(resuming) != TASK_VISIBILITY_VISIBLE
                     || !stack.isTopActivityFocusable())) {
                 ProtoLog.d(WM_DEBUG_STATES, "pauseBackStacks: stack=%s "
                         + "mResumedActivity=%s", stack, resumedActivity);
@@ -1851,8 +1851,12 @@
                 .getTopStackInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) : null;
         for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
             final Task stack = getStackAt(stackNdx);
-            // Always finish non-standard type stacks.
-            if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) {
+            // Always finish non-standard type stacks and stacks created by a organizer.
+            // TODO: For stacks created by organizer, consider reparenting children tasks if the use
+            //       case arises in the future.
+            if (destroyContentOnRemoval
+                    || !stack.isActivityTypeStandardOrUndefined()
+                    || stack.mCreatedByOrganizer) {
                 stack.finishAllActivitiesImmediately();
             } else {
                 // Reparent the stack to the root task of secondary-split-screen or display area.
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 2c39c2b..7423763 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -160,18 +160,20 @@
                 return;
             }
             ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task info changed taskId=%d", task.mTaskId);
-            if (!task.isOrganized()) {
-                // This is safe to ignore if the task is no longer organized
-                return;
-            }
-            try {
-                // Purposely notify of task info change immediately instead of deferring (like
-                // appear and vanish) to allow info changes (such as new PIP params) to flow
-                // without waiting.
-                mTaskOrganizer.onTaskInfoChanged(taskInfo);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Exception sending onTaskInfoChanged callback", e);
-            }
+            mDeferTaskOrgCallbacksConsumer.accept(() -> {
+                if (!task.isOrganized()) {
+                    // This is safe to ignore if the task is no longer organized
+                    return;
+                }
+                try {
+                    // Purposely notify of task info change immediately instead of deferring (like
+                    // appear and vanish) to allow info changes (such as new PIP params) to flow
+                    // without waiting.
+                    mTaskOrganizer.onTaskInfoChanged(taskInfo);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Exception sending onTaskInfoChanged callback", e);
+                }
+            });
         }
 
         void onBackPressedOnTaskRoot(Task task) {
@@ -181,15 +183,17 @@
                 // Skip if the task has not yet received taskAppeared().
                 return;
             }
-            if (!task.isOrganized()) {
-                // This is safe to ignore if the task is no longer organized
-                return;
-            }
-            try {
-                mTaskOrganizer.onBackPressedOnTaskRoot(task.getTaskInfo());
-            } catch (Exception e) {
-                Slog.e(TAG, "Exception sending onBackPressedOnTaskRoot callback", e);
-            }
+            mDeferTaskOrgCallbacksConsumer.accept(() -> {
+                if (!task.isOrganized()) {
+                    // This is safe to ignore if the task is no longer organized
+                    return;
+                }
+                try {
+                    mTaskOrganizer.onBackPressedOnTaskRoot(task.getTaskInfo());
+                } catch (Exception e) {
+                    Slog.e(TAG, "Exception sending onBackPressedOnTaskRoot callback", e);
+                }
+            });
         }
     }
 
@@ -438,7 +442,11 @@
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
+                final WindowContainer wc = WindowContainer.fromBinder(token.asBinder());
+                if (wc == null) {
+                    throw new IllegalArgumentException("Can't resolve window from token");
+                }
+                final Task task = wc.asTask();
                 if (task == null) return false;
                 if (!task.mCreatedByOrganizer) {
                     throw new IllegalArgumentException(
@@ -489,8 +497,7 @@
                         mTmpTaskInfo.positionInParent,
                         lastInfo.positionInParent)
                 || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams
-                || mTmpTaskInfo.getConfiguration().windowConfiguration.getWindowingMode()
-                        != lastInfo.getConfiguration().windowConfiguration.getWindowingMode()
+                || mTmpTaskInfo.getWindowingMode() != lastInfo.getWindowingMode()
                 || !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription);
         if (!changed) {
             int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
@@ -560,8 +567,14 @@
                 if (defaultTaskDisplayArea == null) {
                     return;
                 }
-                Task task = token == null
-                        ? null : WindowContainer.fromBinder(token.asBinder()).asTask();
+                WindowContainer wc = null;
+                if (token != null) {
+                    wc = WindowContainer.fromBinder(token.asBinder());
+                    if (wc == null) {
+                        throw new IllegalArgumentException("Can't resolve window from token");
+                    }
+                }
+                final Task task = wc == null ? null : wc.asTask();
                 if (task == null) {
                     defaultTaskDisplayArea.mLaunchRootTask = null;
                     return;
@@ -662,7 +675,12 @@
             synchronized (mGlobalLock) {
                 ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Set intercept back pressed on root=%b",
                         interceptBackPressed);
-                final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
+                final WindowContainer wc = WindowContainer.fromBinder(token.asBinder());
+                if (wc == null) {
+                    Slog.w(TAG, "Could not resolve window from token");
+                    return;
+                }
+                final Task task = wc.asTask();
                 if (task == null) {
                     Slog.w(TAG, "Could not resolve task from token");
                     return;
diff --git a/services/core/java/com/android/server/wm/TaskPersister.java b/services/core/java/com/android/server/wm/TaskPersister.java
index a3dc290..eff4b9e 100644
--- a/services/core/java/com/android/server/wm/TaskPersister.java
+++ b/services/core/java/com/android/server/wm/TaskPersister.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
 
 import android.annotation.NonNull;
 import android.graphics.Bitmap;
@@ -330,7 +330,7 @@
 
                                 final int taskId = task.mTaskId;
                                 if (mService.mRootWindowContainer.anyTaskForId(taskId,
-                                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) != null) {
+                                        MATCH_ATTACHED_TASK_OR_RECENT_TASKS) != null) {
                                     // Should not happen.
                                     Slog.wtf(TAG, "Existing task with taskId " + taskId + "found");
                                 } else if (userId != task.mUserId) {
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index a6f0f46..614d221 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -225,10 +225,8 @@
                 mClientChannel, mService.mAnimationHandler.getLooper(),
                 mService.mAnimator.getChoreographer());
 
-        mDragApplicationHandle = new InputApplicationHandle(new Binder());
-        mDragApplicationHandle.name = TAG;
-        mDragApplicationHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-
+        mDragApplicationHandle = new InputApplicationHandle(new Binder(), TAG,
+                DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
 
         mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle,
                 displayContent.getDisplayId());
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index aab5da6..30f09ce 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -36,6 +36,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 
 import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
@@ -129,6 +130,7 @@
     private SurfaceControl mChildSurfaceControl;
     private final IWindowSession mSession;
     private final WindowManagerService mService;
+    private final int mDisplayId;
     private final Rect mTaskBounds;
     private final Rect mFrame = new Rect();
     private final Rect mSystemBarInsets = new Rect();
@@ -151,10 +153,15 @@
 
     static TaskSnapshotSurface create(WindowManagerService service, ActivityRecord activity,
             TaskSnapshot snapshot) {
+        return create(service, activity, snapshot, WindowManagerGlobal.getWindowSession());
+    }
+
+    @VisibleForTesting
+    static TaskSnapshotSurface create(WindowManagerService service, ActivityRecord activity,
+            TaskSnapshot snapshot, IWindowSession session) {
 
         final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
         final Window window = new Window();
-        final IWindowSession session = WindowManagerGlobal.getWindowSession();
         window.setSession(session);
         final SurfaceControl surfaceControl = new SurfaceControl();
         final ClientWindowFrames tmpFrames = new ClientWindowFrames();
@@ -215,7 +222,10 @@
             layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES)
                     | FLAG_NOT_FOCUSABLE
                     | FLAG_NOT_TOUCHABLE;
-            layoutParams.privateFlags = windowPrivateFlags & PRIVATE_FLAG_INHERITS;
+            // Setting as trusted overlay to let touches pass through. This is safe because this
+            // window is controlled by the system.
+            layoutParams.privateFlags = (windowPrivateFlags & PRIVATE_FLAG_INHERITS)
+                    | PRIVATE_FLAG_TRUSTED_OVERLAY;
             layoutParams.token = activity.token;
             layoutParams.width = LayoutParams.MATCH_PARENT;
             layoutParams.height = LayoutParams.MATCH_PARENT;
@@ -239,11 +249,11 @@
             insetsState = getInsetsStateWithVisibilityOverride(topFullscreenOpaqueWindow);
 
         }
+        int displayId = activity.getDisplayContent().getDisplayId();
         try {
             final int res = session.addToDisplay(window, layoutParams,
-                    View.GONE, activity.getDisplayContent().getDisplayId(), mTmpInsetsState,
-                    tmpFrames.frame, tmpFrames.displayCutout, null /* outInputChannel */,
-                    mTmpInsetsState, mTempControls);
+                    View.GONE, displayId, mTmpInsetsState, tmpFrames.frame, tmpFrames.displayCutout,
+                    null /* outInputChannel */, mTmpInsetsState, mTempControls);
             if (res < 0) {
                 Slog.w(TAG, "Failed to add snapshot starting window res=" + res);
                 return null;
@@ -251,10 +261,10 @@
         } catch (RemoteException e) {
             // Local call.
         }
-        final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window,
-                surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance,
-                windowFlags, windowPrivateFlags, taskBounds, currentOrientation, activityType,
-                insetsState);
+        final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, displayId,
+                window, surfaceControl, snapshot, layoutParams.getTitle(), taskDescription,
+                appearance, windowFlags, windowPrivateFlags, taskBounds, currentOrientation,
+                activityType, insetsState);
         window.setOuter(snapshotSurface);
         try {
             session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1,
@@ -271,11 +281,13 @@
     }
 
     @VisibleForTesting
-    TaskSnapshotSurface(WindowManagerService service, Window window, SurfaceControl surfaceControl,
-            TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription,
-            int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds,
-            int currentOrientation, int activityType, InsetsState insetsState) {
+    TaskSnapshotSurface(WindowManagerService service, int displayId, Window window,
+            SurfaceControl surfaceControl, TaskSnapshot snapshot, CharSequence title,
+            TaskDescription taskDescription, int appearance, int windowFlags,
+            int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType,
+            InsetsState insetsState) {
         mService = service;
+        mDisplayId = displayId;
         mSurface = service.mSurfaceFactory.get();
         mHandler = new Handler(mService.mH.getLooper());
         mSession = WindowManagerGlobal.getWindowSession();
@@ -368,8 +380,9 @@
                 - ((float) mFrame.width() / mFrame.height())) > 0.01f;
 
         // Keep a reference to it such that it doesn't get destroyed when finalized.
+        final String name = mTitle + " - task-snapshot-surface";
         mChildSurfaceControl = mService.mSurfaceControlFactory.apply(session)
-                .setName(mTitle + " - task-snapshot-surface")
+                .setName(name)
                 .setBufferSize(buffer.getWidth(), buffer.getHeight())
                 .setFormat(buffer.getFormat())
                 .setParent(mSurfaceControl)
@@ -401,6 +414,11 @@
         mSnapshotMatrix.setRectToRect(mTmpSnapshotSize, mTmpDstFrame, Matrix.ScaleToFit.FILL);
         mTransaction.setMatrix(mChildSurfaceControl, mSnapshotMatrix, mTmpFloat9);
 
+        // This is the way to tell the input system to exclude this surface from occlusion
+        // detection since we don't have a window for it. We do this because this window is
+        // generated by the system as well as its content (the snapshot of the app).
+        InputMonitor.setTrustedOverlayInputInfo(mChildSurfaceControl, mTransaction, mDisplayId,
+                name);
         mTransaction.apply();
         surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace());
         surface.release();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 0f6b62b..e4b3542 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2878,6 +2878,7 @@
         return true;
     }
 
+    @Nullable
     static WindowContainer fromBinder(IBinder binder) {
         return RemoteToken.fromBinder(binder).getContainer();
     }
@@ -2891,6 +2892,7 @@
             mWeakRef = new WeakReference<>(container);
         }
 
+        @Nullable
         WindowContainer getContainer() {
             return mWeakRef.get();
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 93b0fd9..74337c2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -50,7 +50,7 @@
     static final boolean DEBUG_WINDOW_TRACE = false;
     static final boolean DEBUG_TASK_MOVEMENT = false;
     static final boolean DEBUG_TASK_POSITIONING = false;
-    static final boolean DEBUG_STACK = false;
+    static final boolean DEBUG_ROOT_TASK = false;
     static final boolean DEBUG_DISPLAY = false;
     static final boolean DEBUG_POWER = false;
     static final boolean SHOW_VERBOSE_TRANSACTIONS = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c806c94..e7d9e6b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -44,6 +44,7 @@
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
+import static android.provider.Settings.Global.DEVELOPMENT_IGNORE_VENDOR_DISPLAY_SETTINGS;
 import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
@@ -197,7 +198,6 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
@@ -576,6 +576,7 @@
     final PackageManagerInternal mPmInternal;
     private final TestUtilityService mTestUtilityService;
 
+    final DisplayWindowSettingsProvider mDisplayWindowSettingsProvider;
     final DisplayWindowSettings mDisplayWindowSettings;
 
     /** If the system should display notifications for apps displaying an alert window. */
@@ -799,6 +800,8 @@
                 DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM);
         private final Uri mRenderShadowsInCompositorUri = Settings.Global.getUriFor(
                 DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR);
+        private final Uri mIgnoreVendorDisplaySettingsUri = Settings.Global.getUriFor(
+                DEVELOPMENT_IGNORE_VENDOR_DISPLAY_SETTINGS);
 
         public SettingsObserver() {
             super(new Handler());
@@ -823,6 +826,8 @@
                     UserHandle.USER_ALL);
             resolver.registerContentObserver(mRenderShadowsInCompositorUri, false, this,
                     UserHandle.USER_ALL);
+            resolver.registerContentObserver(mIgnoreVendorDisplaySettingsUri, false, this,
+                    UserHandle.USER_ALL);
         }
 
         @Override
@@ -866,6 +871,11 @@
                 return;
             }
 
+            if (mIgnoreVendorDisplaySettingsUri.equals(uri)) {
+                updateIgnoreVendorDisplaySettings();
+                return;
+            }
+
             @UpdateAnimationScaleMode
             final int mode;
             if (mWindowAnimationScaleUri.equals(uri)) {
@@ -955,6 +965,19 @@
 
             mAtmService.mSizeCompatFreeform = sizeCompatFreeform;
         }
+
+        void updateIgnoreVendorDisplaySettings() {
+            final ContentResolver resolver = mContext.getContentResolver();
+            final boolean ignoreVendorSettings = Settings.Global.getInt(resolver,
+                    DEVELOPMENT_IGNORE_VENDOR_DISPLAY_SETTINGS, 0) != 0;
+            synchronized (mGlobalLock) {
+                mDisplayWindowSettingsProvider.setVendorSettingsIgnored(ignoreVendorSettings);
+                mRoot.forAllDisplays(display -> {
+                    mDisplayWindowSettings.applySettingsToDisplayLocked(display);
+                    display.reconfigureDisplayLocked();
+                });
+            }
+        }
     }
 
     private void setShadowRenderer() {
@@ -1213,7 +1236,6 @@
         mSurfaceFactory = surfaceFactory;
         mTransaction = mTransactionFactory.get();
 
-        mDisplayWindowSettings = new DisplayWindowSettings(this);
         mPolicy = policy;
         mAnimator = new WindowAnimator(this);
         mRoot = new RootWindowContainer(this);
@@ -1312,6 +1334,12 @@
         mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver,
                 DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
 
+        final boolean ignoreVendorDisplaySettings = Settings.Global.getInt(resolver,
+                DEVELOPMENT_IGNORE_VENDOR_DISPLAY_SETTINGS, 0) != 0;
+        mDisplayWindowSettingsProvider = new DisplayWindowSettingsProvider();
+        mDisplayWindowSettingsProvider.setVendorSettingsIgnored(ignoreVendorDisplaySettings);
+        mDisplayWindowSettings = new DisplayWindowSettings(this, mDisplayWindowSettingsProvider);
+
         IntentFilter filter = new IntentFilter();
         // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
         filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -7669,6 +7697,7 @@
                 if (imeTarget == null) {
                     return;
                 }
+                Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "WMS.showImePostLayout", 0);
                 final InsetsControlTarget controlTarget = imeTarget.getImeControlTarget();
                 imeTarget = controlTarget.getWindow();
                 // If InsetsControlTarget doesn't have a window, its using remoteControlTarget which
@@ -7682,6 +7711,7 @@
 
         @Override
         public void hideIme(IBinder imeTargetWindowToken, int displayId) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WMS.hideIme");
             synchronized (mGlobalLock) {
                 WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
                 ProtoLog.d(WM_DEBUG_IME, "hideIme target: %s ", imeTarget);
@@ -7702,6 +7732,7 @@
                             WindowInsets.Type.ime(), true /* fromIme */);
                 }
             }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
 
         @Override
@@ -8364,7 +8395,7 @@
                             embeddedWindow.getName());
                     return;
                 }
-                t.requestFocusTransfer(newFocusTarget.mInputWindowHandle.token, targetInputToken,
+                t.requestFocusTransfer(newFocusTarget.mInputChannelToken, targetInputToken,
                         displayId).apply();
                 EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
                         "Transfer focus request " + newFocusTarget,
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 7d54ea9..f11cd93 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -249,7 +249,7 @@
             for (int i = 0, n = hops.size(); i < n; ++i) {
                 final WindowContainerTransaction.HierarchyOp hop = hops.get(i);
                 final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
-                if (!wc.isAttached()) {
+                if (wc == null || !wc.isAttached()) {
                     Slog.e(TAG, "Attempt to operate on detached container: " + wc);
                     continue;
                 }
@@ -260,7 +260,13 @@
                 if (transition != null) {
                     transition.collect(wc);
                     if (hop.isReparent() && hop.getNewParent() != null) {
-                        transition.collect(WindowContainer.fromBinder(hop.getNewParent()));
+                        final WindowContainer parentWc =
+                                WindowContainer.fromBinder(hop.getNewParent());
+                        if (parentWc == null) {
+                            Slog.e(TAG, "Can't resolve parent window from token");
+                            continue;
+                        }
+                        transition.collect(parentWc);
                     }
                 }
             }
@@ -269,7 +275,12 @@
             entries = t.getChanges().entrySet().iterator();
             while (entries.hasNext()) {
                 final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next();
-                final Task task = WindowContainer.fromBinder(entry.getKey()).asTask();
+                final WindowContainer wc = WindowContainer.fromBinder(entry.getKey());
+                if (wc == null || !wc.isAttached()) {
+                    Slog.e(TAG, "Attempt to operate on detached container: " + wc);
+                    continue;
+                }
+                final Task task = wc.asTask();
                 final Rect surfaceBounds = entry.getValue().getBoundsChangeSurfaceBounds();
                 if (task == null || !task.isAttached() || surfaceBounds == null) {
                     continue;
@@ -429,6 +440,10 @@
                 WindowContainer newParent = hop.getNewParent() == null
                         ? dc.getDefaultTaskDisplayArea()
                         : WindowContainer.fromBinder(hop.getNewParent());
+                if (newParent == null) {
+                    Slog.e(TAG, "Can't resolve parent window from token");
+                    return 0;
+                }
                 if (task.getParent() != newParent) {
                     if (newParent instanceof TaskDisplayArea) {
                         // For now, reparenting to displayarea is different from other reparents...
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 2e7905c..5bfa662 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -225,8 +225,19 @@
     @Nullable
     private final BackgroundActivityStartCallback mBackgroundActivityStartCallback;
 
-    /** The state for oom-adjustment calculation. */
-    private final OomScoreReferenceState mOomRefState;
+    // The bits used for mActivityStateFlags.
+    private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 0x10000000;
+    private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 0x20000000;
+    private static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 0x40000000;
+    private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 0x80000000;
+    private static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;
+
+    /**
+     * The state for oom-adjustment calculation. The higher 16 bits are the activity states, and the
+     * lower 16 bits are the task layer rank (see {@link Task#mLayerRank}). This field is written by
+     * window manager and read by activity manager.
+     */
+    private volatile int mActivityStateFlags = ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
 
     public WindowProcessController(@NonNull ActivityTaskManagerService atm, ApplicationInfo info,
             String name, int uid, int userId, Object owner,
@@ -240,7 +251,6 @@
         mAtm = atm;
         mDisplayId = INVALID_DISPLAY;
         mBackgroundActivityStartCallback = mAtm.getBackgroundActivityStartCallback();
-        mOomRefState = new OomScoreReferenceState(this);
 
         boolean isSysUiPackage = info.packageName.equals(
                 mAtm.getSysUiServiceComponentLocked().getPackageName());
@@ -707,7 +717,7 @@
 
     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
     public boolean hasVisibleActivities() {
-        return (mOomRefState.mActivityStateFlags & OomScoreReferenceState.FLAG_IS_VISIBLE) != 0;
+        return (mActivityStateFlags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0;
     }
 
     @HotPath(caller = HotPath.LRU_UPDATE)
@@ -1000,34 +1010,6 @@
         mHostActivities.remove(r);
     }
 
-    private static class OomScoreReferenceState extends RootWindowContainer.LockedScheduler {
-        private static final int FLAG_IS_VISIBLE = 0x10000000;
-        private static final int FLAG_IS_PAUSING = 0x20000000;
-        private static final int FLAG_IS_STOPPING = 0x40000000;
-        private static final int FLAG_IS_STOPPING_FINISHING = 0x80000000;
-        /** @see Task#mLayerRank */
-        private static final int MASK_MIN_TASK_LAYER = 0x0000ffff;
-
-        private final WindowProcessController mOwner;
-        boolean mChanged;
-
-        /**
-         * The higher 16 bits are the activity states, and the lower 16 bits are the task layer
-         * rank. This field is written by window manager and read by activity manager.
-         */
-        volatile int mActivityStateFlags = MASK_MIN_TASK_LAYER;
-
-        OomScoreReferenceState(WindowProcessController owner) {
-            super(owner.mAtm);
-            mOwner = owner;
-        }
-
-        @Override
-        public void execute() {
-            mOwner.computeOomScoreReferenceStateIfNeeded();
-        }
-    }
-
     public interface ComputeOomAdjCallback {
         void onVisibleActivity();
         void onPausedActivity();
@@ -1041,26 +1023,21 @@
      */
     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
     public int computeOomAdjFromActivities(ComputeOomAdjCallback callback) {
-        final int flags = mOomRefState.mActivityStateFlags;
-        if ((flags & OomScoreReferenceState.FLAG_IS_VISIBLE) != 0) {
+        final int flags = mActivityStateFlags;
+        if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) {
             callback.onVisibleActivity();
-        } else if ((flags & OomScoreReferenceState.FLAG_IS_PAUSING) != 0) {
+        } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
             callback.onPausedActivity();
-        } else if ((flags & OomScoreReferenceState.FLAG_IS_STOPPING) != 0) {
+        } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) {
             callback.onStoppingActivity(
-                    (flags & OomScoreReferenceState.FLAG_IS_STOPPING_FINISHING) != 0);
+                    (flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0);
         } else {
             callback.onOtherActivity();
         }
-        return flags & OomScoreReferenceState.MASK_MIN_TASK_LAYER;
+        return flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
     }
 
-    void computeOomScoreReferenceStateIfNeeded() {
-        if (!mOomRefState.mChanged) {
-            return;
-        }
-        mOomRefState.mChanged = false;
-
+    void computeProcessActivityState() {
         // Since there could be more than one activities in a process record, we don't need to
         // compute the OomAdj with each of them, just need to find out the activity with the
         // "best" state, the order would be visible, pausing, stopping...
@@ -1101,36 +1078,25 @@
                     finishing &= r.finishing;
                 }
             }
+        }
 
-            int stateFlags = minTaskLayer & OomScoreReferenceState.MASK_MIN_TASK_LAYER;
-            if (visible) {
-                stateFlags |= OomScoreReferenceState.FLAG_IS_VISIBLE;
-            } else if (best == PAUSING) {
-                stateFlags |= OomScoreReferenceState.FLAG_IS_PAUSING;
-            } else if (best == STOPPING) {
-                stateFlags |= OomScoreReferenceState.FLAG_IS_STOPPING;
-                if (finishing) {
-                    stateFlags |= OomScoreReferenceState.FLAG_IS_STOPPING_FINISHING;
-                }
+        int stateFlags = minTaskLayer & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
+        if (visible) {
+            stateFlags |= ACTIVITY_STATE_FLAG_IS_VISIBLE;
+        } else if (best == PAUSING) {
+            stateFlags |= ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED;
+        } else if (best == STOPPING) {
+            stateFlags |= ACTIVITY_STATE_FLAG_IS_STOPPING;
+            if (finishing) {
+                stateFlags |= ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING;
             }
-            mOomRefState.mActivityStateFlags = stateFlags;
         }
-    }
-
-    void invalidateOomScoreReferenceState(boolean computeNow) {
-        mOomRefState.mChanged = true;
-        if (computeNow) {
-            computeOomScoreReferenceStateIfNeeded();
-            return;
-        }
-        mOomRefState.scheduleIfNeeded();
+        mActivityStateFlags = stateFlags;
     }
 
     /** Called when the process has some oom related changes and it is going to update oom-adj. */
     private void prepareOomAdjustment() {
         mAtm.mRootWindowContainer.rankTaskLayersIfNeeded();
-        // The task layer may not change but the activity state in the same task may change.
-        computeOomScoreReferenceStateIfNeeded();
     }
 
     public int computeRelaunchReason() {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 9234390..fc06461 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -556,9 +556,17 @@
     boolean mWindowRemovalAllowed;
 
     // Input channel and input window handle used by the input dispatcher.
-    final InputWindowHandle mInputWindowHandle;
+    final InputWindowHandleWrapper mInputWindowHandle;
     InputChannel mInputChannel;
 
+    /**
+     * The token will be assigned to {@link InputWindowHandle#token} if this window can receive
+     * input event. Note that the token of associated input window handle can be cleared if this
+     * window becomes unable to receive input, but this field will remain until the input channel
+     * is actually disposed.
+     */
+    IBinder mInputChannelToken;
+
     // Used to improve performance of toString()
     private String mStringNameCache;
     private CharSequence mLastTitle;
@@ -856,6 +864,21 @@
         DeathRecipient deathRecipient = new DeathRecipient();
         mPowerManagerWrapper = powerManagerWrapper;
         mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
+        mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle(
+                mActivityRecord != null
+                        ? mActivityRecord.getInputApplicationHandle(false /* update */) : null,
+                getDisplayId()));
+        mInputWindowHandle.setOwnerPid(s.mPid);
+        mInputWindowHandle.setOwnerUid(s.mUid);
+        mInputWindowHandle.setName(getName());
+        mInputWindowHandle.setPackageName(mAttrs.packageName);
+        mInputWindowHandle.setLayoutParamsType(mAttrs.type);
+        // Check private trusted overlay flag and window type to set trustedOverlay variable of
+        // input window handle.
+        mInputWindowHandle.setTrustedOverlay(
+                ((mAttrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0
+                        && mOwnerCanAddInternalSystemWindow)
+                        || InputMonitor.isTrustedOverlay(mAttrs.type));
         if (DEBUG) {
             Slog.v(TAG, "Window " + this + " client=" + c.asBinder()
                             + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
@@ -871,7 +894,6 @@
             mIsFloatingLayer = false;
             mBaseLayer = 0;
             mSubLayer = 0;
-            mInputWindowHandle = null;
             mWinAnimator = null;
             mWpcForDisplayConfigChanges = null;
             return;
@@ -919,16 +941,6 @@
         mLastRequestedWidth = 0;
         mLastRequestedHeight = 0;
         mLayer = 0;
-        mInputWindowHandle = new InputWindowHandle(
-                mActivityRecord != null ? mActivityRecord.mInputApplicationHandle : null,
-                    getDisplayId());
-
-        //  Check private trusted overlay flag and window type to set trustedOverlay variable of
-        //  input window handle.
-        mInputWindowHandle.trustedOverlay =
-                (mAttrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0
-                && mOwnerCanAddInternalSystemWindow;
-        mInputWindowHandle.trustedOverlay |= InputMonitor.isTrustedOverlay(mAttrs.type);
 
         // Make sure we initial all fields before adding to parentWindow, to prevent exception
         // during onDisplayChanged.
@@ -1496,9 +1508,9 @@
         }
         super.onDisplayChanged(dc);
         // Window was not laid out for this display yet, so make sure mLayoutSeq does not match.
-        if (dc != null && mInputWindowHandle.displayId != dc.getDisplayId()) {
+        if (dc != null && mInputWindowHandle.getDisplayId() != dc.getDisplayId()) {
             mLayoutSeq = dc.mLayoutSeq - 1;
-            mInputWindowHandle.displayId = dc.getDisplayId();
+            mInputWindowHandle.setDisplayId(dc.getDisplayId());
         }
     }
 
@@ -2470,7 +2482,9 @@
         }
         String name = getName();
         mInputChannel = mWmService.mInputManager.createInputChannel(name);
-        mInputWindowHandle.token = mInputChannel.getToken();
+        mInputChannelToken = mInputChannel.getToken();
+        mInputWindowHandle.setToken(mInputChannelToken);
+        mWmService.mInputToWindowMap.put(mInputChannelToken, this);
         if (outInputChannel != null) {
             mInputChannel.copyTo(outInputChannel);
         } else {
@@ -2479,7 +2493,6 @@
             // Create fake event receiver that simply reports all events as handled.
             mDeadWindowEventReceiver = new DeadWindowEventReceiver(mInputChannel);
         }
-        mWmService.mInputToWindowMap.put(mInputWindowHandle.token, this);
     }
 
     void disposeInputChannel() {
@@ -2487,17 +2500,19 @@
             mDeadWindowEventReceiver.dispose();
             mDeadWindowEventReceiver = null;
         }
+        if (mInputChannelToken != null) {
+            // Unregister server channel first otherwise it complains about broken channel.
+            mWmService.mInputManager.removeInputChannel(mInputChannelToken);
+            mWmService.mKeyInterceptionInfoForToken.remove(mInputChannelToken);
+            mWmService.mInputToWindowMap.remove(mInputChannelToken);
+            mInputChannelToken = null;
+        }
 
-        // unregister server channel first otherwise it complains about broken channel
         if (mInputChannel != null) {
-            mWmService.mInputManager.removeInputChannel(mInputChannel.getToken());
-
             mInputChannel.dispose();
             mInputChannel = null;
         }
-        mWmService.mKeyInterceptionInfoForToken.remove(mInputWindowHandle.token);
-        mWmService.mInputToWindowMap.remove(mInputWindowHandle.token);
-        mInputWindowHandle.token = null;
+        mInputWindowHandle.setToken(null);
     }
 
     /** Returns true if the replacement window was removed. */
@@ -2567,11 +2582,8 @@
         }
     }
 
-    int getSurfaceTouchableRegion(InputWindowHandle inputWindowHandle, int flags) {
+    int getSurfaceTouchableRegion(Region region, int flags) {
         final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
-        final Region region = inputWindowHandle.touchableRegion;
-        setTouchableRegionCropIfNeeded(inputWindowHandle);
-
         if (modal) {
             flags |= FLAG_NOT_TOUCH_MODAL;
             if (mActivityRecord != null) {
@@ -2593,7 +2605,10 @@
         }
 
         // Translate to surface based coordinates.
-        region.translate(-mWindowFrames.mFrame.left, -mWindowFrames.mFrame.top);
+        final Rect frame = mWindowFrames.mFrame;
+        if (frame.left != 0 || frame.top != 0) {
+            region.translate(-frame.left, -frame.top);
+        }
 
         // TODO(b/139804591): sizecompat layout needs to be reworked. Currently mFrame is post-
         // scaling but the existing logic doesn't expect that. The result is that the already-
@@ -3442,7 +3457,9 @@
                 break;
             case TOUCHABLE_INSETS_REGION: {
                 outRegion.set(mGivenTouchableRegion);
-                outRegion.translate(frame.left, frame.top);
+                if (frame.left != 0 || frame.top != 0) {
+                    outRegion.translate(frame.left, frame.top);
+                }
                 break;
             }
         }
@@ -3469,22 +3486,6 @@
         }
     }
 
-    private void setTouchableRegionCropIfNeeded(InputWindowHandle handle) {
-        final Task task = getTask();
-        if (task == null || !task.cropWindowsToStackBounds()) {
-            handle.setTouchableRegionCrop(null);
-            return;
-        }
-
-        final Task stack = task.getRootTask();
-        if (stack == null || inFreeformWindowingMode()) {
-            handle.setTouchableRegionCrop(null);
-            return;
-        }
-
-        handle.setTouchableRegionCrop(stack.getSurfaceControl());
-    }
-
     private void cropRegionToStackBoundsIfNeeded(Region region) {
         final Task task = getTask();
         if (task == null || !task.cropWindowsToStackBounds()) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index d845b12..72aa766 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -488,6 +488,9 @@
             mSurfaceFormat = format;
 
             w.setHasSurface(true);
+            // The surface instance is changed. Make sure the input info can be applied to the
+            // new surface, e.g. relaunch activity.
+            w.mInputWindowHandle.forceChange();
 
             ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
                         "  CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x / %s",
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 21cb9a7..db93c89 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -17,7 +17,7 @@
 package com.android.server.wm;
 
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW;
+import static android.view.SurfaceControl.METADATA_OWNER_PID;
 import static android.view.SurfaceControl.METADATA_OWNER_UID;
 import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
 
@@ -105,6 +105,7 @@
                 .setFlags(flags)
                 .setMetadata(METADATA_WINDOW_TYPE, windowType)
                 .setMetadata(METADATA_OWNER_UID, ownerUid)
+                .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
                 .setCallsite("WindowSurfaceController");
 
         final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags &
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index aac60b4..da2c005 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -162,9 +162,10 @@
         "android.frameworks.schedulerservice@1.0",
         "android.frameworks.sensorservice@1.0",
         "android.frameworks.stats@1.0",
+        "android.system.suspend.control-cpp",
+        "android.system.suspend.control.internal-cpp",
         "android.system.suspend@1.0",
         "service.incremental",
-        "suspend_control_aidl_interface-cpp",
     ],
 
     static_libs: [
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index c1d5f19..3a00196 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -650,7 +650,7 @@
 
         base::Result<std::shared_ptr<KeyCharacterMap>> ret =
                 KeyCharacterMap::loadContents(filenameChars.c_str(), contentsChars.c_str(),
-                                              KeyCharacterMap::FORMAT_OVERLAY);
+                                              KeyCharacterMap::Format::OVERLAY);
         if (ret) {
             result = *ret;
         }
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 91f7072..63a6eed 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -24,6 +24,7 @@
 #include <android/hardware/power/Mode.h>
 #include <android/system/suspend/1.0/ISystemSuspend.h>
 #include <android/system/suspend/ISuspendControlService.h>
+#include <android/system/suspend/internal/ISuspendControlServiceInternal.h>
 #include <nativehelper/JNIHelp.h>
 #include "jni.h"
 
@@ -133,6 +134,8 @@
 
 static sp<ISystemSuspend> gSuspendHal = nullptr;
 static sp<ISuspendControlService> gSuspendControl = nullptr;
+static sp<system::suspend::internal::ISuspendControlServiceInternal> gSuspendControlInternal =
+        nullptr;
 static sp<IWakeLock> gSuspendBlocker = nullptr;
 static std::mutex gSuspendMutex;
 
@@ -157,10 +160,22 @@
     return gSuspendControl;
 }
 
+sp<system::suspend::internal::ISuspendControlServiceInternal> getSuspendControlInternal() {
+    static std::once_flag suspendControlFlag;
+    std::call_once(suspendControlFlag, []() {
+        gSuspendControlInternal =
+                waitForService<system::suspend::internal::ISuspendControlServiceInternal>(
+                        String16("suspend_control_internal"));
+        LOG_ALWAYS_FATAL_IF(gSuspendControlInternal == nullptr);
+    });
+    return gSuspendControlInternal;
+}
+
 void enableAutoSuspend() {
     static bool enabled = false;
     if (!enabled) {
-        sp<ISuspendControlService> suspendControl = getSuspendControl();
+        sp<system::suspend::internal::ISuspendControlServiceInternal> suspendControl =
+                getSuspendControlInternal();
         suspendControl->enableAutosuspend(&enabled);
     }
 
@@ -227,7 +242,7 @@
 
 static bool nativeForceSuspend(JNIEnv* /* env */, jclass /* clazz */) {
     bool retval = false;
-    getSuspendControl()->forceSuspend(&retval);
+    getSuspendControlInternal()->forceSuspend(&retval);
     return retval;
 }
 
diff --git a/services/core/xsd/cec-config/cec-config.xsd b/services/core/xsd/cec-config/cec-config.xsd
index 0801c88..b59c93c 100644
--- a/services/core/xsd/cec-config/cec-config.xsd
+++ b/services/core/xsd/cec-config/cec-config.xsd
@@ -12,6 +12,7 @@
   </xs:element>
   <xs:complexType name="setting">
     <xs:attribute name="name" type="xs:string"/>
+    <xs:attribute name="value-type" type="xs:string"/>
     <xs:attribute name="user-configurable" type="xs:boolean"/>
     <xs:element name="allowed-values" type="value-list" minOccurs="1" maxOccurs="1"/>
     <xs:element name="default-value" type="value" minOccurs="1" maxOccurs="1"/>
@@ -23,5 +24,6 @@
   </xs:complexType>
   <xs:complexType name="value">
     <xs:attribute name="string-value" type="xs:string"/>
+    <xs:attribute name="int-value" type="xs:string"/>
   </xs:complexType>
 </xs:schema>
diff --git a/services/core/xsd/cec-config/schema/current.txt b/services/core/xsd/cec-config/schema/current.txt
index 34faf45..75872d4 100644
--- a/services/core/xsd/cec-config/schema/current.txt
+++ b/services/core/xsd/cec-config/schema/current.txt
@@ -12,15 +12,19 @@
     method public com.android.server.hdmi.cec.config.Value getDefaultValue();
     method public String getName();
     method public boolean getUserConfigurable();
+    method public String getValueType();
     method public void setAllowedValues(com.android.server.hdmi.cec.config.ValueList);
     method public void setDefaultValue(com.android.server.hdmi.cec.config.Value);
     method public void setName(String);
     method public void setUserConfigurable(boolean);
+    method public void setValueType(String);
   }
 
   public class Value {
     ctor public Value();
+    method public String getIntValue();
     method public String getStringValue();
+    method public void setIntValue(String);
     method public void setStringValue(String);
   }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index 6fea2aa..412f582 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -36,10 +36,10 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.Slog;
 
-import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 import com.android.server.pm.UserRestrictionsUtils;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/CertificateMonitor.java b/services/devicepolicy/java/com/android/server/devicepolicy/CertificateMonitor.java
index fdde4ea..d812b8f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/CertificateMonitor.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/CertificateMonitor.java
@@ -177,7 +177,7 @@
 
         int parentUserId = userHandle.getIdentifier();
 
-        if (mService.getProfileOwner(userHandle.getIdentifier()) != null) {
+        if (mService.getProfileOwnerAsUser(userHandle.getIdentifier()) != null) {
             contentText = resources.getString(R.string.ssl_ca_cert_noti_managed,
                     mService.getProfileOwnerName(userHandle.getIdentifier()));
             smallIconId = R.drawable.stat_sys_certificate_info;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
index 279c678..3067d45 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
@@ -26,12 +26,12 @@
 import android.content.pm.ServiceInfo;
 import android.os.Handler;
 import android.os.IBinder;
+import android.util.IndentingPrintWriter;
 import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.BackgroundThread;
-import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.am.PersistentConnection;
 import com.android.server.appbinding.AppBindingUtils;
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
index d616ed3..15bc93e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
@@ -18,11 +18,11 @@
 import android.annotation.UserIdInt;
 import android.app.admin.DevicePolicyCache;
 import android.app.admin.DevicePolicyManager;
+import android.util.IndentingPrintWriter;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.IndentingPrintWriter;
 
 /**
  * Implementation of {@link DevicePolicyCache}, to which {@link DevicePolicyManagerService} pushes
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyConstants.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyConstants.java
index fec8a80..464d6f5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyConstants.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyConstants.java
@@ -15,11 +15,10 @@
  */
 package com.android.server.devicepolicy;
 
+import android.util.IndentingPrintWriter;
 import android.util.KeyValueListParser;
 import android.util.Slog;
 
-import com.android.internal.util.IndentingPrintWriter;
-
 import java.util.concurrent.TimeUnit;
 
 /**
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 3bfcb6d..767496d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -244,6 +244,7 @@
 import android.text.format.DateUtils;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
@@ -269,7 +270,6 @@
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
 import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
-import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.JournaledFile;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.StatLogger;
@@ -567,6 +567,11 @@
     final boolean mIsWatch;
 
     /**
+     * Whether or not this device is an automotive.
+     */
+    private final boolean mIsAutomotive;
+
+    /**
      * Whether this device has the telephony feature.
      */
     final boolean mHasTelephonyFeature;
@@ -1383,6 +1388,8 @@
                 .hasSystemFeature(PackageManager.FEATURE_WATCH);
         mHasTelephonyFeature = mInjector.getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+        mIsAutomotive = mInjector.getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
         mBackgroundHandler = BackgroundThread.getHandler();
 
         // Needed when mHasFeature == false, because it controls the certificate warning text.
@@ -3356,7 +3363,7 @@
     public boolean isSeparateProfileChallengeAllowed(int userHandle) {
         enforceSystemCaller("query separate challenge support");
 
-        ComponentName profileOwner = getProfileOwner(userHandle);
+        ComponentName profileOwner = getProfileOwnerAsUser(userHandle);
         // Profile challenge is supported on N or newer release.
         return profileOwner != null &&
                 getTargetSdk(profileOwner.getPackageName(), userHandle) > Build.VERSION_CODES.M;
@@ -4794,9 +4801,16 @@
 
                 // Require authentication for the device or profile
                 if (userToLock == UserHandle.USER_ALL) {
-                    // Power off the display
-                    mInjector.powerManagerGoToSleep(SystemClock.uptimeMillis(),
-                            PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
+                    if (mIsAutomotive) {
+                        if (VERBOSE_LOG) {
+                            Slog.v(LOG_TAG, "lockNow(): not powering off display on automotive"
+                                    + " build");
+                        }
+                    } else {
+                        // Power off the display
+                        mInjector.powerManagerGoToSleep(SystemClock.uptimeMillis(),
+                                PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
+                    }
                     mInjector.getIWindowManager().lockNow(null);
                 } else {
                     mInjector.getTrustManager().setDeviceLockedForUser(userToLock, true);
@@ -5290,7 +5304,7 @@
 
         final UserHandle caller = mInjector.binderGetCallingUserHandle();
         // If there is a profile owner, redirect to that; otherwise query the device owner.
-        ComponentName aliasChooser = getProfileOwner(caller.getIdentifier());
+        ComponentName aliasChooser = getProfileOwnerAsUser(caller.getIdentifier());
         if (aliasChooser == null && caller.isSystem()) {
             synchronized (getLockObject()) {
                 final ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked();
@@ -7346,7 +7360,7 @@
     }
 
     public boolean isProfileOwner(ComponentName who, int userId) {
-        final ComponentName profileOwner = getProfileOwner(userId);
+        final ComponentName profileOwner = getProfileOwnerAsUser(userId);
         return who != null && who.equals(profileOwner);
     }
 
@@ -7357,7 +7371,7 @@
      */
     public boolean isProfileOwner(CallerIdentity caller) {
         synchronized (getLockObject()) {
-            final ComponentName profileOwner = getProfileOwner(caller.getUserId());
+            final ComponentName profileOwner = getProfileOwnerAsUser(caller.getUserId());
             // No profile owner.
             if (profileOwner == null) {
                 return false;
@@ -7958,19 +7972,14 @@
 
     @Override
     public ComponentName getProfileOwnerAsUser(int userHandle) {
+        if (!mHasFeature) {
+            return null;
+        }
         Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
 
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(hasCrossUsersPermission(caller, userHandle));
 
-        return getProfileOwner(userHandle);
-    }
-
-    @Override
-    public ComponentName getProfileOwner(int userHandle) {
-        if (!mHasFeature) {
-            return null;
-        }
         synchronized (getLockObject()) {
             return mOwners.getProfileOwnerComponent(userHandle);
         }
@@ -8013,9 +8022,9 @@
         return mInjector.binderWithCleanCallingIdentity(() -> {
             for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
                 if (userInfo.isManagedProfile()) {
-                    if (getProfileOwner(userInfo.id) != null
+                    if (getProfileOwnerAsUser(userInfo.id) != null
                             && isProfileOwnerOfOrganizationOwnedDevice(userInfo.id)) {
-                        ComponentName who = getProfileOwner(userInfo.id);
+                        ComponentName who = getProfileOwnerAsUser(userInfo.id);
                         return getActiveAdminUncheckedLocked(who, userInfo.id);
                     }
                 }
@@ -8062,7 +8071,7 @@
         }
         Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity()));
 
-        ComponentName profileOwner = getProfileOwner(userHandle);
+        ComponentName profileOwner = getProfileOwnerAsUser(userHandle);
         if (profileOwner == null) {
             return null;
         }
@@ -8366,7 +8375,7 @@
             return false;
         }
 
-        final ComponentName profileOwner = getProfileOwner(userId);
+        final ComponentName profileOwner = getProfileOwnerAsUser(userId);
         if (profileOwner == null) {
             return false;
         }
@@ -8500,31 +8509,43 @@
     @Override
     protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, printWriter)) return;
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
 
-        synchronized (getLockObject()) {
+        try (IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ")) {
             pw.println("Current Device Policy Manager state:");
             pw.increaseIndent();
 
-            mOwners.dump(pw);
-            pw.println();
-            mDeviceAdminServiceController.dump(pw);
-            pw.println();
-            dumpDevicePolicyData(pw);
-            pw.println();
-            mConstants.dump(pw);
-            pw.println();
-            mStatLogger.dump(pw);
-            pw.println();
+            dumpImmutableState(pw);
+            synchronized (getLockObject()) {
+                mOwners.dump(pw);
+                pw.println();
+                mDeviceAdminServiceController.dump(pw);
+                pw.println();
+                dumpDevicePolicyData(pw);
+                pw.println();
+                mConstants.dump(pw);
+                pw.println();
+                mStatLogger.dump(pw);
+                pw.println();
 
-            pw.println("Encryption Status: " + getEncryptionStatusName(getEncryptionStatus()));
-            pw.println();
-            mPolicyCache.dump(pw);
-            pw.println();
-            mStateCache.dump(pw);
+                pw.println("Encryption Status: " + getEncryptionStatusName(getEncryptionStatus()));
+                pw.println();
+                mPolicyCache.dump(pw);
+                pw.println();
+                mStateCache.dump(pw);
+            }
         }
     }
 
+    private void dumpImmutableState(IndentingPrintWriter pw) {
+        pw.println("Immutable state:");
+        pw.increaseIndent();
+        pw.printf("mHasFeature=%b\n", mHasFeature);
+        pw.printf("mIsWatch=%b\n", mIsWatch);
+        pw.printf("mIsAutomotive=%b\n", mIsAutomotive);
+        pw.printf("mHasTelephonyFeature=%b\n", mHasTelephonyFeature);
+        pw.decreaseIndent();
+    }
+
     private String getEncryptionStatusName(int encryptionStatus) {
         switch (encryptionStatus) {
             case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE:
@@ -12039,7 +12060,7 @@
             // Managed-profiles cannot be setup on the system user.
             return CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER;
         }
-        if (getProfileOwner(callingUserId) != null) {
+        if (getProfileOwnerAsUser(callingUserId) != null) {
             // Managed user cannot have a managed profile.
             return CODE_USER_HAS_PROFILE_OWNER;
         }
@@ -12716,7 +12737,7 @@
             return true;
         }
 
-        final ComponentName profileOwner = getProfileOwner(userId);
+        final ComponentName profileOwner = getProfileOwnerAsUser(userId);
         if (profileOwner == null) {
             return false;
         }
@@ -12925,7 +12946,7 @@
         final int userId = caller.getUserId();
         enforceUserUnlocked(userId);
 
-        final ComponentName profileOwner = getProfileOwner(userId);
+        final ComponentName profileOwner = getProfileOwnerAsUser(userId);
         if (profileOwner != null && packageName.equals(profileOwner.getPackageName())) {
             throw new IllegalArgumentException("Cannot uninstall a package with a profile owner");
         }
@@ -14505,7 +14526,7 @@
             final List<ActiveAdmin> admins = new ArrayList<>();
             int[] users = mUserManager.getProfileIdsWithDisabled(UserHandle.getCallingUserId());
             for (int i = 0; i < users.length; i++) {
-                final ComponentName componentName = getProfileOwner(users[i]);
+                final ComponentName componentName = getProfileOwnerAsUser(users[i]);
                 if (componentName != null) {
                     ActiveAdmin admin = getActiveAdminUncheckedLocked(componentName, users[i]);
                     if (admin != null) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceStateCacheImpl.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceStateCacheImpl.java
index c3cb9b0..1215253 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceStateCacheImpl.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceStateCacheImpl.java
@@ -16,9 +16,9 @@
 package com.android.server.devicepolicy;
 
 import android.app.admin.DeviceStateCache;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.IndentingPrintWriter;
 
 /**
  * Implementation of {@link DeviceStateCache}, to which {@link DevicePolicyManagerService} pushes
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 7649af4..cced359 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -33,6 +33,7 @@
 import android.os.UserManagerInternal;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
+import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
@@ -42,7 +43,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 267c9b7..dfa726f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1345,7 +1345,7 @@
             mSystemServiceManager.startService(IorapForwardingService.class);
             t.traceEnd();
 
-            if (Build.IS_DEBUGGABLE) {
+            if (Build.IS_DEBUGGABLE && ProfcollectForwardingService.enabled()) {
                 t.traceBegin("ProfcollectForwardingService");
                 mSystemServiceManager.startService(ProfcollectForwardingService.class);
                 t.traceEnd();
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index d14ed5a..1944965 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -31,6 +31,7 @@
 import android.os.SystemProperties;
 import android.os.UpdateEngine;
 import android.os.UpdateEngineCallback;
+import android.provider.DeviceConfig;
 import android.util.Log;
 
 import com.android.server.IoThread;
@@ -68,6 +69,14 @@
         sSelfService = this;
     }
 
+    /**
+     * Check whether profcollect is enabled through device config.
+     */
+    public static boolean enabled() {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, "enabled",
+            false);
+    }
+
     @Override
     public void onStart() {
         if (DEBUG) {
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/FactoryPackageTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/FactoryPackageTest.kt
index 7ae2fe0..e17358d 100644
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/FactoryPackageTest.kt
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/FactoryPackageTest.kt
@@ -17,8 +17,11 @@
 class FactoryPackageTest : BaseHostJUnit4Test() {
 
     companion object {
+        private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app"
+
+        private const val VERSION_ONE = "PackageManagerTestAppVersion1.apk"
+        private const val VERSION_TWO = "PackageManagerTestAppVersion2.apk"
         private const val DEVICE_SIDE = "PackageManagerServiceDeviceSideTests.apk"
-        private const val DEVICE_SIDE_PKG_NAME = "com.android.server.pm.test.deviceside"
 
         @get:ClassRule
         val deviceRebootRule = SystemPreparer.TestRuleDelegate(true)
@@ -37,8 +40,7 @@
     @Before
     @After
     fun removeApk() {
-        HostUtils.deleteAllTestPackages(device, preparer)
-        device.uninstallPackage(DEVICE_SIDE_PKG_NAME)
+        device.uninstallPackage(TEST_PKG_NAME)
         device.deleteFile(filePath.parent.toString())
         device.reboot()
     }
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
index f0b60f4..9399030 100644
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
@@ -23,15 +23,6 @@
 import java.io.File
 import java.io.FileOutputStream
 
-internal const val TEST_PKG_NAME = "com.android.server.pm.test.test_app"
-internal const val VERSION_STUB = "PackageManagerTestAppStub.apk"
-internal const val VERSION_ONE = "PackageManagerTestAppVersion1.apk"
-internal const val VERSION_TWO = "PackageManagerTestAppVersion2.apk"
-internal const val VERSION_THREE = "PackageManagerTestAppVersion3.apk"
-internal const val VERSION_THREE_INVALID = "PackageManagerTestAppVersion3Invalid.apk"
-internal const val VERSION_FOUR = "PackageManagerTestAppVersion4.apk"
-internal const val VERSION_OVERRIDE = "PackageManagerTestAppOriginalOverride.apk"
-
 internal fun SystemPreparer.pushApk(javaResourceName: String, partition: Partition) =
         pushResourceFile(javaResourceName, HostUtils.makePathForApk(javaResourceName, partition)
                 .toString())
@@ -98,25 +89,12 @@
 
 internal object HostUtils {
 
-    /**
-     * Since most of the tests use the same test APKs, consolidate the logic for deleting them
-     * before and after a test runs. This also ensures that a failing test doesn't leave an APK on
-     * device that could spill over to another test when developing locally.
-     *
-     * Iterates all partitions since different tests use different partitions.
-     */
-    fun deleteAllTestPackages(device: ITestDevice, preparer: SystemPreparer) {
-        Partition.values().forEach { partition ->
-            device.uninstallPackage(TEST_PKG_NAME)
-            preparer.deleteApkFolders(partition, VERSION_ONE, VERSION_TWO, VERSION_THREE,
-                    VERSION_THREE_INVALID, VERSION_FOUR, VERSION_OVERRIDE)
-        }
-
-        // TODO: There is an optimization that can be made here by hooking into the SystemPreparer's
-        //  reboot rule, avoiding a reboot cycle by doing the delete in line the built in @After
-        //  reboot.
-        preparer.reboot()
-    }
+    fun getDataDir(device: ITestDevice, pkgName: String) =
+            device.executeShellCommand("dumpsys package $pkgName")
+                    .lineSequence()
+                    .map(String::trim)
+                    .single { it.startsWith("dataDir=") }
+                    .removePrefix("dataDir=")
 
     fun makePathForApk(fileName: String, partition: Partition) =
             makePathForApk(File(fileName), partition)
@@ -158,35 +136,14 @@
             }
             .map(String::trim)
 
-    fun getDataDir(device: ITestDevice, pkgName: String) =
-            packageSection(device, pkgName)
-                    .singleOrNull { it.startsWith("dataDir=") }
-                    ?.removePrefix("dataDir=")
-
-    /** Return all code paths for a package. This will include hidden system package code paths. */
     fun getCodePaths(device: ITestDevice, pkgName: String) =
-            (packageSection(device, pkgName) +
-                    packageSection(device, pkgName, "Hidden system packages"))
+            device.executeShellCommand("pm dump $pkgName")
+                    .lineSequence()
+                    .map(String::trim)
                     .filter { it.startsWith("codePath=") }
                     .map { it.removePrefix("codePath=") }
                     .toList()
 
-    fun getVersionCode(device: ITestDevice, pkgName: String) =
-            packageSection(device, pkgName)
-                    .filter { it.startsWith("versionCode=") }
-                    .map { it.removePrefix("versionCode=") }
-                    .map { it.takeWhile { !it.isWhitespace() } }
-                    .map { it.toInt() }
-                    .firstOrNull()
-
-    fun getPrivateFlags(device: ITestDevice, pkgName: String) =
-            packageSection(device, pkgName)
-                    .filter { it.startsWith("privateFlags=") }
-                    .map { it.removePrefix("privateFlags=[ ") }
-                    .map { it.removeSuffix(" ]") }
-                    .map { it.split(" ") }
-                    .firstOrNull()
-
     private fun userIdLineSequence(device: ITestDevice, pkgName: String) =
             packageSection(device, pkgName)
                     .filter { it.startsWith("User ") }
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/InvalidNewSystemAppTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/InvalidNewSystemAppTest.kt
index 8594706..37c999c 100644
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/InvalidNewSystemAppTest.kt
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/InvalidNewSystemAppTest.kt
@@ -33,6 +33,12 @@
 class InvalidNewSystemAppTest : BaseHostJUnit4Test() {
 
     companion object {
+        private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app"
+        private const val VERSION_ONE = "PackageManagerTestAppVersion1.apk"
+        private const val VERSION_TWO = "PackageManagerTestAppVersion2.apk"
+        private const val VERSION_THREE_INVALID = "PackageManagerTestAppVersion3Invalid.apk"
+        private const val VERSION_FOUR = "PackageManagerTestAppVersion4.apk"
+
         @get:ClassRule
         val deviceRebootRule = SystemPreparer.TestRuleDelegate(true)
     }
@@ -49,7 +55,7 @@
     @Before
     @After
     fun removeApk() {
-        HostUtils.deleteAllTestPackages(device, preparer)
+        device.uninstallPackage(TEST_PKG_NAME)
         preparer.deleteFile(filePath.parent.toString())
                 .reboot()
     }
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/OriginalPackageMigrationTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/OriginalPackageMigrationTest.kt
index 0c5816b..4becae6 100644
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/OriginalPackageMigrationTest.kt
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/OriginalPackageMigrationTest.kt
@@ -34,6 +34,10 @@
 
     companion object {
         private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app"
+        private const val VERSION_ONE = "PackageManagerTestAppVersion1.apk"
+        private const val VERSION_TWO = "PackageManagerTestAppVersion2.apk"
+        private const val VERSION_THREE = "PackageManagerTestAppVersion3.apk"
+        private const val NEW_PKG = "PackageManagerTestAppOriginalOverride.apk"
 
         @get:ClassRule
         val deviceRebootRule = SystemPreparer.TestRuleDelegate(true)
@@ -50,7 +54,9 @@
     @Before
     @After
     fun deleteApkFolders() {
-        HostUtils.deleteAllTestPackages(device, preparer)
+        preparer.deleteApkFolders(Partition.SYSTEM, VERSION_ONE, VERSION_TWO, VERSION_THREE,
+                NEW_PKG)
+                .reboot()
     }
 
     @Test
@@ -83,10 +89,10 @@
         device.pushFile(file, "${HostUtils.getDataDir(device, TEST_PKG_NAME)}/files/test.txt")
 
         preparer.deleteApkFolders(Partition.SYSTEM, apk)
-                .pushApk(VERSION_OVERRIDE, Partition.SYSTEM)
+                .pushApk(NEW_PKG, Partition.SYSTEM)
                 .reboot()
 
-        assertCodePath(VERSION_OVERRIDE)
+        assertCodePath(NEW_PKG)
 
         // And then reading the data contents back
         assertThat(device.pullFileContents(
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemAppScanPriorityTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemAppScanPriorityTest.kt
deleted file mode 100644
index 8d789e0..0000000
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemAppScanPriorityTest.kt
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.server.pm.test
-
-import com.android.internal.util.test.SystemPreparer
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.ClassRule
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.RuleChain
-import org.junit.rules.TemporaryFolder
-import org.junit.runner.RunWith
-import java.io.File
-
-/**
- * Pushes APKs onto various system partitions to verify that multiple versions result in the
- * highest version being scanned. Also tries to upgrade/replace these APKs which should result
- * in a version upgrade on reboot.
- *
- * This will also verify that APKs under the same folder/file name across different partitions
- * are parsed as separate entities and don't get combined under the same cache entry.
- *
- * Known limitations:
- * - Does not verify that v1 isn't scanned. It's possible to introduce a bug that upgrades the
- *     system on every reboot from v1 -> v2, as this isn't easily visible after scan has finished.
- *     This would also have to successfully preserve the app data though, which seems unlikely.
- * - This takes a very long time to run. 105 seconds for the first test case, up to 60 seconds for
- *     each following case. It's theoretically possible to parallelize these tests so that each
- *     method is run by installing all the apps under different names, requiring only 3 reboots to
- *     fully verify, rather than 3 * numTestCases.
- */
-@RunWith(DeviceJUnit4ClassRunner::class)
-class SystemAppScanPriorityTest : BaseHostJUnit4Test() {
-
-    companion object {
-        @get:ClassRule
-        var deviceRebootRule = SystemPreparer.TestRuleDelegate(true)
-    }
-
-    private val tempFolder = TemporaryFolder()
-    private val preparer: SystemPreparer = SystemPreparer(tempFolder,
-            SystemPreparer.RebootStrategy.FULL, deviceRebootRule) { this.device }
-
-    private var firstReboot = true
-
-    @Rule
-    @JvmField
-    val rules = RuleChain.outerRule(tempFolder).around(preparer)!!
-
-    @Before
-    @After
-    fun deleteFiles() {
-        HostUtils.deleteAllTestPackages(device, preparer)
-    }
-
-    @Before
-    fun resetFirstReboot() {
-        firstReboot = true
-    }
-
-    @Test
-    fun takeHigherPriority() {
-        preparer.pushFile(VERSION_ONE, Partition.VENDOR)
-                .pushFile(VERSION_TWO, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.PRODUCT)
-    }
-
-    @Test
-    fun takeLowerPriority() {
-        preparer.pushFile(VERSION_TWO, Partition.VENDOR)
-                .pushFile(VERSION_ONE, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.VENDOR)
-    }
-
-    @Test
-    fun upgradeToHigherOnLowerPriority() {
-        preparer.pushFile(VERSION_ONE, Partition.VENDOR)
-                .pushFile(VERSION_TWO, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.PRODUCT)
-
-        preparer.pushFile(VERSION_THREE, Partition.VENDOR)
-                .rebootForTest()
-
-        assertVersionAndPartition(3, Partition.VENDOR)
-    }
-
-    @Test
-    fun upgradeToNewerOnHigherPriority() {
-        preparer.pushFile(VERSION_ONE, Partition.VENDOR)
-                .pushFile(VERSION_TWO, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.PRODUCT)
-
-        preparer.pushFile(VERSION_THREE, Partition.SYSTEM_EXT)
-                .rebootForTest()
-
-        assertVersionAndPartition(3, Partition.SYSTEM_EXT)
-    }
-
-    @Test
-    fun replaceNewerOnLowerPriority() {
-        preparer.pushFile(VERSION_TWO, Partition.VENDOR)
-                .pushFile(VERSION_ONE, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.VENDOR)
-
-        preparer.pushFile(VERSION_THREE, Partition.VENDOR)
-                .rebootForTest()
-
-        assertVersionAndPartition(3, Partition.VENDOR)
-    }
-
-    @Test
-    fun replaceNewerOnHigherPriority() {
-        preparer.pushFile(VERSION_ONE, Partition.VENDOR)
-                .pushFile(VERSION_TWO, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.PRODUCT)
-
-        preparer.pushFile(VERSION_THREE, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertVersionAndPartition(3, Partition.PRODUCT)
-    }
-
-    @Test
-    fun fallbackToLowerPriority() {
-        preparer.pushFile(VERSION_TWO, Partition.VENDOR)
-                .pushFile(VERSION_ONE, Partition.PRODUCT)
-                .pushFile(VERSION_THREE, Partition.SYSTEM_EXT)
-                .rebootForTest()
-
-        assertVersionAndPartition(3, Partition.SYSTEM_EXT)
-
-        preparer.deleteFile(VERSION_THREE, Partition.SYSTEM_EXT)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.VENDOR)
-    }
-
-    @Test
-    fun fallbackToHigherPriority() {
-        preparer.pushFile(VERSION_THREE, Partition.VENDOR)
-                .pushFile(VERSION_ONE, Partition.PRODUCT)
-                .pushFile(VERSION_TWO, Partition.SYSTEM_EXT)
-                .rebootForTest()
-
-        assertVersionAndPartition(3, Partition.VENDOR)
-
-        preparer.deleteFile(VERSION_THREE, Partition.VENDOR)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.SYSTEM_EXT)
-    }
-
-    @Test
-    fun removeBoth() {
-        preparer.pushFile(VERSION_ONE, Partition.VENDOR)
-                .pushFile(VERSION_TWO, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertVersionAndPartition(2, Partition.PRODUCT)
-
-        preparer.deleteFile(VERSION_ONE, Partition.VENDOR)
-                .deleteFile(VERSION_TWO, Partition.PRODUCT)
-                .rebootForTest()
-
-        assertThat(device.getAppPackageInfo(TEST_PKG_NAME)).isNull()
-    }
-
-    private fun assertVersionAndPartition(versionCode: Int, partition: Partition) {
-        assertThat(HostUtils.getVersionCode(device, TEST_PKG_NAME)).isEqualTo(versionCode)
-
-        val privateFlags = HostUtils.getPrivateFlags(device, TEST_PKG_NAME)
-
-        when (partition) {
-            Partition.SYSTEM,
-            Partition.SYSTEM_PRIVILEGED -> {
-                assertThat(privateFlags).doesNotContain(Partition.VENDOR.toString())
-                assertThat(privateFlags).doesNotContain(Partition.PRODUCT.toString())
-                assertThat(privateFlags).doesNotContain(Partition.SYSTEM_EXT.toString())
-            }
-            Partition.VENDOR -> {
-                assertThat(privateFlags).contains(Partition.VENDOR.toString())
-                assertThat(privateFlags).doesNotContain(Partition.PRODUCT.toString())
-                assertThat(privateFlags).doesNotContain(Partition.SYSTEM_EXT.toString())
-            }
-            Partition.PRODUCT -> {
-                assertThat(privateFlags).doesNotContain(Partition.VENDOR.toString())
-                assertThat(privateFlags).contains(Partition.PRODUCT.toString())
-                assertThat(privateFlags).doesNotContain(Partition.SYSTEM_EXT.toString())
-            }
-            Partition.SYSTEM_EXT -> {
-                assertThat(privateFlags).doesNotContain(Partition.VENDOR.toString())
-                assertThat(privateFlags).doesNotContain(Partition.PRODUCT.toString())
-                assertThat(privateFlags).contains(Partition.SYSTEM_EXT.toString())
-            }
-        }.run { /* exhaust */ }
-    }
-
-    // Following methods don't use HostUtils in order to test cache behavior when using the same
-    // name across partitions. Writes all files under the version 1 name.
-    private fun makeDevicePath(partition: Partition) =
-            partition.baseAppFolder
-                    .resolve(File(VERSION_ONE).nameWithoutExtension)
-                    .resolve(VERSION_ONE)
-                    .toString()
-
-    private fun SystemPreparer.pushFile(file: String, partition: Partition) =
-            pushResourceFile(file, makeDevicePath(partition))
-
-    private fun SystemPreparer.deleteFile(file: String, partition: Partition) =
-            deleteFile(makeDevicePath(partition))
-
-    /**
-     * Custom reboot used to write app data after the first reboot. This can then be verified
-     * after each subsequent reboot to ensure no data is lost.
-     */
-    private fun SystemPreparer.rebootForTest() {
-        if (firstReboot) {
-            firstReboot = false
-            preparer.reboot()
-
-            val file = tempFolder.newFile()
-            file.writeText("Test")
-            pushFile(file, "${HostUtils.getDataDir(device, TEST_PKG_NAME)}/files/test.txt")
-        } else {
-            val versionBefore = HostUtils.getVersionCode(device, TEST_PKG_NAME)
-            preparer.reboot()
-            val versionAfter = HostUtils.getVersionCode(device, TEST_PKG_NAME)
-
-            if (versionBefore != null && versionAfter != null) {
-                val fileContents = device.pullFileContents(
-                        "${HostUtils.getDataDir(device, TEST_PKG_NAME)}/files/test.txt")
-                if (versionAfter < versionBefore) {
-                    // A downgrade will wipe app data
-                    assertThat(fileContents).isNull()
-                } else {
-                    // An upgrade or update will preserve app data
-                    assertThat(fileContents).isEqualTo("Test")
-                }
-            }
-        }
-    }
-}
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt
index 99dff08..46120af 100644
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt
@@ -37,6 +37,9 @@
 class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
 
     companion object {
+        private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app"
+        private const val VERSION_STUB = "PackageManagerTestAppStub.apk"
+        private const val VERSION_ONE = "PackageManagerTestAppVersion1.apk"
 
         /**
          * How many total users on device to test, including primary. This will clean up any
@@ -87,12 +90,6 @@
                 savedDevice?.removeUser(it)
             }
 
-            savedDevice?.let { device ->
-                savedPreparer?.let { preparer ->
-                    HostUtils.deleteAllTestPackages(device, preparer)
-                }
-            }
-
             savedDevice?.uninstallPackage(TEST_PKG_NAME)
             savedDevice?.deleteFile(stubFile.parent.toString())
             savedDevice?.deleteFile(deviceCompressedFile.parent.toString())
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index 736a7be..da4071b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -27,9 +27,11 @@
 import static com.android.server.RescueParty.LEVEL_FACTORY_RESET;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 
 import android.content.ContentResolver;
@@ -79,8 +81,11 @@
     private static final String CALLING_PACKAGE2 = "com.package.name2";
     private static final String NAMESPACE1 = "namespace1";
     private static final String NAMESPACE2 = "namespace2";
+    private static final String NAMESPACE3 = "namespace3";
     private static final String PROP_DEVICE_CONFIG_DISABLE_FLAG =
             "persist.device_config.configuration.disable_rescue_party";
+    private static final String PROP_DISABLE_FACTORY_RESET_FLAG =
+            "persist.device_config.configuration.disable_rescue_party_factory_reset";
 
     private MockitoSession mSession;
     private HashMap<String, String> mSystemSettingsMap;
@@ -183,56 +188,58 @@
 
     @Test
     public void testBootLoopDetectionWithExecutionForAllRescueLevels() {
+        RescueParty.onSettingsProviderPublished(mMockContext);
+        verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver),
+                mMonitorCallbackCaptor.capture()));
+
         noteBoot();
 
         verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null);
         assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS,
                 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
 
+        // Record DeviceConfig accesses
+        RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
+        RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue();
+        monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1));
+        monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2));
+
+        final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
+
         noteBoot();
 
-        verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, /*resetNamespaces=*/ null);
+        verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedAllResetNamespaces);
         assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES,
                 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
 
         noteBoot();
 
-        verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/ null);
+        verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces);
         assertEquals(RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS,
                 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
 
         noteBoot();
 
-        verify(() -> RecoverySystem.rebootPromptAndWipeUserData(mMockContext, RescueParty.TAG));
         assertEquals(LEVEL_FACTORY_RESET,
                 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
     }
 
     @Test
     public void testPersistentAppCrashDetectionWithExecutionForAllRescueLevels() {
-        notePersistentAppCrash();
+        notePersistentAppCrash(1);
 
         verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null);
-        assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS,
-                SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
 
-        notePersistentAppCrash();
+        notePersistentAppCrash(2);
 
         verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, /*resetNamespaces=*/ null);
-        assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES,
-                SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
 
-        notePersistentAppCrash();
+        notePersistentAppCrash(3);
 
         verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/ null);
-        assertEquals(RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS,
-                SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
 
-        notePersistentAppCrash();
-
-        verify(() -> RecoverySystem.rebootPromptAndWipeUserData(mMockContext, RescueParty.TAG));
-        assertEquals(LEVEL_FACTORY_RESET,
-                SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
+        notePersistentAppCrash(4);
+        assertTrue(RescueParty.isAttemptingFactoryReset());
     }
 
     @Test
@@ -247,6 +254,7 @@
         monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1));
         monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2));
         monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2));
+        monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3));
         // Fake DeviceConfig value changes
         monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1));
         verify(mMockPackageWatchdog).startObservingHealth(observer,
@@ -255,31 +263,29 @@
         verify(mMockPackageWatchdog, times(2)).startObservingHealth(eq(observer),
                 mPackageListCaptor.capture(),
                 eq(RescueParty.DEFAULT_OBSERVING_DURATION_MS));
+        monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3));
+        verify(mMockPackageWatchdog).startObservingHealth(observer,
+                Arrays.asList(CALLING_PACKAGE2), RescueParty.DEFAULT_OBSERVING_DURATION_MS);
         assertTrue(mPackageListCaptor.getValue().containsAll(
                 Arrays.asList(CALLING_PACKAGE1, CALLING_PACKAGE2)));
         // Perform and verify scoped resets
         final String[] expectedResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
+        final String[] expectedAllResetNamespaces =
+                new String[]{NAMESPACE1, NAMESPACE2, NAMESPACE3};
         observer.execute(new VersionedPackage(
-                CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+                CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
         verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, expectedResetNamespaces);
-        assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS,
-                SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
 
         observer.execute(new VersionedPackage(
-                CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
+                CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2);
         verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedResetNamespaces);
-        assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES,
-                SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
 
         observer.execute(new VersionedPackage(
-                CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
-        verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/null);
-        assertEquals(RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS,
-                SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
+                CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3);
+        verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces);
 
         observer.execute(new VersionedPackage(
-                CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH);
-        verify(() -> RecoverySystem.rebootPromptAndWipeUserData(mMockContext, RescueParty.TAG));
+                CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4);
         assertTrue(RescueParty.isAttemptingFactoryReset());
     }
 
@@ -288,7 +294,6 @@
         for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
             noteBoot();
         }
-        verify(() -> RecoverySystem.rebootPromptAndWipeUserData(mMockContext, RescueParty.TAG));
         assertTrue(RescueParty.isAttemptingFactoryReset());
     }
 
@@ -322,11 +327,11 @@
         SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
         SystemProperties.set(PROP_DISABLE_RESCUE, Boolean.toString(true));
         assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
-                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), false);
+                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false);
 
         SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
         assertTrue(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
-                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING));
+                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1));
     }
 
     @Test
@@ -335,58 +340,49 @@
         SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(true));
 
         assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
-                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), false);
+                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false);
 
-        // Restore the property value initalized in SetUp()
+        // Restore the property value initialized in SetUp()
         SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
         SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false));
     }
 
     @Test
+    public void testDisablingFactoryResetByDeviceConfigFlag() {
+        SystemProperties.set(PROP_DISABLE_FACTORY_RESET_FLAG, Boolean.toString(true));
+
+        for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
+            noteBoot();
+        }
+        assertFalse(RescueParty.isAttemptingFactoryReset());
+
+        // Restore the property value initialized in SetUp()
+        SystemProperties.set(PROP_DISABLE_FACTORY_RESET_FLAG, "");
+    }
+
+    @Test
     public void testHealthCheckLevels() {
         RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
 
         // Ensure that no action is taken for cases where the failure reason is unknown
-        SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(
-                LEVEL_FACTORY_RESET));
-        assertEquals(observer.onHealthCheckFailed(null, PackageWatchdog.FAILURE_REASON_UNKNOWN),
+        assertEquals(observer.onHealthCheckFailed(null, PackageWatchdog.FAILURE_REASON_UNKNOWN, 1),
                 PackageHealthObserverImpact.USER_IMPACT_NONE);
 
-        /*
-        For the following cases, ensure that the returned user impact corresponds with the user
-        impact of the next available rescue level, not the current one.
-         */
-        SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(
-                RescueParty.LEVEL_NONE));
+        // Ensure the correct user impact is returned for each mitigation count.
         assertEquals(observer.onHealthCheckFailed(null,
-                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING),
+                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1),
                 PackageHealthObserverImpact.USER_IMPACT_LOW);
 
-        SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(
-                RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS));
         assertEquals(observer.onHealthCheckFailed(null,
-                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING),
+                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2),
                 PackageHealthObserverImpact.USER_IMPACT_LOW);
 
-
-        SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(
-                RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES));
         assertEquals(observer.onHealthCheckFailed(null,
-                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING),
+                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3),
                 PackageHealthObserverImpact.USER_IMPACT_HIGH);
 
-
-        SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(
-                RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS));
         assertEquals(observer.onHealthCheckFailed(null,
-                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING),
-                PackageHealthObserverImpact.USER_IMPACT_HIGH);
-
-
-        SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(
-                LEVEL_FACTORY_RESET));
-        assertEquals(observer.onHealthCheckFailed(null,
-                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING),
+                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4),
                 PackageHealthObserverImpact.USER_IMPACT_HIGH);
     }
 
@@ -419,17 +415,6 @@
         assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_HIGH);
     }
 
-    @Test
-    public void testRescueLevelIncrementsWhenExecuted() {
-        RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
-        SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(
-                RescueParty.LEVEL_NONE));
-        observer.execute(sFailingPackage,
-                PackageWatchdog.FAILURE_REASON_APP_CRASH);
-        assertEquals(SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, -1),
-                RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS);
-    }
-
     private void verifySettingsResets(int resetMode, String[] resetNamespaces) {
         verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null,
                 resetMode, UserHandle.USER_SYSTEM));
@@ -437,7 +422,7 @@
                 eq(resetMode), anyInt()));
         // Verify DeviceConfig resets
         if (resetNamespaces == null) {
-            verify(() -> DeviceConfig.resetToDefaults(resetMode, /*namespace=*/ null));
+            verify(() -> DeviceConfig.resetToDefaults(anyInt(), anyString()), never());
         } else {
             for (String namespace : resetNamespaces) {
                 verify(() -> DeviceConfig.resetToDefaults(resetMode, namespace));
@@ -449,9 +434,9 @@
         RescuePartyObserver.getInstance(mMockContext).executeBootLoopMitigation();
     }
 
-    private void notePersistentAppCrash() {
+    private void notePersistentAppCrash(int mitigationCount) {
         RescuePartyObserver.getInstance(mMockContext).execute(new VersionedPackage(
-                "com.package.name", 1), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+                "com.package.name", 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, mitigationCount);
     }
 
     private Bundle getConfigAccessBundle(String callingPackage, String namespace) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index db4aba5..8e4942e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -47,6 +47,7 @@
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_LONG_TIME;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_SHORT_TIME;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
+import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LAZY_BATCHING;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_FUTURITY;
@@ -62,6 +63,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -365,7 +367,7 @@
     }
 
     private void setIdleUntilAlarm(int type, long triggerTime, PendingIntent pi) {
-        setTestAlarm(type, triggerTime, pi, 0, FLAG_IDLE_UNTIL, TEST_CALLING_UID);
+        setTestAlarm(type, triggerTime, pi, 0, FLAG_IDLE_UNTIL | FLAG_STANDALONE, TEST_CALLING_UID);
     }
 
     private void setWakeFromIdle(int type, long triggerTime, PendingIntent pi) {
@@ -410,6 +412,12 @@
         mService.mConstants.onPropertiesChanged(mDeviceConfigProperties);
     }
 
+    private void setDeviceConfigBoolean(String key, boolean val) {
+        mDeviceConfigKeys.add(key);
+        doReturn(val).when(mDeviceConfigProperties).getBoolean(eq(key), anyBoolean());
+        mService.mConstants.onPropertiesChanged(mDeviceConfigProperties);
+    }
+
     /**
      * Lowers quotas to make testing feasible. Careful while calling as this will replace any
      * existing settings for the calling test.
@@ -1382,6 +1390,35 @@
         }
     }
 
+    @Test
+    public void alarmStoreMigration() {
+        setDeviceConfigBoolean(KEY_LAZY_BATCHING, false);
+        final int numAlarms = 10;
+        final PendingIntent[] pis = new PendingIntent[numAlarms];
+        for (int i = 0; i < numAlarms; i++) {
+            pis[i] = getNewMockPendingIntent();
+            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 1, pis[i]);
+        }
+
+        final ArrayList<Alarm> alarmsBefore = mService.mAlarmStore.asList();
+        assertEquals(numAlarms, alarmsBefore.size());
+        for (int i = 0; i < numAlarms; i++) {
+            final PendingIntent pi = pis[i];
+            assertTrue(i + "th PendingIntent missing: ",
+                    alarmsBefore.removeIf(a -> a.matches(pi, null)));
+        }
+
+        setDeviceConfigBoolean(KEY_LAZY_BATCHING, true);
+
+        final ArrayList<Alarm> alarmsAfter = mService.mAlarmStore.asList();
+        assertEquals(numAlarms, alarmsAfter.size());
+        for (int i = 0; i < numAlarms; i++) {
+            final PendingIntent pi = pis[i];
+            assertTrue(i + "th PendingIntent missing: ",
+                    alarmsAfter.removeIf(a -> a.matches(pi, null)));
+        }
+    }
+
     @After
     public void tearDown() {
         if (mMockingSession != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
index c4fc61a..42fa3d4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
@@ -16,6 +16,9 @@
 
 package com.android.server.alarm;
 
+import static android.app.AlarmManager.ELAPSED_REALTIME;
+import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
+
 import static com.android.server.alarm.Constants.TEST_CALLING_PACKAGE;
 import static com.android.server.alarm.Constants.TEST_CALLING_UID;
 
@@ -23,35 +26,50 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 import java.util.ArrayList;
 
 @Presubmit
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 public class AlarmStoreTest {
-    private AlarmStore mAlarmStore;
 
-    @Before
-    public void setUp() {
-        mAlarmStore = new BatchingAlarmStore(null);
+    @Parameter
+    public AlarmStore mAlarmStore;
+
+    @Parameters
+    public static Object[] stores() {
+        return new AlarmStore[]{
+                new LazyAlarmStore(),
+                new BatchingAlarmStore(),
+        };
     }
 
     private static Alarm createAlarm(long whenElapsed, long windowLength) {
-        return createAlarm(AlarmManager.ELAPSED_REALTIME, whenElapsed, windowLength, 0);
+        return createAlarm(ELAPSED_REALTIME, whenElapsed, windowLength, 0);
     }
 
     private static Alarm createWakeupAlarm(long whenElapsed, long windowLength, int flags) {
-        return createAlarm(AlarmManager.ELAPSED_REALTIME_WAKEUP, whenElapsed, windowLength, flags);
+        return createAlarm(ELAPSED_REALTIME_WAKEUP, whenElapsed, windowLength, flags);
+    }
+
+    private static Alarm createAlarmClock(long whenElapsed) {
+        final AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(whenElapsed,
+                mock(PendingIntent.class));
+        return new Alarm(ELAPSED_REALTIME_WAKEUP, whenElapsed, whenElapsed, 0, 0,
+                mock(PendingIntent.class), null, null, null, 0, info, TEST_CALLING_UID,
+                TEST_CALLING_PACKAGE);
     }
 
     private static Alarm createAlarm(int type, long whenElapsed, long windowLength, int flags) {
@@ -206,4 +224,21 @@
         });
         assertEquals(7, mAlarmStore.getNextDeliveryTime());
     }
+
+    @Test
+    public void alarmClockRemovalListener() {
+        final Runnable onRemoved = mock(Runnable.class);
+        mAlarmStore.setAlarmClockRemovalListener(onRemoved);
+
+        final Alarm simpleAlarm = createAlarm(5, 0);
+        final Alarm alarmClock = createAlarmClock(10);
+
+        addAlarmsToStore(simpleAlarm, alarmClock);
+
+        mAlarmStore.remove(simpleAlarm::equals);
+        verifyZeroInteractions(onRemoved);
+
+        mAlarmStore.remove(alarmClock::equals);
+        verify(onRemoved).run();
+    }
 }
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 5c2b8ce..b955199 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
@@ -27,17 +27,18 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.view.SurfaceControl;
-import android.view.SurfaceControl.DisplayPrimaries;
 import android.view.SurfaceControl.CieXyz;
+import android.view.SurfaceControl.DisplayPrimaries;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.R;
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.R;
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -190,6 +191,7 @@
      * Matrix should match the precalculated one for given cct and display primaries.
      */
     @Test
+    @Ignore
     public void displayWhiteBalance_validateTransformMatrix() {
         DisplayPrimaries displayPrimaries = new DisplayPrimaries();
         displayPrimaries.red = new CieXyz();
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 26fd0a2..6ead95c 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -85,6 +85,7 @@
     <uses-permission android:name="android.permission.VIBRATE"/>
     <uses-permission android:name="android.permission.ACCESS_VIBRATOR_STATE"/>
     <uses-permission android:name="android.permission.VIBRATE_ALWAYS_ON"/>
+    <uses-permission android:name="android.permission.CONTROL_DEVICE_STATE"/>
 
     <!-- Uses API introduced in O (26) -->
     <uses-sdk android:minSdkVersion="1"
diff --git a/services/tests/servicestests/src/android/location/timezone/LocationTimeZoneEventTest.java b/services/tests/servicestests/src/android/location/timezone/LocationTimeZoneEventTest.java
index f9dd7dc..80373ac 100644
--- a/services/tests/servicestests/src/android/location/timezone/LocationTimeZoneEventTest.java
+++ b/services/tests/servicestests/src/android/location/timezone/LocationTimeZoneEventTest.java
@@ -23,8 +23,6 @@
 
 import static java.util.Collections.singletonList;
 
-import android.os.UserHandle;
-
 import org.junit.Test;
 
 import java.util.List;
@@ -35,10 +33,6 @@
 
     private static final List<String> ARBITRARY_TIME_ZONE_IDS = singletonList("Europe/London");
 
-    private static final UserHandle ARBITRARY_USER_HANDLE = UserHandle.SYSTEM;
-    private static final UserHandle ARBITRARY_USER_HANDLE2 =
-            UserHandle.of(ARBITRARY_USER_HANDLE.getIdentifier() + 1);
-
     @Test(expected = RuntimeException.class)
     public void testSetInvalidEventType() {
         new LocationTimeZoneEvent.Builder().setEventType(Integer.MAX_VALUE);
@@ -47,7 +41,6 @@
     @Test(expected = RuntimeException.class)
     public void testBuildUnsetEventType() {
         new LocationTimeZoneEvent.Builder()
-                .setUserHandle(ARBITRARY_USER_HANDLE)
                 .setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS)
                 .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS)
                 .build();
@@ -56,7 +49,6 @@
     @Test(expected = RuntimeException.class)
     public void testInvalidTimeZoneIds() {
         new LocationTimeZoneEvent.Builder()
-                .setUserHandle(ARBITRARY_USER_HANDLE)
                 .setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
                 .setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS)
                 .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS)
@@ -66,7 +58,6 @@
     @Test
     public void testEquals() {
         LocationTimeZoneEvent.Builder builder1 = new LocationTimeZoneEvent.Builder()
-                .setUserHandle(ARBITRARY_USER_HANDLE)
                 .setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
                 .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS);
         {
@@ -75,7 +66,6 @@
         }
 
         LocationTimeZoneEvent.Builder builder2 = new LocationTimeZoneEvent.Builder()
-                .setUserHandle(ARBITRARY_USER_HANDLE)
                 .setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
                 .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS);
         {
@@ -85,22 +75,6 @@
             assertEquals(two, one);
         }
 
-        builder1.setUserHandle(ARBITRARY_USER_HANDLE2);
-        {
-            LocationTimeZoneEvent one = builder1.build();
-            LocationTimeZoneEvent two = builder2.build();
-            assertNotEquals(one, two);
-            assertNotEquals(two, one);
-        }
-
-        builder2.setUserHandle(ARBITRARY_USER_HANDLE2);
-        {
-            LocationTimeZoneEvent one = builder1.build();
-            LocationTimeZoneEvent two = builder2.build();
-            assertEquals(one, two);
-            assertEquals(two, one);
-        }
-
         builder1.setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS + 1);
         {
             LocationTimeZoneEvent one = builder1.build();
@@ -153,7 +127,6 @@
     @Test
     public void testParcelable() {
         LocationTimeZoneEvent.Builder builder = new LocationTimeZoneEvent.Builder()
-                .setUserHandle(ARBITRARY_USER_HANDLE)
                 .setEventType(LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE)
                 .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS);
         assertRoundTripParcelable(builder.build());
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/GestureManifoldTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/GestureManifoldTest.java
index 538e2d5..0e78785 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/GestureManifoldTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/GestureManifoldTest.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.os.Handler;
 import android.view.MotionEvent;
 
 import androidx.test.InstrumentationRegistry;
@@ -56,7 +57,8 @@
         // Construct a testable GestureManifold.
         mResultListener = mock(GestureManifold.Listener.class);
         mState = new TouchState();
-        mManifold = new GestureManifold(context, mResultListener, mState);
+        Handler handler = new Handler(context.getMainLooper());
+        mManifold = new GestureManifold(context, mResultListener, mState, handler);
         // Play the role of touch explorer in updating the shared state.
         when(mResultListener.onGestureStarted()).thenReturn(onGestureStarted());
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
index dda81ff..89bd625 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.accessibility.gestures;
 
+import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_HOVER_ENTER;
 import static android.view.MotionEvent.ACTION_HOVER_EXIT;
@@ -33,7 +34,7 @@
 import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_EXPLORING;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
 import android.graphics.PointF;
@@ -127,10 +128,9 @@
         mContext = InstrumentationRegistry.getContext();
         mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
         AccessibilityManagerService ams = new AccessibilityManagerService(mContext);
-        GestureManifold detector = mock(GestureManifold.class);
         mCaptor = new EventCaptor();
         mHandler = new TestHandler();
-        mTouchExplorer = new TouchExplorer(mContext, ams, detector, mHandler);
+        mTouchExplorer = new TouchExplorer(mContext, ams, null, mHandler);
         mTouchExplorer.setNext(mCaptor);
     }
 
@@ -174,6 +174,42 @@
     }
 
     /**
+     * Test the case where the event location is correct when clicking after the following
+     * situation happened: entering the delegate state through doubleTapAndHold gesture and
+     * receiving a cancel event to return the clear state.
+     */
+    @Test
+    public void testClick_afterCanceledDoubleTapAndHold_eventLocationIsCorrect() {
+        // Generates the click position by this click operation, otherwise the offset used
+        // while delegating could not be set.
+        send(downEvent(DEFAULT_X + 10, DEFAULT_Y + 10));
+        // Waits for transition to touch exploring state.
+        mHandler.fastForward(2 * USER_INTENT_TIMEOUT);
+        send(upEvent());
+
+        // Simulates detecting the doubleTapAndHold gesture and enters the delegate state.
+        final MotionEvent sendEvent =
+                fromTouchscreen(downEvent(DEFAULT_X + 100, DEFAULT_Y + 100));
+        mTouchExplorer.onDoubleTapAndHold(sendEvent, sendEvent, 0);
+        assertState(STATE_DELEGATING);
+
+        send(cancelEvent());
+
+        // Generates the click operation, and checks the event location of the ACTION_HOVER_ENTER
+        // event is correct.
+        send(downEvent());
+        // Waits for transition to touch exploring state.
+        mHandler.fastForward(2 * USER_INTENT_TIMEOUT);
+        send(upEvent());
+
+        final List<MotionEvent> events = getCapturedEvents();
+        assertTrue(events.stream().anyMatch(
+                motionEvent -> motionEvent.getActionMasked() == ACTION_HOVER_ENTER
+                        && motionEvent.getX() == DEFAULT_X
+                        && motionEvent.getY() == DEFAULT_Y));
+    }
+
+    /**
      * Test the case where ACTION_POINTER_DOWN is followed by a number of ACTION_MOVE events that do
      * not change the coordinates.
      */
@@ -234,8 +270,8 @@
         // Wait for the views responding to hover enter/move events.
         mHandler.fastForward(oneThirdUserIntentTimeout);
         // Simulate receiving the a11y exit event sent by the first view.
-        AccessibilityEvent a11yExitEvent = AccessibilityEvent.obtain(
-                AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+        AccessibilityEvent a11yExitEvent =
+                AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
         mTouchExplorer.onAccessibilityEvent(a11yExitEvent);
 
         // Wait for running the hover exit event runnable. After it, touch-exploration end event
@@ -326,6 +362,39 @@
         assertCapturedEventsNoHistory();
     }
 
+    @Test
+    public void testCanceledGesture_shouldDoNothing() {
+        mTouchExplorer.setMultiFingerGesturesEnabled(true);
+        mTouchExplorer.setTwoFingerPassthroughEnabled(true);
+        // Start a three-finger swipe.
+        send(downEvent());
+        send(pointerDownEvent());
+        send(thirdPointerDownEvent());
+        moveEachPointers(mLastEvent, p(0, 200), p(0, 200), p(0, 200));
+        send(mLastEvent);
+        assertState(STATE_GESTURE_DETECTING);
+        mHandler.fastForward(2 * (int) Swipe.MAX_TIME_TO_CONTINUE_SWIPE_MS);
+        // Lift the third finger but keep the other two going.
+        send(thirdPointerUpEvent());
+        // Manually construct the next move event. Using moveEachPointers() will batch the move
+        // event onto the pointer up event which will mean that the move event still has a pointer
+        // count of 3.
+        // Todo: refactor to avoid using batching as there is no special reason to do it that way.
+        float[] x = new float[2];
+        float[] y = new float[2];
+        x[0] = mLastEvent.getX(0) + 100;
+        x[1] = mLastEvent.getX(1) + 100;
+        y[0] = mLastEvent.getY(0) + 100;
+        y[1] = mLastEvent.getY(1) + 100;
+        send(manyPointerEvent(ACTION_MOVE, x, y));
+        // Ensure that no two-finger passthrough is being executed.
+        assertState(STATE_GESTURE_DETECTING);
+        assertNoCapturedEvents();
+        send(pointerUpEvent());
+        send(upEvent());
+        mTouchExplorer.setMultiFingerGesturesEnabled(false);
+    }
+
     private static MotionEvent fromTouchscreen(MotionEvent ev) {
         ev.setSource(InputDevice.SOURCE_TOUCHSCREEN);
         return ev;
@@ -376,8 +445,7 @@
                     throw new IllegalArgumentException("Illegal state: " + state);
             }
         } catch (Throwable t) {
-            throw new RuntimeException(
-                    "Failed to go to state " + stateToString(state), t);
+            throw new RuntimeException("Failed to go to state " + stateToString(state), t);
         }
     }
 
@@ -427,6 +495,10 @@
                 TouchState.getStateSymbolicName(mTouchExplorer.getState().getState()));
     }
 
+    private void assertNoCapturedEvents() {
+        assertEquals(0, getCapturedEvents().size());
+    }
+
     private void assertCapturedEvents(int... actionsInOrder) {
         final int eventCount = actionsInOrder.length;
         assertEquals(eventCount, getCapturedEvents().size());
@@ -449,6 +521,19 @@
         return ((EventCaptor) mCaptor).mEvents;
     }
 
+    private MotionEvent cancelEvent() {
+        mLastDownTime = SystemClock.uptimeMillis();
+        return fromTouchscreen(
+                MotionEvent.obtain(mLastDownTime, mLastDownTime, ACTION_CANCEL,
+                        DEFAULT_X, DEFAULT_Y, 0));
+    }
+
+    private MotionEvent downEvent(float x, float y) {
+        mLastDownTime = SystemClock.uptimeMillis();
+        return fromTouchscreen(
+                MotionEvent.obtain(mLastDownTime, mLastDownTime, ACTION_DOWN, x, y, 0));
+    }
+
     private MotionEvent downEvent() {
         mLastDownTime = SystemClock.uptimeMillis();
         return fromTouchscreen(
@@ -572,8 +657,8 @@
     }
 
     /**
-     * A {@link android.os.Handler} that doesn't process messages until {@link
-     * #fastForward(int)} is invoked.
+     * A {@link android.os.Handler} that doesn't process messages until {@link #fastForward(int)} is
+     * invoked.
      *
      * @see com.android.server.testutils.TestHandler
      */
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index e82ff34..aed590b 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -74,11 +75,16 @@
     private static final int MODE_FULLSCREEN =
             Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 
-    @Mock private AccessibilityManagerService mService;
-    @Mock private MagnificationController.TransitionCallBack mTransitionCallBack;
-    @Mock private Context mContext;
-    @Mock private FullScreenMagnificationController mScreenMagnificationController;
-    @Captor private ArgumentCaptor<MagnificationAnimationCallback> mCallbackArgumentCaptor;
+    @Mock
+    private AccessibilityManagerService mService;
+    @Mock
+    private MagnificationController.TransitionCallBack mTransitionCallBack;
+    @Mock
+    private Context mContext;
+    @Mock
+    private FullScreenMagnificationController mScreenMagnificationController;
+    @Captor
+    private ArgumentCaptor<MagnificationAnimationCallback> mCallbackArgumentCaptor;
 
     private MockWindowMagnificationConnection mMockConnection;
     private WindowMagnificationManager mWindowMagnificationManager;
@@ -96,7 +102,8 @@
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, DEFAULT_SCALE,
                 CURRENT_USER_ID);
         mWindowMagnificationManager = Mockito.spy(
-                new WindowMagnificationManager(mContext, CURRENT_USER_ID));
+                new WindowMagnificationManager(mContext, CURRENT_USER_ID,
+                        mock(WindowMagnificationManager.Callback.class)));
         mMockConnection = new MockWindowMagnificationConnection(true);
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mMagnificationController = new MagnificationController(mService, new Object(), mContext,
@@ -261,6 +268,19 @@
         assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
     }
 
+    @Test
+    public void onPerformScaleAction_magnifierEnabled_handleScaleChange() throws RemoteException {
+        final float newScale = 4.0f;
+        setMagnificationEnabled(MODE_WINDOW);
+
+        mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale);
+
+        verify(mWindowMagnificationManager).setScale(eq(TEST_DISPLAY), eq(newScale));
+        verify(mWindowMagnificationManager).persistScale(eq(TEST_DISPLAY));
+        verify(mService).onMagnificationScaleChanged(eq(TEST_DISPLAY),
+                eq(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
+    }
+
     private void setMagnificationEnabled(int mode) throws RemoteException {
 
         setMagnificationEnabled(mode, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
index a10e0ba..41b6e98 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
@@ -70,7 +70,8 @@
     @Before
     public void setUp() throws RemoteException {
         mContext = InstrumentationRegistry.getContext();
-        mWindowMagnificationManager = new WindowMagnificationManager(mContext, 0);
+        mWindowMagnificationManager = new WindowMagnificationManager(mContext, 0,
+                mock(WindowMagnificationManager.Callback.class));
         mMockConnection = new MockWindowMagnificationConnection();
         mWindowMagnificationGestureHandler = new WindowMagnificationGestureHandler(
                 mContext, mWindowMagnificationManager, mock(ScaleChangedListener.class),
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index d5be3ed..f26c86c 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -16,7 +16,6 @@
 
 package com.android.server.accessibility.magnification;
 
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
@@ -76,6 +75,8 @@
     private StatusBarManagerInternal mMockStatusBarManagerInternal;
     @Mock
     private MagnificationAnimationCallback mAnimationCallback;
+    @Mock
+    private WindowMagnificationManager.Callback mMockCallback;
     private MockContentResolver mResolver;
     private WindowMagnificationManager mWindowMagnificationManager;
 
@@ -86,7 +87,8 @@
         LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
         mResolver = new MockContentResolver();
         mMockConnection = new MockWindowMagnificationConnection();
-        mWindowMagnificationManager = new WindowMagnificationManager(mContext, CURRENT_USER_ID);
+        mWindowMagnificationManager = new WindowMagnificationManager(mContext, CURRENT_USER_ID,
+                mMockCallback);
 
         when(mContext.getContentResolver()).thenReturn(mResolver);
         doAnswer((InvocationOnMock invocation) -> {
@@ -300,6 +302,17 @@
     }
 
     @Test
+    public void onPerformScaleAction_magnifierEnabled_notifyAction() throws RemoteException {
+        final float newScale = 4.0f;
+        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+
+        mMockConnection.getConnectionCallback().onPerformScaleAction(TEST_DISPLAY, newScale);
+
+        verify(mMockCallback).onPerformScaleAction(eq(TEST_DISPLAY), eq(newScale));
+    }
+
+    @Test
     public void binderDied_windowMagnifierIsEnabled_resetState() throws RemoteException {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/Face10Test.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/Face10Test.java
index b73a783..b0f7b0c 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/Face10Test.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/Face10Test.java
@@ -43,7 +43,7 @@
     private Context mContext;
 
     private LockoutResetDispatcher mLockoutResetDispatcher;
-    private Face10 mFace10;
+    private com.android.server.biometrics.sensors.face.hidl.Face10 mFace10;
     private IBinder mBinder;
 
     private static void waitForIdle() {
@@ -55,9 +55,9 @@
         MockitoAnnotations.initMocks(this);
 
         mLockoutResetDispatcher = new LockoutResetDispatcher(mContext);
-        mFace10 = new Face10(mContext, SENSOR_ID, BiometricManager.Authenticators.BIOMETRIC_STRONG,
-                mLockoutResetDispatcher, false /* supportsSelfIllumination */,
-                1 /* maxTemplatesAllowed */);
+        mFace10 = new com.android.server.biometrics.sensors.face.hidl.Face10(mContext, SENSOR_ID,
+                BiometricManager.Authenticators.BIOMETRIC_STRONG, mLockoutResetDispatcher,
+                false /* supportsSelfIllumination */, 1 /* maxTemplatesAllowed */);
         mBinder = new Binder();
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 8d7bc16..77e1676 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -674,6 +674,7 @@
     @Test
     public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() {
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
 
         // Add admin1.
 
@@ -2748,6 +2749,7 @@
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
 
         // Check that the system user is unaffiliated.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -4363,6 +4365,8 @@
 
     @Test
     public void testGetBindDeviceAdminTargetUsers() throws Exception {
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
+
         // Setup device owner.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -6263,6 +6267,7 @@
 
     @Test
     public void testGetAllCrossProfilePackages_notSet_returnsEmpty() throws Exception {
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
         addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1);
         mContext.packageName = admin1.getPackageName();
 
@@ -6275,6 +6280,7 @@
     @Test
     public void testGetAllCrossProfilePackages_notSet_dpmsReinitialized_returnsEmpty()
             throws Exception {
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
         addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1);
         mContext.packageName = admin1.getPackageName();
 
@@ -6287,6 +6293,7 @@
 
     @Test
     public void testGetAllCrossProfilePackages_whenSet_returnsCombinedSet() throws Exception {
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
         addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1);
         final Set<String> packages = Sets.newSet("TEST_PACKAGE", "TEST_COMMON_PACKAGE");
         mContext.packageName = admin1.getPackageName();
@@ -6303,6 +6310,7 @@
     @Test
     public void testGetAllCrossProfilePackages_whenSet_dpmsReinitialized_returnsCombinedSet()
             throws Exception {
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
         addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1);
         final Set<String> packages = Sets.newSet("TEST_PACKAGE", "TEST_COMMON_PACKAGE");
         mContext.packageName = admin1.getPackageName();
@@ -6483,6 +6491,8 @@
     @Test
     public void testSetAccountTypesWithManagementDisabledOnOrgOwnedManagedProfile()
             throws Exception {
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
+
         final int managedProfileUserId = 15;
         final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
 
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index 9b182a7..95aac60 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -19,8 +19,13 @@
 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertThrows;
 
+import android.hardware.devicestate.IDeviceStateManagerCallback;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -28,11 +33,14 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import javax.annotation.Nullable;
+
 /**
  * Unit tests for {@link DeviceStateManagerService}.
  * <p/>
  * Run with <code>atest DeviceStateManagerServiceTest</code>.
  */
+@Presubmit
 @RunWith(AndroidJUnit4.class)
 public final class DeviceStateManagerServiceTest {
     private static final int DEFAULT_DEVICE_STATE = 0;
@@ -48,7 +56,6 @@
         mProvider = new TestDeviceStateProvider();
         mPolicy = new TestDeviceStatePolicy(mProvider);
         mService = new DeviceStateManagerService(InstrumentationRegistry.getContext(), mPolicy);
-        mService.onStart();
     }
 
     @Test
@@ -187,6 +194,38 @@
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE);
     }
 
+    @Test
+    public void registerCallback() throws RemoteException {
+        TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
+        mService.getBinderService().registerCallback(callback);
+
+        mProvider.notifyRequestState(OTHER_DEVICE_STATE);
+        assertNotNull(callback.getLastNotifiedValue());
+        assertEquals(callback.getLastNotifiedValue().intValue(), OTHER_DEVICE_STATE);
+
+        mProvider.notifyRequestState(DEFAULT_DEVICE_STATE);
+        assertEquals(callback.getLastNotifiedValue().intValue(), DEFAULT_DEVICE_STATE);
+
+        mPolicy.blockConfigure();
+        mProvider.notifyRequestState(OTHER_DEVICE_STATE);
+        // The callback should not have been notified of the state change as the policy is still
+        // pending callback.
+        assertEquals(callback.getLastNotifiedValue().intValue(), DEFAULT_DEVICE_STATE);
+
+        mPolicy.resumeConfigure();
+        // Now that the policy is finished processing the callback should be notified of the state
+        // change.
+        assertEquals(callback.getLastNotifiedValue().intValue(), OTHER_DEVICE_STATE);
+    }
+
+    @Test
+    public void registerCallback_emitsInitialValue() throws RemoteException {
+        TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
+        mService.getBinderService().registerCallback(callback);
+        assertNotNull(callback.getLastNotifiedValue());
+        assertEquals(callback.getLastNotifiedValue().intValue(), DEFAULT_DEVICE_STATE);
+    }
+
     private static final class TestDeviceStatePolicy implements DeviceStatePolicy {
         private final DeviceStateProvider mProvider;
         private int mLastDeviceStateRequestedToConfigure = INVALID_DEVICE_STATE;
@@ -262,4 +301,19 @@
             mListener.onStateChanged(state);
         }
     }
+
+    private static final class TestDeviceStateManagerCallback extends
+            IDeviceStateManagerCallback.Stub {
+        Integer mLastNotifiedValue;
+
+        @Override
+        public void onDeviceStateChanged(int deviceState) {
+            mLastNotifiedValue = deviceState;
+        }
+
+        @Nullable
+        Integer getLastNotifiedValue() {
+            return mLastNotifiedValue;
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 13b0198..026db42 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -460,6 +460,7 @@
      * Tests that collection of display color sampling results are sensible.
      */
     @Test
+    @FlakyTest(bugId = 172555744)
     public void testDisplayedContentSampling() {
         DisplayManagerService displayManager =
                 new DisplayManagerService(mContext, mShortMockedInjector);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
index ae9c618..a27f733 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
@@ -17,6 +17,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static junit.framework.Assert.assertTrue;
+
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
@@ -77,14 +79,16 @@
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
-                + "      <value string-value=\"0\" />"
-                + "      <value string-value=\"1\" />"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
                 + "    </allowed-values>"
-                + "    <default-value string-value=\"1\" />"
+                + "    <default-value int-value=\"1\" />"
                 + "  </setting>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"false\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -123,14 +127,16 @@
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
-                + "      <value string-value=\"0\" />"
-                + "      <value string-value=\"1\" />"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
                 + "    </allowed-values>"
-                + "    <default-value string-value=\"1\" />"
+                + "    <default-value int-value=\"1\" />"
                 + "  </setting>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -152,14 +158,16 @@
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
-                + "      <value string-value=\"0\" />"
-                + "      <value string-value=\"1\" />"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
                 + "    </allowed-values>"
-                + "    <default-value string-value=\"1\" />"
+                + "    <default-value int-value=\"1\" />"
                 + "  </setting>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -172,6 +180,7 @@
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"false\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -186,31 +195,32 @@
     }
 
     @Test
-    public void getAllowedValues_NoMasterXml() {
+    public void isStringValueType_NoMasterXml() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter, null, null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.getAllowedValues("foo"));
+                () -> hdmiCecConfig.isStringValueType("foo"));
     }
 
     @Test
-    public void getAllowedValues_InvalidSetting() {
+    public void isStringValueType_InvalidSetting() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.getAllowedValues("foo"));
+                () -> hdmiCecConfig.isStringValueType("foo"));
     }
 
     @Test
-    public void getAllowedValues_BasicSanity() {
+    public void isStringValueType_BasicSanity() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -220,7 +230,107 @@
                 + "    <default-value string-value=\"to_tv\" />"
                 + "  </setting>"
                 + "</cec-settings>", null);
-        assertThat(hdmiCecConfig.getAllowedValues(
+        assertTrue(hdmiCecConfig.isStringValueType(
+                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP));
+    }
+
+    @Test
+    public void isIntValueType_NoMasterXml() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter, null, null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.isIntValueType("foo"));
+    }
+
+    @Test
+    public void isIntValueType_InvalidSetting() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.isIntValueType("foo"));
+    }
+
+    @Test
+    public void isIntValueType_BasicSanity() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertTrue(hdmiCecConfig.isIntValueType(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED));
+    }
+
+    @Test
+    public void getAllowedStringValues_NoMasterXml() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter, null, null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getAllowedStringValues("foo"));
+    }
+
+    @Test
+    public void getAllowedStringValues_InvalidSetting() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getAllowedStringValues("foo"));
+    }
+
+    @Test
+    public void getAllowedStringValues_InvalidValueType() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getAllowedStringValues(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED));
+    }
+
+    @Test
+    public void getAllowedStringValues_BasicSanity() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value string-value=\"to_tv\" />"
+                + "      <value string-value=\"broadcast\" />"
+                + "      <value string-value=\"none\" />"
+                + "    </allowed-values>"
+                + "    <default-value string-value=\"to_tv\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getAllowedStringValues(
                     HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP))
                 .containsExactly(HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV,
                                  HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST,
@@ -228,31 +338,32 @@
     }
 
     @Test
-    public void getDefaultValue_NoMasterXml() {
+    public void getAllowedIntValues_NoMasterXml() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter, null, null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.getDefaultValue("foo"));
+                () -> hdmiCecConfig.getAllowedIntValues("foo"));
     }
 
     @Test
-    public void getDefaultValue_InvalidSetting() {
+    public void getAllowedIntValues_InvalidSetting() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.getDefaultValue("foo"));
+                () -> hdmiCecConfig.getAllowedIntValues("foo"));
     }
 
     @Test
-    public void getDefaultValue_BasicSanity() {
+    public void getAllowedIntValues_InvalidValueType() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -262,32 +373,242 @@
                 + "    <default-value string-value=\"to_tv\" />"
                 + "  </setting>"
                 + "</cec-settings>", null);
-        assertThat(hdmiCecConfig.getDefaultValue(
-                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP))
-                .isEqualTo(HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getAllowedIntValues(
+                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP));
     }
 
     @Test
-    public void getValue_NoMasterXml() {
+    public void getAllowedIntValues_BasicSanity() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getAllowedIntValues(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED))
+                .containsExactly(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED,
+                                 HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+    }
+
+    @Test
+    public void getAllowedIntValues_HexValues() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0x00\" />"
+                + "      <value int-value=\"0x01\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"0x01\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getAllowedIntValues(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED))
+                .containsExactly(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED,
+                                 HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+    }
+
+    @Test
+    public void getDefaultStringValue_NoMasterXml() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter, null, null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.getValue("foo"));
+                () -> hdmiCecConfig.getDefaultStringValue("foo"));
     }
 
     @Test
-    public void getValue_InvalidSetting() {
+    public void getDefaultStringValue_InvalidSetting() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.getValue("foo"));
+                () -> hdmiCecConfig.getDefaultStringValue("foo"));
     }
 
     @Test
-    public void getValue_GlobalSetting_BasicSanity() {
+    public void getDefaultStringValue_InvalidValueType() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getDefaultStringValue(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED));
+    }
+
+    @Test
+    public void getDefaultStringValue_BasicSanity() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value string-value=\"to_tv\" />"
+                + "      <value string-value=\"broadcast\" />"
+                + "      <value string-value=\"none\" />"
+                + "    </allowed-values>"
+                + "    <default-value string-value=\"to_tv\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getDefaultStringValue(
+                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP))
+                .isEqualTo(HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
+    }
+
+    @Test
+    public void getDefaultIntValue_NoMasterXml() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter, null, null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getDefaultIntValue("foo"));
+    }
+
+    @Test
+    public void getDefaultIntValue_InvalidSetting() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getDefaultIntValue("foo"));
+    }
+
+    @Test
+    public void getDefaultIntValue_InvalidValueType() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value string-value=\"to_tv\" />"
+                + "      <value string-value=\"broadcast\" />"
+                + "      <value string-value=\"none\" />"
+                + "    </allowed-values>"
+                + "    <default-value string-value=\"to_tv\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getDefaultIntValue(
+                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP));
+    }
+
+    @Test
+    public void getDefaultIntValue_BasicSanity() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getDefaultIntValue(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED))
+                .isEqualTo(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+    }
+
+    @Test
+    public void getDefaultIntValue_HexValue() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0x00\" />"
+                + "      <value int-value=\"0x01\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"0x01\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getDefaultIntValue(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED))
+                .isEqualTo(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+    }
+
+    @Test
+    public void getStringValue_NoMasterXml() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter, null, null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getStringValue("foo"));
+    }
+
+    @Test
+    public void getStringValue_InvalidSetting() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getStringValue("foo"));
+    }
+
+    @Test
+    public void getStringValue_InvalidType() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getStringValue(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED));
+    }
+
+    @Test
+    public void getStringValue_GlobalSetting_BasicSanity() {
         when(mStorageAdapter.retrieveGlobalSetting(mContext,
                   Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                   HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV))
@@ -297,6 +618,7 @@
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -306,13 +628,13 @@
                 + "    <default-value string-value=\"to_tv\" />"
                 + "  </setting>"
                 + "</cec-settings>", null);
-        assertThat(hdmiCecConfig.getValue(
+        assertThat(hdmiCecConfig.getStringValue(
                     HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP))
                 .isEqualTo(HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
     }
 
     @Test
-    public void getValue_SystemProperty_BasicSanity() {
+    public void getStringValue_SystemProperty_BasicSanity() {
         when(mStorageAdapter.retrieveSystemProperty(
                   HdmiCecConfig.SYSPROP_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
                   HdmiProperties.power_state_change_on_active_source_lost_values
@@ -324,6 +646,7 @@
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"power_state_change_on_active_source_lost\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"false\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"none\" />"
@@ -332,38 +655,155 @@
                 + "    <default-value string-value=\"none\" />"
                 + "  </setting>"
                 + "</cec-settings>", null);
-        assertThat(hdmiCecConfig.getValue(
+        assertThat(hdmiCecConfig.getStringValue(
                     HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST))
                 .isEqualTo(HdmiProperties.power_state_change_on_active_source_lost_values
                         .STANDBY_NOW.name().toLowerCase());
     }
 
     @Test
-    public void setValue_NoMasterXml() {
+    public void getIntValue_NoMasterXml() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter, null, null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.setValue("foo", "bar"));
+                () -> hdmiCecConfig.getIntValue("foo"));
     }
 
     @Test
-    public void setValue_InvalidSetting() {
+    public void getIntValue_InvalidSetting() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.setValue("foo", "bar"));
+                () -> hdmiCecConfig.getIntValue("foo"));
     }
 
     @Test
-    public void setValue_NotConfigurable() {
+    public void getIntValue_InvalidType() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value string-value=\"to_tv\" />"
+                + "      <value string-value=\"broadcast\" />"
+                + "      <value string-value=\"none\" />"
+                + "    </allowed-values>"
+                + "    <default-value string-value=\"to_tv\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.getIntValue(
+                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP));
+    }
+
+    @Test
+    public void getIntValue_GlobalSetting_BasicSanity() {
+        when(mStorageAdapter.retrieveGlobalSetting(mContext,
+                  Global.HDMI_CONTROL_ENABLED,
+                  Integer.toString(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED)))
+            .thenReturn(Integer.toString(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED));
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getIntValue(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED))
+                .isEqualTo(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+    }
+
+    @Test
+    public void getIntValue_GlobalSetting_HexValue() {
+        when(mStorageAdapter.retrieveGlobalSetting(mContext,
+                  Global.HDMI_CONTROL_ENABLED,
+                  Integer.toHexString(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED)))
+            .thenReturn(Integer.toString(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED));
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0x0\" />"
+                + "      <value int-value=\"0x1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"0x1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getIntValue(
+                    HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED))
+                .isEqualTo(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+    }
+
+    @Test
+    public void getIntValue_SystemProperty_BasicSanity() {
+        when(mStorageAdapter.retrieveSystemProperty(
+                  HdmiCecConfig.SYSPROP_SYSTEM_AUDIO_MODE_MUTING,
+                  Integer.toString(HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_ENABLED)))
+                .thenReturn(Integer.toString(HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED));
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"system_audio_mode_muting\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThat(hdmiCecConfig.getIntValue(
+                    HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING))
+                .isEqualTo(HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED);
+    }
+
+    @Test
+    public void setStringValue_NoMasterXml() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter, null, null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.setStringValue("foo", "bar"));
+    }
+
+    @Test
+    public void setStringValue_InvalidSetting() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.setStringValue("foo", "bar"));
+    }
+
+    @Test
+    public void setStringValue_NotConfigurable() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"false\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -374,18 +814,19 @@
                 + "  </setting>"
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.setValue(
+                () -> hdmiCecConfig.setStringValue(
                         HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
                         HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST));
     }
 
     @Test
-    public void setValue_InvalidValue() {
+    public void setStringValue_InvalidValue() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -396,18 +837,19 @@
                 + "  </setting>"
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
-                () -> hdmiCecConfig.setValue(
+                () -> hdmiCecConfig.setStringValue(
                         HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
                         "bar"));
     }
 
     @Test
-    public void setValue_GlobalSetting_BasicSanity() {
+    public void setStringValue_GlobalSetting_BasicSanity() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"send_standby_on_sleep\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"to_tv\" />"
@@ -417,7 +859,7 @@
                 + "    <default-value string-value=\"to_tv\" />"
                 + "  </setting>"
                 + "</cec-settings>", null);
-        hdmiCecConfig.setValue(HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
+        hdmiCecConfig.setStringValue(HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
                                HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
         verify(mStorageAdapter).storeGlobalSetting(mContext,
                   Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
@@ -425,12 +867,13 @@
     }
 
     @Test
-    public void setValue_SystemProperty_BasicSanity() {
+    public void setStringValue_SystemProperty_BasicSanity() {
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
                 + "<cec-settings>"
                 + "  <setting name=\"power_state_change_on_active_source_lost\""
+                + "           value-type=\"string\""
                 + "           user-configurable=\"true\">"
                 + "    <allowed-values>"
                 + "      <value string-value=\"none\" />"
@@ -439,7 +882,7 @@
                 + "    <default-value string-value=\"none\" />"
                 + "  </setting>"
                 + "</cec-settings>", null);
-        hdmiCecConfig.setValue(
+        hdmiCecConfig.setStringValue(
                   HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
                   HdmiProperties.power_state_change_on_active_source_lost_values
                       .STANDBY_NOW.name().toLowerCase());
@@ -448,4 +891,137 @@
                   HdmiProperties.power_state_change_on_active_source_lost_values
                       .STANDBY_NOW.name().toLowerCase());
     }
+
+    @Test
+    public void setIntValue_NoMasterXml() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter, null, null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.setIntValue("foo", 0));
+    }
+
+    @Test
+    public void setIntValue_InvalidSetting() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.setIntValue("foo", 0));
+    }
+
+    @Test
+    public void setIntValue_NotConfigurable() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"false\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.setIntValue(
+                        HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+                        HdmiControlManager.HDMI_CEC_CONTROL_DISABLED));
+    }
+
+    @Test
+    public void setIntValue_InvalidValue() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        assertThrows(IllegalArgumentException.class,
+                () -> hdmiCecConfig.setIntValue(
+                        HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+                        123));
+    }
+
+    @Test
+    public void setIntValue_GlobalSetting_BasicSanity() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        hdmiCecConfig.setIntValue(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+                                  HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        verify(mStorageAdapter).storeGlobalSetting(mContext,
+                  Global.HDMI_CONTROL_ENABLED,
+                  Integer.toString(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED));
+    }
+
+    @Test
+    public void setIntValue_GlobalSetting_HexValue() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"hdmi_cec_enabled\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0x0\" />"
+                + "      <value int-value=\"0x1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"0x1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        hdmiCecConfig.setIntValue(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+                                  HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        verify(mStorageAdapter).storeGlobalSetting(mContext,
+                  Global.HDMI_CONTROL_ENABLED,
+                  Integer.toString(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED));
+    }
+
+    @Test
+    public void setIntValue_SystemProperty_BasicSanity() {
+        HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
+                mContext, mStorageAdapter,
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
+                + "<cec-settings>"
+                + "  <setting name=\"system_audio_mode_muting\""
+                + "           value-type=\"int\""
+                + "           user-configurable=\"true\">"
+                + "    <allowed-values>"
+                + "      <value int-value=\"0\" />"
+                + "      <value int-value=\"1\" />"
+                + "    </allowed-values>"
+                + "    <default-value int-value=\"1\" />"
+                + "  </setting>"
+                + "</cec-settings>", null);
+        hdmiCecConfig.setIntValue(
+                  HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
+                  HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED);
+        verify(mStorageAdapter).storeSystemProperty(
+                  HdmiCecConfig.SYSPROP_SYSTEM_AUDIO_MODE_MUTING,
+                  Integer.toString(HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 440befc..c0dad52 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -645,6 +645,91 @@
     }
 
     @Test
+    public void handleOnInitializeCecComplete_ByEnableCec() {
+        mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
+                mHdmiControlService.INITIATED_BY_ENABLE_CEC);
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSource =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+        HdmiCecMessage textViewOn =
+                HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
+                        ADDR_TV);
+
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+    }
+
+    @Test
+    public void handleOnInitializeCecComplete_ByBootUp() {
+        mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
+                mHdmiControlService.INITIATED_BY_BOOT_UP);
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSource =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+        HdmiCecMessage textViewOn =
+                HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
+                        ADDR_TV);
+
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+    }
+
+    @Test
+    public void handleOnInitializeCecComplete_ByScreenOn() {
+        mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
+                mHdmiControlService.INITIATED_BY_SCREEN_ON);
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSource =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+        HdmiCecMessage textViewOn =
+                HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
+                        ADDR_TV);
+
+        assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+        assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+    }
+
+    @Test
+    public void handleOnInitializeCecComplete_ByWakeUpMessage() {
+        mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
+                mHdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE);
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSource =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+        HdmiCecMessage textViewOn =
+                HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
+                        ADDR_TV);
+
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+    }
+
+    @Test
+    public void handleOnInitializeCecComplete_ByHotplug() {
+        mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
+                mHdmiControlService.INITIATED_BY_HOTPLUG);
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSource =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+        HdmiCecMessage textViewOn =
+                HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
+                        ADDR_TV);
+
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+    }
+
+    @Test
     public void handleActiveSource_ActiveSource_None() {
         mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
             HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index 4702940..553df3b 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -130,6 +130,17 @@
     }
 
     @Test
+    public void isValid_setTimerProgramTitle() {
+        assertMessageValidity("40:67:47:61:6D:65:20:6F:66:20:54:68:72:6F:6E:65:73").isEqualTo(OK);
+        assertMessageValidity("40:67:4A").isEqualTo(OK);
+
+        assertMessageValidity("4F:67:47:4F:54").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F4:67:47:4F:54").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:67").isEqualTo(ERROR_PARAMETER_SHORT);
+        assertMessageValidity("40:67:47:9A:54").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
     public void isValid_setMenuLanguage() {
         assertMessageValidity("4F:32:53:50:41").isEqualTo(OK);
         assertMessageValidity("0F:32:45:4E:47:8C:49:D3:48").isEqualTo(OK);
@@ -182,6 +193,166 @@
         assertMessageValidity("40:0A:30").isEqualTo(ERROR_PARAMETER);
     }
 
+    @Test
+    public void isValid_setAnalogueTimer_clearAnalogueTimer() {
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:13:AD:06").isEqualTo(OK);
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:03:34").isEqualTo(OK);
+
+        assertMessageValidity("0F:33:0C:08:10:1E:04:30:08:00:13:AD:06")
+                .isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:34:04:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:13:AD:06")
+                .isEqualTo(ERROR_PARAMETER_SHORT);
+        // Out of range Day of Month
+        assertMessageValidity("04:34:20:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Month of Year
+        assertMessageValidity("04:33:0C:00:10:1E:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Hour
+        assertMessageValidity("04:34:04:0C:18:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Minute
+        assertMessageValidity("04:33:0C:08:10:50:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Duration Hours
+        assertMessageValidity("04:34:04:0C:16:0F:64:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Minute
+        assertMessageValidity("04:33:0C:08:10:1E:04:64:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:88:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:A2:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Analogue Broadcast Type
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:03:EA:60:03").isEqualTo(ERROR_PARAMETER);
+        // Out of range Analogue Frequency
+        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:FF:FF:06").isEqualTo(ERROR_PARAMETER);
+        // Out of range Broadcast System
+        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:20").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_setDigitalTimer_clearDigitalTimer() {
+        // Services identified by Digital IDs - ARIB Broadcast System
+        assertMessageValidity("04:99:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75:30").isEqualTo(OK);
+        // Service identified by Digital IDs - ATSC Broadcast System
+        assertMessageValidity("04:97:1E:07:12:20:50:28:01:01:8B:5E:39:5A").isEqualTo(OK);
+        // Service identified by Digital IDs - DVB Broadcast System
+        assertMessageValidity("04:99:05:0C:06:0A:19:3B:40:19:8B:44:03:11:04:FC").isEqualTo(OK);
+        // Service identified by Channel - 1 part channel number
+        assertMessageValidity("04:97:12:06:0C:2D:5A:19:08:91:04:00:B1").isEqualTo(OK);
+        // Service identified by Channel - 2 part channel number
+        assertMessageValidity("04:99:15:09:00:0F:00:2D:04:82:09:C8:72:C8").isEqualTo(OK);
+
+        assertMessageValidity("4F:97:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75:30")
+                .isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:99:15:09:00:0F:00:2D:04:82:09:C8:72:C8").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("04:97:1E:12:20:58:01:01:8B:5E:39:5A")
+                .isEqualTo(ERROR_PARAMETER_SHORT);
+        // Out of range Day of Month
+        assertMessageValidity("04:99:24:0C:06:0A:19:3B:40:19:8B:44:03:11:04:FC")
+                .isEqualTo(ERROR_PARAMETER);
+        // Out of range Month of Year
+        assertMessageValidity("04:97:12:10:0C:2D:5A:19:08:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Hour
+        assertMessageValidity("04:99:0C:08:20:05:04:1E:00:00:C4:C2:11:D8:75:30")
+                .isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Minute
+        assertMessageValidity("04:97:15:09:00:4B:00:2D:04:82:09:C8:72:C8")
+                .isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Duration Hours
+        assertMessageValidity("04:99:1E:07:12:20:78:28:01:01:8B:5E:39:5A")
+                .isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Minute
+        assertMessageValidity("04:97:05:0C:06:0A:19:48:40:19:8B:44:03:11:04:FC")
+                .isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:99:12:06:0C:2D:5A:19:90:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("04:97:0C:08:15:05:04:1E:21:00:C4:C2:11:D8:75:30")
+                .isEqualTo(ERROR_PARAMETER);
+
+        // Invalid Digital Broadcast System
+        assertMessageValidity("04:99:1E:07:12:20:50:28:01:04:8B:5E:39:5A")
+                .isEqualTo(ERROR_PARAMETER);
+        // Invalid Digital Broadcast System
+        assertMessageValidity("04:97:05:0C:06:0A:19:3B:40:93:8B:44:03:11:04:FC")
+                .isEqualTo(ERROR_PARAMETER);
+        // Insufficient data for ARIB Broadcast system
+        assertMessageValidity("04:99:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75")
+                .isEqualTo(ERROR_PARAMETER);
+        // Insufficient data for ATSC Broadcast system
+        assertMessageValidity("04:97:1E:07:12:20:50:28:01:01:8B:5E:39").isEqualTo(ERROR_PARAMETER);
+        // Insufficient data for DVB Broadcast system
+        assertMessageValidity("04:99:05:0C:06:0A:19:3B:40:19:8B:44:03:11:04")
+                .isEqualTo(ERROR_PARAMETER);
+        // Insufficient data for 2 part channel number
+        assertMessageValidity("04:97:15:09:00:0F:00:2D:04:82:09:C8:72").isEqualTo(ERROR_PARAMETER);
+        // Invalid Channel Number format
+        assertMessageValidity("04:99:12:06:0C:2D:5A:19:08:91:0D:00:B1").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_setExternalTimer_clearExternalTimer() {
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(OK);
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(OK);
+
+        assertMessageValidity("4F:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F4:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04").isEqualTo(ERROR_PARAMETER_SHORT);
+        // Out of range Day of Month
+        assertMessageValidity("40:A2:28:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Month of Year
+        assertMessageValidity("40:A1:0C:0F:15:05:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Hour
+        assertMessageValidity("40:A2:14:09:1A:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Start Time - Minute
+        assertMessageValidity("40:A1:0C:08:15:48:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Duration Hours
+        assertMessageValidity("40:A2:14:09:12:28:66:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Out of range Duration - Minute
+        assertMessageValidity("40:A1:0C:08:15:05:04:3F:02:04:20").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:84:05:10:00").isEqualTo(ERROR_PARAMETER);
+        // Invalid Recording Sequence
+        assertMessageValidity("40:A1:0C:08:15:05:04:1E:14:04:20").isEqualTo(ERROR_PARAMETER);
+        // Invalid external source specifier
+        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:08:10:00").isEqualTo(ERROR_PARAMETER);
+        // Invalid External PLug
+        assertMessageValidity("04:A1:0C:08:15:05:04:1E:02:04:00").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_timerClearedStatus() {
+        assertMessageValidity("40:43:01:7E").isEqualTo(OK);
+        assertMessageValidity("40:43:80").isEqualTo(OK);
+
+        assertMessageValidity("4F:43:01").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:43:80").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:43").isEqualTo(ERROR_PARAMETER_SHORT);
+        assertMessageValidity("40:43:03").isEqualTo(ERROR_PARAMETER);
+    }
+
+    @Test
+    public void isValid_timerStatus() {
+        // Programmed - Space available
+        assertMessageValidity("40:35:58").isEqualTo(OK);
+        // Programmed - Not enough space available
+        assertMessageValidity("40:35:B9:32:1C:4F").isEqualTo(OK);
+        // Not programmed - Date out of range
+        assertMessageValidity("40:35:82:3B").isEqualTo(OK);
+        // Not programmed - Duplicate
+        assertMessageValidity("40:35:EE:52:0C").isEqualTo(OK);
+
+        assertMessageValidity("4F:35:58").isEqualTo(ERROR_DESTINATION);
+        assertMessageValidity("F0:35:82").isEqualTo(ERROR_SOURCE);
+        assertMessageValidity("40:35").isEqualTo(ERROR_PARAMETER_SHORT);
+        // Programmed - Invalid programmed info
+        assertMessageValidity("40:35:BD").isEqualTo(ERROR_PARAMETER);
+        // Non programmed - Invalid not programmed error info
+        assertMessageValidity("40:35:DE").isEqualTo(ERROR_PARAMETER);
+        // Programmed - Might not be enough space available - Invalid duration hours
+        assertMessageValidity("40:35:BB:96:1C").isEqualTo(ERROR_PARAMETER);
+        // Not programmed - Duplicate - Invalid duration minutes
+        assertMessageValidity("40:35:EE:52:4A").isEqualTo(ERROR_PARAMETER);
+    }
+
     private IntegerSubject assertMessageValidity(String message) {
         return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message)));
     }
diff --git a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
index 292b7c6..c4b19e8 100644
--- a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
@@ -26,7 +26,6 @@
 import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_PERM_FAILED;
 import static com.android.server.location.timezone.TestSupport.USER1_CONFIG_GEO_DETECTION_DISABLED;
 import static com.android.server.location.timezone.TestSupport.USER1_CONFIG_GEO_DETECTION_ENABLED;
-import static com.android.server.location.timezone.TestSupport.USER1_ID;
 import static com.android.server.location.timezone.TestSupport.USER2_CONFIG_GEO_DETECTION_ENABLED;
 
 import static org.junit.Assert.assertEquals;
@@ -38,9 +37,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UserIdInt;
 import android.location.timezone.LocationTimeZoneEvent;
-import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 import android.util.IndentingPrintWriter;
 
@@ -66,13 +63,13 @@
     private static final long ARBITRARY_TIME = 12345L;
 
     private static final LocationTimeZoneEvent USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1 =
-            createLocationTimeZoneEvent(USER1_ID, EVENT_TYPE_SUCCESS, asList("Europe/London"));
+            createLocationTimeZoneEvent(EVENT_TYPE_SUCCESS, asList("Europe/London"));
     private static final LocationTimeZoneEvent USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2 =
-            createLocationTimeZoneEvent(USER1_ID, EVENT_TYPE_SUCCESS, asList("Europe/Paris"));
+            createLocationTimeZoneEvent(EVENT_TYPE_SUCCESS, asList("Europe/Paris"));
     private static final LocationTimeZoneEvent USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT =
-            createLocationTimeZoneEvent(USER1_ID, EVENT_TYPE_UNCERTAIN, null);
+            createLocationTimeZoneEvent(EVENT_TYPE_UNCERTAIN, null);
     private static final LocationTimeZoneEvent USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT =
-            createLocationTimeZoneEvent(USER1_ID, EVENT_TYPE_PERMANENT_FAILURE, null);
+            createLocationTimeZoneEvent(EVENT_TYPE_PERMANENT_FAILURE, null);
 
     private TestThreadingDomain mTestThreadingDomain;
     private TestCallback mTestCallback;
@@ -936,11 +933,10 @@
                 controller.getUncertaintyTimeoutDelayMillis());
     }
 
-    private static LocationTimeZoneEvent createLocationTimeZoneEvent(@UserIdInt int userId,
+    private static LocationTimeZoneEvent createLocationTimeZoneEvent(
             int eventType, @Nullable List<String> timeZoneIds) {
         LocationTimeZoneEvent.Builder builder = new LocationTimeZoneEvent.Builder()
                 .setElapsedRealtimeNanos(ARBITRARY_TIME)
-                .setUserHandle(UserHandle.of(userId))
                 .setEventType(eventType);
         if (timeZoneIds != null) {
             builder.setTimeZoneIds(timeZoneIds);
diff --git a/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java b/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java
index 40d959d..9ba0967 100644
--- a/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java
@@ -44,7 +44,6 @@
 public class IncrementalStatesTest {
     private IncrementalStates mIncrementalStates;
     private ConditionVariable mUnstartableCalled = new ConditionVariable();
-    private ConditionVariable mStartableCalled = new ConditionVariable();
     private ConditionVariable mFullyLoadedCalled = new ConditionVariable();
     private AtomicInteger mUnstartableReason = new AtomicInteger(0);
     private static final int WAIT_TIMEOUT_MILLIS = 1000; /* 1 second */
@@ -57,7 +56,6 @@
 
         @Override
         public void onPackageStartable() {
-            mStartableCalled.open();
         }
 
         @Override
@@ -77,24 +75,22 @@
         mIncrementalStates.setCallback(mCallback);
         mIncrementalStates.onCommit(true);
         // Test that package is now startable and loading
-        assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS));
         assertTrue(mIncrementalStates.isStartable());
         assertTrue(mIncrementalStates.isLoading());
-        mStartableCalled.close();
         mUnstartableCalled.close();
         mFullyLoadedCalled.close();
     }
 
     /**
-     * Test that startable state changes to false when Incremental Storage is unhealthy.
+     * Test that the package is still startable when Incremental Storage is unhealthy.
      */
     @Test
     public void testStartableTransition_IncrementalStorageUnhealthy() {
         mIncrementalStates.onStorageHealthStatusChanged(
                 IStorageHealthListener.HEALTH_STATUS_UNHEALTHY);
-        // Test that package is now unstartable
-        assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertFalse(mIncrementalStates.isStartable());
+        // Test that package is still startable
+        assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
+        assertTrue(mIncrementalStates.isStartable());
         assertEquals(PackageManager.UNSTARTABLE_REASON_UNKNOWN, mUnstartableReason.get());
     }
 
@@ -112,73 +108,34 @@
     }
 
     /**
-     * Test that the package becomes unstartable when health status indicate storage issues.
+     * Test that the package is still startable when health status indicate storage issues.
      */
     @Test
     public void testStartableTransition_IncrementalStorageBlocked() {
         mIncrementalStates.onStorageHealthStatusChanged(
                 IStorageHealthListener.HEALTH_STATUS_UNHEALTHY_STORAGE);
-        // Test that package is now unstartable
-        assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertFalse(mIncrementalStates.isStartable());
-        assertEquals(PackageManager.UNSTARTABLE_REASON_INSUFFICIENT_STORAGE,
+        // Test that package is still startable
+        assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
+        assertTrue(mIncrementalStates.isStartable());
+        assertEquals(PackageManager.UNSTARTABLE_REASON_UNKNOWN,
                 mUnstartableReason.get());
     }
 
     /**
-     * Test that the package becomes unstartable when health status indicates transport issues.
+     * Test that the package is still startable when health status indicates transport issues.
      */
     @Test
     public void testStartableTransition_DataLoaderIntegrityError() {
         mIncrementalStates.onStorageHealthStatusChanged(
                 IStorageHealthListener.HEALTH_STATUS_UNHEALTHY_TRANSPORT);
-        // Test that package is now unstartable
-        assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertFalse(mIncrementalStates.isStartable());
-        assertEquals(PackageManager.UNSTARTABLE_REASON_CONNECTION_ERROR,
+        // Test that package is still startable
+        assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
+        assertTrue(mIncrementalStates.isStartable());
+        assertEquals(PackageManager.UNSTARTABLE_REASON_UNKNOWN,
                 mUnstartableReason.get());
     }
 
     /**
-     * Test that the package becomes unstartable when Incremental Storage is unhealthy, and it
-     * becomes startable again when Incremental Storage is healthy again.
-     */
-    @Test
-    public void testStartableTransition_IncrementalStorageUnhealthyBackToHealthy()
-            throws InterruptedException {
-        mIncrementalStates.onStorageHealthStatusChanged(
-                IStorageHealthListener.HEALTH_STATUS_UNHEALTHY);
-        // Test that package is unstartable
-        assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertFalse(mIncrementalStates.isStartable());
-
-        mIncrementalStates.onStorageHealthStatusChanged(
-                IStorageHealthListener.HEALTH_STATUS_OK);
-        // Test that package is now startable
-        assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertTrue(mIncrementalStates.isStartable());
-    }
-
-    /**
-     * Test that the package becomes unstartable when health status indicates transportation issue,
-     * and it becomes startable again when health status is ok again.
-     */
-    @Test
-    public void testStartableTransition_DataLoaderUnhealthyBackToHealthy()
-            throws InterruptedException {
-        mIncrementalStates.onStorageHealthStatusChanged(
-                IStorageHealthListener.HEALTH_STATUS_UNHEALTHY_TRANSPORT);
-        // Test that package is unstartable
-        assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertFalse(mIncrementalStates.isStartable());
-
-        mIncrementalStates.onStorageHealthStatusChanged(IStorageHealthListener.HEALTH_STATUS_OK);
-        // Test that package is now startable
-        assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertTrue(mIncrementalStates.isStartable());
-    }
-
-    /**
      * Test that when loading progress is 1, the package becomes fully loaded, and the change of
      * Incremental Storage health status does not affect the startable state.
      */
@@ -197,43 +154,11 @@
     }
 
     /**
-     * Test that when loading progress is 1, the package becomes fully loaded, and if the package
-     * was unstartable, it becomes startable.
-     */
-    @Test
-    public void testLoadingTransition_FullyLoadedWhenUnstartable() throws InterruptedException {
-        mIncrementalStates.onStorageHealthStatusChanged(
-                IStorageHealthListener.HEALTH_STATUS_UNHEALTHY);
-        // Test that package is unstartable
-        assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertFalse(mIncrementalStates.isStartable());
-        // Test that package is still loading
-        assertTrue(mIncrementalStates.isLoading());
-
-        mIncrementalStates.setProgress(0.5f);
-        // Test that package is still unstartable
-        assertFalse(mStartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertFalse(mIncrementalStates.isStartable());
-        mIncrementalStates.setProgress(1.0f);
-        // Test that package is now startable
-        assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertTrue(mIncrementalStates.isStartable());
-        // Test that package is now fully loaded
-        assertTrue(mFullyLoadedCalled.block(WAIT_TIMEOUT_MILLIS));
-        assertFalse(mIncrementalStates.isLoading());
-    }
-
-    /**
      * Test startability transitions if app crashes or anrs
      */
     @Test
     public void testStartableTransition_AppCrashOrAnr() {
         mIncrementalStates.onCrashOrAnr();
-        assertFalse(mIncrementalStates.isStartable());
-        mIncrementalStates.setProgress(1.0f);
-        assertTrue(mIncrementalStates.isStartable());
-        mIncrementalStates.onCrashOrAnr();
-        // Test that if fully loaded, app remains startable even if it has crashed
         assertTrue(mIncrementalStates.isStartable());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 6febae0..7f35511 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -1053,6 +1053,35 @@
     }
 
     @Test
+    public void testGetAmbientDisplaySuppressionTokens_default() {
+        createService();
+        BinderService service = mService.getBinderServiceInstance();
+
+        assertThat(service.getAmbientDisplaySuppressionTokens()).isEmpty();
+    }
+
+    @Test
+    public void testGetAmbientDisplaySuppressionTokens_singleToken() {
+        createService();
+        BinderService service = mService.getBinderServiceInstance();
+        service.suppressAmbientDisplay("test1", true);
+        service.suppressAmbientDisplay("test2", false);
+
+        assertThat(service.getAmbientDisplaySuppressionTokens()).containsExactly("test1");
+    }
+
+    @Test
+    public void testGetAmbientDisplaySuppressionTokens_multipleTokens() {
+        createService();
+        BinderService service = mService.getBinderServiceInstance();
+        service.suppressAmbientDisplay("test1", true);
+        service.suppressAmbientDisplay("test2", true);
+
+        assertThat(service.getAmbientDisplaySuppressionTokens())
+                .containsExactly("test1", "test2");
+    }
+
+    @Test
     public void testSetPowerBoost_redirectsCallToNativeWrapper() {
         createService();
         mService.systemReady(null);
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index c430503..0ad669f 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -728,7 +728,6 @@
         assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
     }
 
-    @Ignore
     @Test
     public void testPredictionTimedOut() throws Exception {
         // Set it to timeout or usage, so that prediction can override it
@@ -1257,6 +1256,7 @@
         assertBucket(STANDBY_BUCKET_ACTIVE);
     }
 
+    @Ignore
     @Test
     public void testPredictionStrikesBack() throws Exception {
         reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
diff --git a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
new file mode 100644
index 0000000..40575e4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
@@ -0,0 +1,304 @@
+/**
+ * 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.
+ */
+
+package com.android.server.utils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.TraceBuffer;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test class for {@link Watcher}, {@link Watchable}, {@link WatchableImpl},
+ * {@link WatchedArrayMap}, {@link WatchedSparseArray}, and
+ * {@link WatchedSparseBooleanArray}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:WatcherTest
+ */
+@SmallTest
+public class WatcherTest {
+
+    // A small Watchable leaf node
+    private class Leaf extends WatchableImpl {
+        private int datum = 0;
+        void set(int i) {
+            if (datum != i) {
+                datum = i;
+                dispatchChange(this);
+            }
+        }
+        void tick() {
+            set(datum + 1);
+        }
+    }
+
+    // A top-most watcher.  It counts the number of notifications that it receives.
+    private class Tester extends Watcher {
+        // The count of changes.
+        public int changes = 0;
+
+        // The single Watchable that this monitors.
+        public final Watchable mWatched;
+
+        // The key, used for messages
+        public String mKey;
+
+        // Create the Tester with a Watcher
+        public Tester(Watchable w, String k) {
+            mWatched = w;
+            mKey = k;
+        }
+
+        // Listen for events
+        public void register() {
+            mWatched.registerObserver(this);
+        }
+
+        // Stop listening for events
+        public void unregister() {
+            mWatched.unregisterObserver(this);
+        }
+
+        // Count the number of notifications received.
+        @Override
+        public void onChange(Watchable what) {
+            changes++;
+        }
+
+        // Verify the count.
+        public void verify(int want, String msg) {
+            assertEquals(mKey + " " + msg, want, changes);
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void test_notify() {
+
+        Tester tester;
+
+        // Create a few leaves
+        Leaf a = new Leaf();
+        Leaf b = new Leaf();
+        Leaf c = new Leaf();
+        Leaf d = new Leaf();
+
+        // Basic test.  Create a leaf and verify that changes to the leaf get notified to
+        // the tester.
+        tester = new Tester(a, "Leaf");
+        tester.verify(0, "Initial leaf - no registration");
+        a.tick();
+        tester.verify(0, "Updates with no registration");
+        tester.register();
+        a.tick();
+        tester.verify(1, "Updates with registration");
+        a.tick();
+        a.tick();
+        tester.verify(3, "Updates with registration");
+
+        // Add the same leaf to more than one tester.  Verify that a change to the leaf is seen by
+        // all registered listeners.
+        Tester buddy1 = new Tester(a, "Leaf2");
+        Tester buddy2 = new Tester(a, "Leaf3");
+        buddy1.verify(0, "Initial leaf - no registration");
+        buddy2.verify(0, "Initial leaf - no registration");
+        a.tick();
+        tester.verify(4, "Updates with buddies");
+        buddy1.verify(0, "Updates - no registration");
+        buddy2.verify(0, "Updates - no registration");
+        buddy1.register();
+        buddy2.register();
+        buddy1.verify(0, "No updates - registered");
+        buddy2.verify(0, "No updates - registered");
+        a.tick();
+        buddy1.verify(1, "First update");
+        buddy2.verify(1, "First update");
+        buddy1.unregister();
+        a.tick();
+        buddy1.verify(1, "Second update - unregistered");
+        buddy2.verify(2, "Second update");
+
+        buddy1 = null;
+        buddy2 = null;
+
+        final int INDEX_A = 1;
+        final int INDEX_B = 2;
+        final int INDEX_C = 3;
+        final int INDEX_D = 4;
+
+        // Test WatchedArrayMap
+        WatchedArrayMap<Integer, Leaf> am = new WatchedArrayMap<>();
+        am.put(INDEX_A, a);
+        am.put(INDEX_B, b);
+        tester = new Tester(am, "WatchedArrayMap");
+        tester.verify(0, "Initial array - no registration");
+        a.tick();
+        tester.verify(0, "Updates with no registration");
+        tester.register();
+        tester.verify(0, "Updates with no registration");
+        a.tick();
+        tester.verify(1, "Updates with registration");
+        b.tick();
+        tester.verify(2, "Updates with registration");
+        am.remove(INDEX_B);
+        tester.verify(3, "Removed b");
+        b.tick();
+        tester.verify(3, "Updates with b not watched");
+        am.put(INDEX_B, b);
+        am.put(INDEX_C, b);
+        tester.verify(5, "Added b twice");
+        b.tick();
+        tester.verify(6, "Changed b - single notification");
+        am.remove(INDEX_C);
+        tester.verify(7, "Removed first b");
+        b.tick();
+        tester.verify(8, "Changed b - single notification");
+        am.remove(INDEX_B);
+        tester.verify(9, "Removed second b");
+        b.tick();
+        tester.verify(9, "Updated b - no change");
+        am.clear();
+        tester.verify(10, "Cleared array");
+        b.tick();
+        tester.verify(10, "Change to b not in array");
+
+        // Special methods
+        am.put(INDEX_C, c);
+        tester.verify(11, "Added c");
+        c.tick();
+        tester.verify(12, "Ticked c");
+        am.setValueAt(am.indexOfKey(INDEX_C), d);
+        tester.verify(13, "Replaced c with d");
+        c.tick();
+        d.tick();
+        tester.verify(14, "Ticked d and c (c not registered)");
+
+        am = null;
+
+        // Test WatchedSparseArray
+        WatchedSparseArray<Leaf> sa = new WatchedSparseArray<>();
+        sa.put(INDEX_A, a);
+        sa.put(INDEX_B, b);
+        tester = new Tester(sa, "WatchedSparseArray");
+        tester.verify(0, "Initial array - no registration");
+        a.tick();
+        tester.verify(0, "Updates with no registration");
+        tester.register();
+        tester.verify(0, "Updates with no registration");
+        a.tick();
+        tester.verify(1, "Updates with registration");
+        b.tick();
+        tester.verify(2, "Updates with registration");
+        sa.remove(INDEX_B);
+        tester.verify(3, "Removed b");
+        b.tick();
+        tester.verify(3, "Updates with b not watched");
+        sa.put(INDEX_B, b);
+        sa.put(INDEX_C, b);
+        tester.verify(5, "Added b twice");
+        b.tick();
+        tester.verify(6, "Changed b - single notification");
+        sa.remove(INDEX_C);
+        tester.verify(7, "Removed first b");
+        b.tick();
+        tester.verify(8, "Changed b - single notification");
+        sa.remove(INDEX_B);
+        tester.verify(9, "Removed second b");
+        b.tick();
+        tester.verify(9, "Updated b - no change");
+        sa.clear();
+        tester.verify(10, "Cleared array");
+        b.tick();
+        tester.verify(10, "Change to b not in array");
+
+        // Special methods
+        sa.put(INDEX_A, a);
+        sa.put(INDEX_B, b);
+        sa.put(INDEX_C, c);
+        tester.verify(13, "Added c");
+        c.tick();
+        tester.verify(14, "Ticked c");
+        sa.setValueAt(sa.indexOfKey(INDEX_C), d);
+        tester.verify(15, "Replaced c with d");
+        c.tick();
+        d.tick();
+        tester.verify(16, "Ticked d and c (c not registered)");
+        sa.append(INDEX_D, c);
+        tester.verify(17, "Append c");
+        c.tick();
+        d.tick();
+        tester.verify(19, "Ticked d and c");
+        assertEquals("Verify four elements", 4, sa.size());
+        // Figure out which elements are at which indices.
+        Leaf[] x = new Leaf[4];
+        for (int i = 0; i < 4; i++) {
+            x[i] = sa.valueAt(i);
+        }
+        sa.removeAtRange(0, 2);
+        tester.verify(20, "Removed two elements in one operation");
+        x[0].tick();
+        x[1].tick();
+        tester.verify(20, "Ticked two removed elements");
+        x[2].tick();
+        x[3].tick();
+        tester.verify(22, "Ticked two remaining elements");
+
+        sa = null;
+
+        // Test WatchedSparseBooleanArray
+        WatchedSparseBooleanArray sb = new WatchedSparseBooleanArray();
+        tester = new Tester(sb, "WatchedSparseBooleanArray");
+        tester.verify(0, "Initial array - no registration");
+        sb.put(INDEX_A, true);
+        tester.verify(0, "Updates with no registration");
+        tester.register();
+        tester.verify(0, "Updates with no registration");
+        sb.put(INDEX_B, true);
+        tester.verify(1, "Updates with registration");
+        sb.put(INDEX_B, true);
+        tester.verify(1, "Null update");
+        sb.put(INDEX_B, false);
+        sb.put(INDEX_C, true);
+        tester.verify(3, "Updates with registration");
+        // Special methods
+        sb.put(INDEX_C, true);
+        tester.verify(3, "Added true, no change");
+        sb.setValueAt(sb.indexOfKey(INDEX_C), false);
+        tester.verify(4, "Replaced true with false");
+        sb.append(INDEX_D, true);
+        tester.verify(5, "Append true");
+
+        sb = null;
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index bf742b7..7ec8689 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -19,6 +19,7 @@
 import static android.app.AppOpsManager.MODE_DEFAULT;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
+import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
@@ -3796,4 +3797,40 @@
             }
         }
     }
+
+    @Test
+    public void testUnlockNotificationChannelImportance() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        channel.lockFields(USER_LOCKED_IMPORTANCE);
+        assertTrue((channel.getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0);
+
+        mHelper.unlockNotificationChannelImportance(PKG_O, UID_O, channel.getId());
+        assertTrue((channel.getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0);
+
+    }
+
+    @Test
+    public void testUnlockAllNotificationChannels() {
+        NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
+        NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_P, UID_P, channelB, true, false);
+        NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
+        mHelper.createNotificationChannel(PKG_P, UID_O, channelC, false, false);
+
+        channelA.lockFields(USER_LOCKED_IMPORTANCE);
+        channelB.lockFields(USER_LOCKED_IMPORTANCE);
+        channelC.lockFields(USER_LOCKED_IMPORTANCE);
+
+        assertTrue((channelA.getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0);
+        assertTrue((channelB.getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0);
+        assertTrue((channelC.getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0);
+
+        mHelper.unlockAllNotificationChannels();
+        assertTrue((channelA.getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0);
+        assertTrue((channelB.getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0);
+        assertTrue((channelC.getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0);
+
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index f026b85..5685ea5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -197,8 +197,7 @@
 
         // Add activity that should be shown on the keyguard.
         final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mAtm)
-                .setCreateTask(true)
-                .setStack(stack)
+                .setTask(stack)
                 .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
                 .build();
 
@@ -225,8 +224,8 @@
         final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
         final Task alwaysOnTopStack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM,
                 ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(alwaysOnTopStack).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setTask(alwaysOnTopStack).build();
         alwaysOnTopStack.setAlwaysOnTop(true);
         taskDisplayArea.positionChildAt(POSITION_TOP, alwaysOnTopStack,
                 false /* includingParents */);
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 f1d3e18..0654968 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -362,8 +362,7 @@
                 .setDisplay(addNewDisplayContentAt(DisplayContent.POSITION_BOTTOM))
                 .build();
         final ActivityRecord activityOnNewDisplay = new ActivityBuilder(mAtm)
-                .setStack(stack)
-                .setCreateTask(true)
+                .setTask(stack)
                 .setProcessName("new")
                 .build();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index f378345..cf7f741 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -59,9 +59,9 @@
 import static com.android.server.wm.Task.ActivityState.STARTED;
 import static com.android.server.wm.Task.ActivityState.STOPPED;
 import static com.android.server.wm.Task.ActivityState.STOPPING;
-import static com.android.server.wm.Task.STACK_VISIBILITY_INVISIBLE;
-import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE;
-import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+import static com.android.server.wm.Task.TASK_VISIBILITY_INVISIBLE;
+import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE;
+import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -131,8 +131,9 @@
 
     @Before
     public void setUp() throws Exception {
-        mStack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
-        mTask = mStack.getBottomMostTask();
+        mTask = new TaskBuilder(mSupervisor)
+                .setCreateParentTask(true).setCreateActivity(true).build();
+        mStack = mTask.getRootTask();
         mActivity = mTask.getTopNonFinishingActivity();
 
         setBooted(mAtm);
@@ -515,13 +516,13 @@
         mActivity.setState(Task.ActivityState.STOPPED, "Testing");
         spyOn(mStack);
 
-        doReturn(STACK_VISIBILITY_VISIBLE).when(mStack).getVisibility(null);
+        doReturn(TASK_VISIBILITY_VISIBLE).when(mStack).getVisibility(null);
         assertEquals(true, mActivity.shouldResumeActivity(null /* activeActivity */));
 
-        doReturn(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT).when(mStack).getVisibility(null);
+        doReturn(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT).when(mStack).getVisibility(null);
         assertEquals(false, mActivity.shouldResumeActivity(null /* activeActivity */));
 
-        doReturn(STACK_VISIBILITY_INVISIBLE).when(mStack).getVisibility(null);
+        doReturn(TASK_VISIBILITY_INVISIBLE).when(mStack).getVisibility(null);
         assertEquals(false, mActivity.shouldResumeActivity(null /* activeActivity */));
     }
 
@@ -534,7 +535,7 @@
         mActivity.addResultLocked(topActivity, "resultWho", 0, 0, new Intent());
         topActivity.finishing = true;
 
-        doReturn(STACK_VISIBILITY_VISIBLE).when(mStack).getVisibility(null);
+        doReturn(TASK_VISIBILITY_VISIBLE).when(mStack).getVisibility(null);
         assertEquals(true, mActivity.shouldResumeActivity(null /* activeActivity */));
         assertEquals(false, mActivity.shouldPauseActivity(null /*activeActivity */));
     }
@@ -787,7 +788,7 @@
         // Have two tasks (topRootableTask and mTask) as the children of mStack.
         ActivityRecord topActivity = new ActivityBuilder(mActivity.mAtmService)
                 .setCreateTask(true)
-                .setStack(mStack)
+                .setParentTask(mStack)
                 .build();
         Task topRootableTask = topActivity.getTask();
         topRootableTask.moveToFront("test");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index f9ad49b..1d5dc43 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -71,8 +71,8 @@
      */
     @Test
     public void testStoppingActivityRemovedWhenResumed() {
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(mFullscreenStack).build();
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(mFullscreenStack).build();
         mSupervisor.mStoppingActivities.add(firstActivity);
 
         firstActivity.completeResumeLocked();
@@ -85,8 +85,8 @@
      */
     @Test
     public void testReportWaitingActivityLaunchedIfNeeded() {
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(mFullscreenStack).build();
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(mFullscreenStack).build();
 
         final WaitResult taskToFrontWait = new WaitResult();
         mSupervisor.mWaitingActivityLaunched.add(taskToFrontWait);
@@ -153,7 +153,7 @@
     @Test
     public void testNotifyTaskFocusChanged() {
         final ActivityRecord fullScreenActivityA = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(mFullscreenStack).build();
+                .setParentTask(mFullscreenStack).build();
         final Task taskA = fullScreenActivityA.getTask();
 
         final TaskChangeNotificationController taskChangeNotifier =
@@ -166,7 +166,7 @@
         reset(taskChangeNotifier);
 
         final ActivityRecord fullScreenActivityB = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(mFullscreenStack).build();
+                .setParentTask(mFullscreenStack).build();
         final Task taskB = fullScreenActivityB.getTask();
 
         mAtm.setResumedActivityUncheckLocked(fullScreenActivityB, "resumeB");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index b632331..faf4f52 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -43,10 +43,10 @@
 import static com.android.server.wm.Task.ActivityState.STOPPED;
 import static com.android.server.wm.Task.ActivityState.STOPPING;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
-import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT;
-import static com.android.server.wm.Task.STACK_VISIBILITY_INVISIBLE;
-import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE;
-import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT;
+import static com.android.server.wm.Task.TASK_VISIBILITY_INVISIBLE;
+import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE;
+import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
 import static com.android.server.wm.TaskDisplayArea.getStackAbove;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
@@ -123,7 +123,7 @@
         final Task destStack = mDefaultTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        mTask.reparent(destStack, true /* toTop */, Task.REPARENT_KEEP_STACK_AT_FRONT,
+        mTask.reparent(destStack, true /* toTop */, Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT,
                 false /* animate */, true /* deferResume*/,
                 "testResumedActivityFromTaskReparenting");
 
@@ -140,7 +140,7 @@
 
         final Task destStack = mDefaultTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        mTask.reparent(destStack, true /*toTop*/, REPARENT_MOVE_STACK_TO_FRONT, false, false,
+        mTask.reparent(destStack, true /*toTop*/, REPARENT_MOVE_ROOT_TASK_TO_FRONT, false, false,
                 "testResumedActivityFromActivityReparenting");
 
         assertNull(mStack.getResumedActivity());
@@ -242,8 +242,7 @@
     public void testRemoveOrganizedTask_UpdateStackReference() {
         final Task rootHomeTask = mDefaultTaskDisplayArea.getRootHomeTask();
         final ActivityRecord homeActivity = new ActivityBuilder(mAtm)
-                .setStack(rootHomeTask)
-                .setCreateTask(true)
+                .setTask(rootHomeTask)
                 .build();
         final Task secondaryStack = mAtm.mTaskOrganizerController.createRootTask(
                 rootHomeTask.getDisplayContent(), WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
@@ -291,7 +290,7 @@
 
     @Test
     public void testStopActivityWhenActivityDestroyed() {
-        final ActivityRecord r = new ActivityBuilder(mAtm).setTask(mTask).build();
+        final ActivityRecord r = new ActivityBuilder(mAtm).setCreateTask(true).build();
         r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
         mStack.moveToFront("testStopActivityWithDestroy");
         r.stopIfPossible();
@@ -303,7 +302,6 @@
     public void testFindTaskWithOverlay() {
         final ActivityRecord r = new ActivityBuilder(mAtm)
                 .setCreateTask(true)
-                .setStack(mStack)
                 .setUid(0)
                 .build();
         final Task task = r.getTask();
@@ -314,7 +312,7 @@
 
         final RootWindowContainer.FindTaskResult result =
                 new RootWindowContainer.FindTaskResult();
-        result.process(r, mStack);
+        result.process(r, task);
 
         assertEquals(r, task.getTopNonFinishingActivity(false /* includeOverlays */));
         assertEquals(taskOverlay, task.getTopNonFinishingActivity(true /* includeOverlays */));
@@ -355,9 +353,11 @@
         final TaskDisplayArea taskDisplayArea = addNewDisplayContentAt(DisplayContent.POSITION_TOP)
                 .getDefaultTaskDisplayArea();
         final Task stack1 = createStackForShouldBeVisibleTest(taskDisplayArea,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */,
+                true /* twoLevelTask */);
         final Task stack2 = createStackForShouldBeVisibleTest(taskDisplayArea,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */,
+                true /* twoLevelTask */);
 
         // Do not move display to back because there is still another stack.
         stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.getTopMostTask());
@@ -377,8 +377,7 @@
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         // Add an activity to the pinned stack so it isn't considered empty for visibility check.
         final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
-                .setCreateTask(true)
-                .setStack(pinnedStack)
+                .setTask(pinnedStack)
                 .build();
 
         assertTrue(homeStack.shouldBeVisible(null /* starting */));
@@ -419,10 +418,10 @@
         assertFalse(homeStack.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenPrimary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenSecondary.getVisibility(null /* starting */));
 
         // Home stack should be visible if one of the halves of split-screen is translucent.
@@ -430,11 +429,11 @@
         assertTrue(homeStack.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 homeStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenPrimary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenSecondary.getVisibility(null /* starting */));
 
         final Task splitScreenSecondary2 =
@@ -445,9 +444,9 @@
         doReturn(false).when(splitScreenSecondary2).isTranslucent(any());
         assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE,
+        assertEquals(TASK_VISIBILITY_INVISIBLE,
                 splitScreenSecondary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
         // First split-screen secondary should be visible behind another translucent split-screen
@@ -455,9 +454,9 @@
         doReturn(true).when(splitScreenSecondary2).isTranslucent(any());
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitScreenSecondary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
         final Task assistantStack = createStackForShouldBeVisibleTest(
@@ -470,13 +469,13 @@
         assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 assistantStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE,
+        assertEquals(TASK_VISIBILITY_INVISIBLE,
                 splitScreenPrimary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE,
+        assertEquals(TASK_VISIBILITY_INVISIBLE,
                 splitScreenSecondary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE,
+        assertEquals(TASK_VISIBILITY_INVISIBLE,
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
         // Split-screen stacks should be visible behind a translucent fullscreen stack.
@@ -485,13 +484,13 @@
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 assistantStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitScreenPrimary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitScreenSecondary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
         // Assistant stack shouldn't be visible behind translucent split-screen stack,
@@ -506,25 +505,25 @@
             assertTrue(assistantStack.shouldBeVisible(null /* starting */));
             assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
             assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
-            assertEquals(STACK_VISIBILITY_VISIBLE,
+            assertEquals(TASK_VISIBILITY_VISIBLE,
                     assistantStack.getVisibility(null /* starting */));
-            assertEquals(STACK_VISIBILITY_INVISIBLE,
+            assertEquals(TASK_VISIBILITY_INVISIBLE,
                     splitScreenPrimary.getVisibility(null /* starting */));
-            assertEquals(STACK_VISIBILITY_INVISIBLE,
+            assertEquals(TASK_VISIBILITY_INVISIBLE,
                     splitScreenSecondary.getVisibility(null /* starting */));
-            assertEquals(STACK_VISIBILITY_INVISIBLE,
+            assertEquals(TASK_VISIBILITY_INVISIBLE,
                     splitScreenSecondary2.getVisibility(null /* starting */));
         } else {
             assertFalse(assistantStack.shouldBeVisible(null /* starting */));
             assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
             assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
-            assertEquals(STACK_VISIBILITY_INVISIBLE,
+            assertEquals(TASK_VISIBILITY_INVISIBLE,
                     assistantStack.getVisibility(null /* starting */));
-            assertEquals(STACK_VISIBILITY_VISIBLE,
+            assertEquals(TASK_VISIBILITY_VISIBLE,
                     splitScreenPrimary.getVisibility(null /* starting */));
-            assertEquals(STACK_VISIBILITY_INVISIBLE,
+            assertEquals(TASK_VISIBILITY_INVISIBLE,
                     splitScreenSecondary.getVisibility(null /* starting */));
-            assertEquals(STACK_VISIBILITY_VISIBLE,
+            assertEquals(TASK_VISIBILITY_VISIBLE,
                     splitScreenSecondary2.getVisibility(null /* starting */));
         }
     }
@@ -549,33 +548,33 @@
         // Re-parent home to split secondary.
         homeStack.reparent(splitSecondary, POSITION_TOP);
         // Current tasks should be visible.
-        assertEquals(STACK_VISIBILITY_VISIBLE, splitPrimary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE, splitSecondary.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, splitPrimary.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, splitSecondary.getVisibility(null /* starting */));
         // Home task should still be visible even though it is a child of another visible task.
-        assertEquals(STACK_VISIBILITY_VISIBLE, homeStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, homeStack.getVisibility(null /* starting */));
 
 
         // Add fullscreen translucent task that partially occludes split tasks
         final Task translucentStack = createStandardStackForVisibilityTest(
                 WINDOWING_MODE_FULLSCREEN, true /* translucent */);
         // Fullscreen translucent task should be visible
-        assertEquals(STACK_VISIBILITY_VISIBLE, translucentStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, translucentStack.getVisibility(null /* starting */));
         // Split tasks should be visible behind translucent
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitPrimary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitSecondary.getVisibility(null /* starting */));
         // Home task should be visible behind translucent since its parent is visible behind
         // translucent.
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 homeStack.getVisibility(null /* starting */));
 
 
         // Hide split-secondary
         splitSecondary.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, true /* set */);
         // Home split secondary and home task should be invisible.
-        assertEquals(STACK_VISIBILITY_INVISIBLE, splitSecondary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_INVISIBLE, splitSecondary.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
     }
 
     @Test
@@ -587,9 +586,9 @@
                 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
 
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 bottomStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 translucentStack.getVisibility(null /* starting */));
     }
 
@@ -605,10 +604,10 @@
                 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
 
-        assertEquals(STACK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE,
+        assertEquals(TASK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_INVISIBLE,
                 translucentStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
     }
 
     @Test
@@ -623,10 +622,10 @@
                 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
 
-        assertEquals(STACK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 opaqueStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 translucentStack.getVisibility(null /* starting */));
     }
 
@@ -639,9 +638,9 @@
                 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         true /* translucent */);
 
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 bottomTranslucentStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 translucentStack.getVisibility(null /* starting */));
     }
 
@@ -654,9 +653,9 @@
                 createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
                         false /* translucent */);
 
-        assertEquals(STACK_VISIBILITY_INVISIBLE,
+        assertEquals(TASK_VISIBILITY_INVISIBLE,
                 bottomTranslucentStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
     }
 
     @Test
@@ -670,16 +669,15 @@
         final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+        assertEquals(TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 bottomStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
+        assertEquals(TASK_VISIBILITY_VISIBLE,
                 translucentStack.getVisibility(null /* starting */));
         // Add an activity to the pinned stack so it isn't considered empty for visibility check.
         final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
-                .setCreateTask(true)
-                .setStack(pinnedStack)
+                .setTask(pinnedStack)
                 .build();
-        assertEquals(STACK_VISIBILITY_VISIBLE, pinnedStack.getVisibility(null /* starting */));
+        assertEquals(TASK_VISIBILITY_VISIBLE, pinnedStack.getVisibility(null /* starting */));
     }
 
     @Test
@@ -689,8 +687,7 @@
         ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
         if (topRunningHomeActivity == null) {
             topRunningHomeActivity = new ActivityBuilder(mAtm)
-                    .setStack(homeStack)
-                    .setCreateTask(true)
+                    .setTask(homeStack)
                     .build();
         }
 
@@ -721,7 +718,7 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
 
         final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
-                    .setStack(homeStack)
+                    .setParentTask(homeStack)
                     .setCreateTask(true)
                     .build();
         final Task task = firstActivity.getTask();
@@ -985,14 +982,29 @@
         return stack;
     }
 
-    @SuppressWarnings("TypeParameterUnusedInFormals")
     private Task createStackForShouldBeVisibleTest(
             TaskDisplayArea taskDisplayArea, int windowingMode, int activityType, boolean onTop) {
+        return createStackForShouldBeVisibleTest(taskDisplayArea,
+                windowingMode, activityType, onTop, false /* twoLevelTask */);
+    }
+
+    @SuppressWarnings("TypeParameterUnusedInFormals")
+    private Task createStackForShouldBeVisibleTest(TaskDisplayArea taskDisplayArea,
+            int windowingMode, int activityType, boolean onTop, boolean twoLevelTask) {
         final Task task;
         if (activityType == ACTIVITY_TYPE_HOME) {
             task = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
             mDefaultTaskDisplayArea.positionChildAt(onTop ? POSITION_TOP : POSITION_BOTTOM, task,
                     false /* includingParents */);
+        } else if (twoLevelTask) {
+            task = new TaskBuilder(mSupervisor)
+                    .setTaskDisplayArea(taskDisplayArea)
+                    .setWindowingMode(windowingMode)
+                    .setActivityType(activityType)
+                    .setOnTop(onTop)
+                    .setCreateActivity(true)
+                    .setCreateParentTask(true)
+                    .build().getRootTask();
         } else {
             task = new TaskBuilder(mSupervisor)
                     .setTaskDisplayArea(taskDisplayArea)
@@ -1154,7 +1166,7 @@
         ActivityRecord activity = homeStack.topRunningActivity();
         if (activity == null) {
             activity = new ActivityBuilder(mAtm)
-                    .setStack(homeStack)
+                    .setParentTask(homeStack)
                     .setCreateTask(true)
                     .build();
         }
@@ -1319,8 +1331,7 @@
 
     @Test
     public void testResetTaskWithFinishingActivities() {
-        final ActivityRecord taskTop =
-                new ActivityBuilder(mAtm).setStack(mStack).setCreateTask(true).build();
+        final ActivityRecord taskTop = new ActivityBuilder(mAtm).setTask(mStack).build();
         // Make all activities in the task are finishing to simulate Task#getTopActivity
         // returns null.
         taskTop.finishing = true;
@@ -1334,10 +1345,8 @@
     public void testIterateOccludedActivity() {
         final ArrayList<ActivityRecord> occludedActivities = new ArrayList<>();
         final Consumer<ActivityRecord> handleOccludedActivity = occludedActivities::add;
-        final ActivityRecord bottomActivity =
-                new ActivityBuilder(mAtm).setStack(mStack).setTask(mTask).build();
-        final ActivityRecord topActivity =
-                new ActivityBuilder(mAtm).setStack(mStack).setTask(mTask).build();
+        final ActivityRecord bottomActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
+        final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
         // Top activity occludes bottom activity.
         doReturn(true).when(mStack).shouldBeVisible(any());
         assertTrue(topActivity.shouldBeVisible());
@@ -1355,8 +1364,7 @@
         assertThat(occludedActivities).isEmpty();
 
         // A finishing activity should not occlude other activities behind.
-        final ActivityRecord finishingActivity =
-                new ActivityBuilder(mAtm).setStack(mStack).setTask(mTask).build();
+        final ActivityRecord finishingActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
         finishingActivity.finishing = true;
         doCallRealMethod().when(finishingActivity).occludesParent();
         assertTrue(topActivity.shouldBeVisible());
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 3720e520..a7ced1d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -486,7 +486,7 @@
         final ActivityStarter starter = prepareStarter(0);
 
         final LockTaskController lockTaskController = mAtm.getLockTaskController();
-        doReturn(true).when(lockTaskController).isLockTaskModeViolation(any());
+        doReturn(true).when(lockTaskController).isNewTaskLockTaskModeViolation(any());
 
         final int result = starter.setReason("testTaskModeViolation").execute();
 
@@ -712,10 +712,10 @@
         // Put 2 tasks in the same stack (simulate the behavior of home stack).
         final Task rootTask = new TaskBuilder(mSupervisor).build();
         final ActivityRecord activity = new ActivityBuilder(mAtm)
-                .setStack(rootTask)
+                .setParentTask(rootTask)
                 .setCreateTask(true).build();
         new ActivityBuilder(mAtm)
-                .setStack(activity.getRootTask())
+                .setParentTask(activity.getRootTask())
                 .setCreateTask(true).build();
 
         // Create a top finishing activity.
diff --git a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
index 0f54895..9d8710d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
@@ -63,8 +62,7 @@
 
     @Test
     public void testDeferring() {
-        final ActivityRecord activity1 = createActivityRecord(mDisplayContent,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         final ActivityRecord activity2 = createAppWindow(activity1.getTask(), ACTIVITY_TYPE_STANDARD,
                 "activity2").mActivityRecord;
         final AnimatingActivityRegistry registry =
@@ -87,8 +85,7 @@
 
     @Test
     public void testContainerRemoved() {
-        final ActivityRecord window1 = createActivityRecord(mDisplayContent,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord window1 = createActivityRecord(mDisplayContent);
         final ActivityRecord window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD,
                 "window2").mActivityRecord;
         final AnimatingActivityRegistry registry =
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 30502d8..87a5985 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -58,7 +58,7 @@
     private ActivityRecord mActivity;
 
     public void setUpOnDisplay(DisplayContent dc) {
-        mActivity = createTestActivityRecord(dc, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
+        mActivity = createActivityRecord(dc, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
         mTask = mActivity.getTask();
         mStack = mTask.getRootTask();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index c1212f5..bc4f16e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -132,13 +132,11 @@
 
     @Test
     public void testGetAnimationTargets_visibilityAlreadyUpdated() {
-        // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, visible)
-        //                   +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, invisible)
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity1 = createTestActivityRecord(stack1);
+        // [DisplayContent] -+- [Task1] - [ActivityRecord1] (opening, visible)
+        //                   +- [Task2] - [ActivityRecord2] (closing, invisible)
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
 
-        final Task stack2 = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity2 = createTestActivityRecord(stack2);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
         activity2.setVisible(false);
         activity2.mVisibleRequested = false;
 
@@ -161,16 +159,14 @@
 
     @Test
     public void testGetAnimationTargets_visibilityAlreadyUpdated_butForcedTransitionRequested() {
-        // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (closing, invisible)
-        //                   +- [TaskStack2] - [Task2] - [ActivityRecord2] (opening, visible)
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity1 = createTestActivityRecord(stack1);
+        // [DisplayContent] -+- [Task1] - [ActivityRecord1] (closing, invisible)
+        //                   +- [Task2] - [ActivityRecord2] (opening, visible)
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         activity1.setVisible(true);
         activity1.mVisibleRequested = true;
         activity1.mRequestForceTransition = true;
 
-        final Task stack2 = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity2 = createTestActivityRecord(stack2);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
         activity2.setVisible(false);
         activity2.mVisibleRequested = false;
         activity2.mRequestForceTransition = true;
@@ -195,10 +191,8 @@
     @Test
     public void testGetAnimationTargets_exitingBeforeTransition() {
         // Create another non-empty task so the animation target won't promote to task display area.
-        createTestActivityRecord(
-                mDisplayContent.getDefaultTaskDisplayArea().getOrCreateRootHomeTask());
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity = createTestActivityRecord(stack);
+        createActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent);
         activity.setVisible(false);
         activity.mIsExiting = true;
 
@@ -208,19 +202,18 @@
         // Animate closing apps even if it's not visible when it is exiting before we had a chance
         // to play the transition animation.
         assertEquals(
-                new ArraySet<>(new WindowContainer[]{stack}),
+                new ArraySet<>(new WindowContainer[]{activity.getRootTask()}),
                 AppTransitionController.getAnimationTargets(
                         new ArraySet<>(), closing, false /* visible */));
     }
 
     @Test
     public void testGetAnimationTargets_windowsAreBeingReplaced() {
-        // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, visible)
-        //                                                      +- [AppWindow1] (being-replaced)
-        //                   +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, invisible)
-        //                                                      +- [AppWindow2] (being-replaced)
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity1 = createTestActivityRecord(stack1);
+        // [DisplayContent] -+- [Task1] - [ActivityRecord1] (opening, visible)
+        //                                       +- [AppWindow1] (being-replaced)
+        //                   +- [Task2] - [ActivityRecord2] (closing, invisible)
+        //                                       +- [AppWindow2] (being-replaced)
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
                 TYPE_BASE_APPLICATION);
         attrs.setTitle("AppWindow1");
@@ -228,8 +221,7 @@
         appWindow1.mWillReplaceWindow = true;
         activity1.addWindow(appWindow1);
 
-        final Task stack2 = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity2 = createTestActivityRecord(stack2);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
         activity2.setVisible(false);
         activity2.mVisibleRequested = false;
         attrs.setTitle("AppWindow2");
@@ -246,7 +238,7 @@
         // Don't animate closing apps if it's already invisible even though its windows are being
         // replaced.
         assertEquals(
-                new ArraySet<>(new WindowContainer[]{stack1}),
+                new ArraySet<>(new WindowContainer[]{activity1.getRootTask()}),
                 AppTransitionController.getAnimationTargets(
                         opening, closing, true /* visible */));
         assertEquals(
@@ -257,24 +249,22 @@
 
     @Test
     public void testGetAnimationTargets_openingClosingInDifferentTask() {
-        // [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
-        //                   |                          +- [ActivityRecord2] (invisible)
+        // [DisplayContent] -+- [Task1] -+- [ActivityRecord1] (opening, invisible)
+        //                   |           +- [ActivityRecord2] (invisible)
         //                   |
-        //                   +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible)
-        //                                              +- [ActivityRecord4] (invisible)
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, task1);
+        //                   +- [Task2] -+- [ActivityRecord3] (closing, visible)
+        //                               +- [ActivityRecord4] (invisible)
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         activity1.setVisible(false);
         activity1.mVisibleRequested = true;
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, task1);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent,
+                activity1.getTask());
         activity2.setVisible(false);
         activity2.mVisibleRequested = false;
 
-        final Task stack2 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task2 = createTaskInStack(stack2, 0 /* userId */);
-        final ActivityRecord activity3 = createActivityRecordInTask(mDisplayContent, task2);
-        final ActivityRecord activity4 = createActivityRecordInTask(mDisplayContent, task2);
+        final ActivityRecord activity3 = createActivityRecord(mDisplayContent);
+        final ActivityRecord activity4 = createActivityRecord(mDisplayContent,
+                activity3.getTask());
         activity4.setVisible(false);
         activity4.mVisibleRequested = false;
 
@@ -286,25 +276,24 @@
         // Promote animation targets to TaskStack level. Invisible ActivityRecords don't affect
         // promotion decision.
         assertEquals(
-                new ArraySet<>(new WindowContainer[]{stack1}),
+                new ArraySet<>(new WindowContainer[]{activity1.getRootTask()}),
                 AppTransitionController.getAnimationTargets(
                         opening, closing, true /* visible */));
         assertEquals(
-                new ArraySet<>(new WindowContainer[]{stack2}),
+                new ArraySet<>(new WindowContainer[]{activity3.getRootTask()}),
                 AppTransitionController.getAnimationTargets(
                         opening, closing, false /* visible */));
     }
 
     @Test
     public void testGetAnimationTargets_openingClosingInSameTask() {
-        // [DisplayContent] - [TaskStack] - [Task] -+- [ActivityRecord1] (opening, invisible)
-        //                                          +- [ActivityRecord2] (closing, visible)
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task = createTaskInStack(stack, 0 /* userId */);
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, task);
+        // [DisplayContent] - [Task] -+- [ActivityRecord1] (opening, invisible)
+        //                            +- [ActivityRecord2] (closing, visible)
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         activity1.setVisible(false);
         activity1.mVisibleRequested = true;
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, task);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent,
+                activity1.getTask());
 
         final ArraySet<ActivityRecord> opening = new ArraySet<>();
         opening.add(activity1);
@@ -325,26 +314,24 @@
 
     @Test
     public void testGetAnimationTargets_animateOnlyTranslucentApp() {
-        // [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
-        //                   |                          +- [ActivityRecord2] (visible)
+        // [DisplayContent] -+- [Task1] -+- [ActivityRecord1] (opening, invisible)
+        //                   |           +- [ActivityRecord2] (visible)
         //                   |
-        //                   +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible)
-        //                                              +- [ActivityRecord4] (visible)
+        //                   +- [Task2] -+- [ActivityRecord3] (closing, visible)
+        //                               +- [ActivityRecord4] (visible)
 
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, task1);
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         activity1.setVisible(false);
         activity1.mVisibleRequested = true;
         activity1.setOccludesParent(false);
 
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, task1);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent,
+                activity1.getTask());
 
-        final Task stack2 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task2 = createTaskInStack(stack2, 0 /* userId */);
-        final ActivityRecord activity3 = createActivityRecordInTask(mDisplayContent, task2);
+        final ActivityRecord activity3 = createActivityRecord(mDisplayContent);
         activity3.setOccludesParent(false);
-        final ActivityRecord activity4 = createActivityRecordInTask(mDisplayContent, task2);
+        final ActivityRecord activity4 = createActivityRecord(mDisplayContent,
+                activity3.getTask());
 
         final ArraySet<ActivityRecord> opening = new ArraySet<>();
         opening.add(activity1);
@@ -365,28 +352,26 @@
 
     @Test
     public void testGetAnimationTargets_animateTranslucentAndOpaqueApps() {
-        // [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
-        //                   |                          +- [ActivityRecord2] (opening, invisible)
+        // [DisplayContent] -+- [Task1] -+- [ActivityRecord1] (opening, invisible)
+        //                   |           +- [ActivityRecord2] (opening, invisible)
         //                   |
-        //                   +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible)
-        //                                              +- [ActivityRecord4] (closing, visible)
+        //                   +- [Task2] -+- [ActivityRecord3] (closing, visible)
+        //                               +- [ActivityRecord4] (closing, visible)
 
-        final Task stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, task1);
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
         activity1.setVisible(false);
         activity1.mVisibleRequested = true;
         activity1.setOccludesParent(false);
 
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, task1);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent,
+                activity1.getTask());
         activity2.setVisible(false);
         activity2.mVisibleRequested = true;
 
-        final Task stack2 = createTaskStackOnDisplay(mDisplayContent);
-        final Task task2 = createTaskInStack(stack2, 0 /* userId */);
-        final ActivityRecord activity3 = createActivityRecordInTask(mDisplayContent, task2);
+        final ActivityRecord activity3 = createActivityRecord(mDisplayContent);
         activity3.setOccludesParent(false);
-        final ActivityRecord activity4 = createActivityRecordInTask(mDisplayContent, task2);
+        final ActivityRecord activity4 = createActivityRecord(mDisplayContent,
+                activity3.getTask());
 
         final ArraySet<ActivityRecord> opening = new ArraySet<>();
         opening.add(activity1);
@@ -398,26 +383,24 @@
         // Promote animation targets to TaskStack level even though opening (closing) app is
         // translucent as long as all visible siblings animate at the same time.
         assertEquals(
-                new ArraySet<>(new WindowContainer[]{stack1}),
+                new ArraySet<>(new WindowContainer[]{activity1.getRootTask()}),
                 AppTransitionController.getAnimationTargets(
                         opening, closing, true /* visible */));
         assertEquals(
-                new ArraySet<>(new WindowContainer[]{stack2}),
+                new ArraySet<>(new WindowContainer[]{activity3.getRootTask()}),
                 AppTransitionController.getAnimationTargets(
                         opening, closing, false /* visible */));
     }
 
     @Test
-    public void testGetAnimationTargets_stackContainsMultipleTasks() {
-        // [DisplayContent] - [TaskStack] -+- [Task1] - [ActivityRecord1] (opening, invisible)
-        //                                 +- [Task2] - [ActivityRecord2] (closing, visible)
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final Task task1 = createTaskInStack(stack, 0 /* userId */);
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, task1);
+    public void testGetAnimationTargets_taskContainsMultipleTasks() {
+        // [DisplayContent] - [Task] -+- [Task1] - [ActivityRecord1] (opening, invisible)
+        //                            +- [Task2] - [ActivityRecord2] (closing, visible)
+        final Task parentTask = createTaskStackOnDisplay(mDisplayContent);
+        final ActivityRecord activity1 = createActivityRecordWithParentTask(parentTask);
         activity1.setVisible(false);
         activity1.mVisibleRequested = true;
-        final Task task2 = createTaskInStack(stack, 0 /* userId */);
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, task2);
+        final ActivityRecord activity2 = createActivityRecordWithParentTask(parentTask);
 
         final ArraySet<ActivityRecord> opening = new ArraySet<>();
         opening.add(activity1);
@@ -426,11 +409,11 @@
 
         // Promote animation targets up to Task level, not beyond.
         assertEquals(
-                new ArraySet<>(new WindowContainer[]{task1}),
+                new ArraySet<>(new WindowContainer[]{activity1.getTask()}),
                 AppTransitionController.getAnimationTargets(
                         opening, closing, true /* visible */));
         assertEquals(
-                new ArraySet<>(new WindowContainer[]{task2}),
+                new ArraySet<>(new WindowContainer[]{activity2.getTask()}),
                 AppTransitionController.getAnimationTargets(
                         opening, closing, false /* visible */));
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 485f92f..850e72e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -16,8 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE;
@@ -116,10 +114,8 @@
         final DisplayContent dc2 = createNewDisplay(Display.STATE_ON);
 
         // Create 2 app window tokens to represent 2 activity window.
-        final ActivityRecord activity1 = createTestActivityRecord(dc1,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        final ActivityRecord activity2 = createTestActivityRecord(dc2,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity1 = createActivityRecord(dc1);
+        final ActivityRecord activity2 = createActivityRecord(dc2);
 
         activity1.allDrawn = true;
         activity1.startingDisplayed = true;
@@ -153,7 +149,7 @@
 
         final Task stack1 = createTaskStackOnDisplay(dc1);
         final Task task1 = createTaskInStack(stack1, 0 /* userId */);
-        final ActivityRecord activity1 = createTestActivityRecord(dc1);
+        final ActivityRecord activity1 = createNonAttachedActivityRecord(dc1);
         task1.addChild(activity1, 0);
 
         // Simulate same app is during opening / closing transition set stage.
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
index b93a8fc..fd562c3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
@@ -16,9 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 
@@ -31,7 +28,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.SurfaceControl;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -62,8 +58,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mActivity = createTestActivityRecord(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD);
+        mActivity = createActivityRecord(mDisplayContent);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 6837e0e..28d5ffe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -92,7 +92,7 @@
     public void setUp() throws Exception {
         mStack = createTaskStackOnDisplay(mDisplayContent);
         mTask = createTaskInStack(mStack, 0 /* userId */);
-        mActivity = createTestActivityRecord(mDisplayContent);
+        mActivity = createNonAttachedActivityRecord(mDisplayContent);
 
         mTask.addChild(mActivity, 0);
     }
@@ -307,7 +307,7 @@
         assertEquals(Configuration.ORIENTATION_PORTRAIT, displayConfig.orientation);
         assertEquals(Configuration.ORIENTATION_PORTRAIT, activityConfig.orientation);
 
-        final ActivityRecord topActivity = createTestActivityRecord(mStack);
+        final ActivityRecord topActivity = createActivityRecord(mTask);
         topActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         assertEquals(Configuration.ORIENTATION_LANDSCAPE, displayConfig.orientation);
@@ -490,7 +490,7 @@
     }
 
     private ActivityRecord createTestActivityRecordForGivenTask(Task task) {
-        final ActivityRecord activity = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         task.addChild(activity, 0);
         waitUntilHandlersIdle();
         return activity;
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
index 9a668b9..4a5a81e8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
@@ -67,7 +67,7 @@
         mDisplayAreaGroup.addChild(mTaskDisplayArea, POSITION_TOP);
         mStack = mTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        mActivity = new ActivityBuilder(mAtm).setCreateTask(true).setStack(mStack).build();
+        mActivity = new ActivityBuilder(mAtm).setTask(mStack).build();
         mDisplayContent.setLastFocusedTaskDisplayArea(mTaskDisplayArea);
     }
 
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 f52f983..fbfc0e0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -283,8 +282,7 @@
     @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testComputeImeTarget_startingWindow() {
-        ActivityRecord activity = createActivityRecord(mDisplayContent,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        ActivityRecord activity = createActivityRecord(mDisplayContent);
 
         final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, activity,
                 "startingWin");
@@ -328,7 +326,7 @@
         assertEquals(dc, stack.getDisplayContent());
 
         final Task task = createTaskInStack(stack, 0 /* userId */);
-        final ActivityRecord activity = createTestActivityRecord(dc);
+        final ActivityRecord activity = createNonAttachedActivityRecord(dc);
         task.addChild(activity, 0);
         assertEquals(dc, task.getDisplayContent());
         assertEquals(dc, activity.getDisplayContent());
@@ -399,14 +397,14 @@
         // Add stack with activity.
         final Task stack0 = createTaskStackOnDisplay(dc0);
         final Task task0 = createTaskInStack(stack0, 0 /* userId */);
-        final ActivityRecord activity = createTestActivityRecord(dc0);
+        final ActivityRecord activity = createNonAttachedActivityRecord(dc0);
         task0.addChild(activity, 0);
         dc0.configureDisplayPolicy();
         assertNotNull(dc0.mTapDetector);
 
         final Task stack1 = createTaskStackOnDisplay(dc1);
         final Task task1 = createTaskInStack(stack1, 0 /* userId */);
-        final ActivityRecord activity1 = createTestActivityRecord(dc0);
+        final ActivityRecord activity1 = createNonAttachedActivityRecord(dc0);
         task1.addChild(activity1, 0);
         dc1.configureDisplayPolicy();
         assertNotNull(dc1.mTapDetector);
@@ -1223,7 +1221,7 @@
 
         // Launch another activity before the transition is finished.
         final Task task2 = new TaskBuilder(mSupervisor).setDisplay(mDisplayContent).build();
-        final ActivityRecord app2 = new ActivityBuilder(mAtm).setStack(task2)
+        final ActivityRecord app2 = new ActivityBuilder(mAtm).setTask(task2)
                 .setUseProcess(app.app).build();
         app2.setVisible(false);
         mDisplayContent.mOpeningApps.add(app2);
@@ -1260,8 +1258,7 @@
     @Test
     public void testFinishFixedRotationNoAppTransitioningTask() {
         unblockDisplayRotation(mDisplayContent);
-        final ActivityRecord app = createActivityRecord(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord app = createActivityRecord(mDisplayContent);
         final Task task = app.getTask();
         final ActivityRecord app2 = new ActivityBuilder(mWm.mAtmService).setTask(task).build();
         mDisplayContent.setFixedRotationLaunchingApp(app2, (mDisplayContent.getRotation() + 1) % 4);
@@ -1314,8 +1311,7 @@
         final ActivityRecord pinnedActivity = createActivityRecord(displayContent,
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
         final Task pinnedTask = pinnedActivity.getRootTask();
-        final ActivityRecord homeActivity = createTestActivityRecord(
-                displayContent.getDefaultTaskDisplayArea().getOrCreateRootHomeTask());
+        final ActivityRecord homeActivity = createActivityRecord(displayContent);
         if (displayConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
             homeActivity.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
             pinnedActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -1378,10 +1374,8 @@
         // Skip freezing so the unrelated conditions in updateRotationUnchecked won't disturb.
         doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
 
-        final ActivityRecord activity = createActivityRecord(mDisplayContent,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        final ActivityRecord recentsActivity = createActivityRecord(mDisplayContent,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent);
+        final ActivityRecord recentsActivity = createActivityRecord(mDisplayContent);
         recentsActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
 
         // Do not rotate if the recents animation is animating on top.
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
new file mode 100644
index 0000000..b346bb8
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
@@ -0,0 +1,367 @@
+/*
+ * 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.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.Nullable;
+import android.platform.test.annotations.Presubmit;
+import android.util.Xml;
+import android.view.Display;
+import android.view.DisplayAddress;
+import android.view.DisplayInfo;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Tests for the {@link DisplayWindowSettingsProvider} class.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:DisplayWindowSettingsProviderTests
+ */
+@SmallTest
+@Presubmit
+@WindowTestsBase.UseTestDisplay
+@RunWith(WindowTestRunner.class)
+public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
+    private static final int DISPLAY_PORT = 0xFF;
+    private static final long DISPLAY_MODEL = 0xEEEEEEEEL;
+
+    private static final File TEST_FOLDER = getInstrumentation().getTargetContext().getCacheDir();
+
+    private TestStorage mBaseSettingsStorage;
+    private TestStorage mOverrideSettingsStorage;
+
+    private DisplayContent mPrimaryDisplay;
+    private DisplayContent mSecondaryDisplay;
+
+    @Before
+    public void setUp() throws Exception {
+        deleteRecursively(TEST_FOLDER);
+
+        mBaseSettingsStorage = new TestStorage();
+        mOverrideSettingsStorage = new TestStorage();
+
+        mPrimaryDisplay = mWm.getDefaultDisplayContentLocked();
+        mSecondaryDisplay = mDisplayContent;
+        assertNotEquals(Display.DEFAULT_DISPLAY, mSecondaryDisplay.getDisplayId());
+    }
+
+    @After
+    public void tearDown() {
+        deleteRecursively(TEST_FOLDER);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage() {
+        final String displayIdentifier = mSecondaryDisplay.getDisplayInfo().uniqueId;
+        prepareOverrideDisplaySettings(displayIdentifier);
+
+        SettingsEntry expectedSettings = new SettingsEntry();
+        expectedSettings.mWindowingMode = WINDOWING_MODE_PINNED;
+        readAndAssertExpectedSettings(mPrimaryDisplay, expectedSettings);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage_LegacyDisplayId() {
+        final String displayIdentifier = mPrimaryDisplay.getDisplayInfo().name;
+        prepareOverrideDisplaySettings(displayIdentifier);
+
+        SettingsEntry expectedSettings = new SettingsEntry();
+        expectedSettings.mWindowingMode = WINDOWING_MODE_PINNED;
+        readAndAssertExpectedSettings(mPrimaryDisplay, expectedSettings);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage_LegacyDisplayId_UpdateAfterAccess()
+            throws Exception {
+        // Store display settings with legacy display identifier.
+        final DisplayInfo mPrimaryDisplayInfo = mPrimaryDisplay.getDisplayInfo();
+        final String displayIdentifier = mPrimaryDisplayInfo.name;
+        prepareOverrideDisplaySettings(displayIdentifier);
+
+        // Update settings with new value, should trigger write to injector.
+        DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
+                mBaseSettingsStorage, mOverrideSettingsStorage);
+        SettingsEntry overrideSettings = provider.getOverrideSettings(mPrimaryDisplayInfo);
+        overrideSettings.mForcedDensity = 200;
+        provider.updateOverrideSettings(mPrimaryDisplayInfo, overrideSettings);
+        assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
+
+        // Verify that display identifier was updated.
+        final String newDisplayIdentifier = getStoredDisplayAttributeValue(
+                mOverrideSettingsStorage, "name");
+        assertEquals("Display identifier must be updated to use uniqueId",
+                mPrimaryDisplayInfo.uniqueId, newDisplayIdentifier);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage_UsePortAsId() {
+        final DisplayAddress.Physical displayAddress =
+                DisplayAddress.fromPortAndModel(DISPLAY_PORT, DISPLAY_MODEL);
+        mPrimaryDisplay.getDisplayInfo().address = displayAddress;
+
+        final String displayIdentifier = "port:" + DISPLAY_PORT;
+        prepareOverrideDisplaySettings(displayIdentifier, true /* usePortAsId */);
+
+        SettingsEntry expectedSettings = new SettingsEntry();
+        expectedSettings.mWindowingMode = WINDOWING_MODE_PINNED;
+        readAndAssertExpectedSettings(mPrimaryDisplay, expectedSettings);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage_UsePortAsId_IncorrectAddress() {
+        final String displayIdentifier = mPrimaryDisplay.getDisplayInfo().uniqueId;
+        prepareOverrideDisplaySettings(displayIdentifier, true /* usePortAsId */);
+
+        mPrimaryDisplay.getDisplayInfo().address = DisplayAddress.fromPhysicalDisplayId(123456);
+
+        // Verify that the entry is not matched and default settings are returned instead.
+        SettingsEntry expectedSettings = new SettingsEntry();
+        readAndAssertExpectedSettings(mPrimaryDisplay, expectedSettings);
+    }
+
+    @Test
+    public void testWritingDisplaySettingsToStorage() throws Exception {
+        final DisplayInfo secondaryDisplayInfo = mSecondaryDisplay.getDisplayInfo();
+
+        // Write some settings to storage.
+        DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
+                mBaseSettingsStorage, mOverrideSettingsStorage);
+        SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
+        overrideSettings.mShouldShowSystemDecors = true;
+        overrideSettings.mShouldShowIme = true;
+        provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+        assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
+
+        // Verify that settings were stored correctly.
+        assertEquals("Attribute value must be stored", secondaryDisplayInfo.uniqueId,
+                getStoredDisplayAttributeValue(mOverrideSettingsStorage, "name"));
+        assertEquals("Attribute value must be stored", "true",
+                getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowSystemDecors"));
+        assertEquals("Attribute value must be stored", "true",
+                getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowIme"));
+    }
+
+    @Test
+    public void testWritingDisplaySettingsToStorage_UsePortAsId() throws Exception {
+        prepareOverrideDisplaySettings(null /* displayIdentifier */, true /* usePortAsId */);
+
+        // Store config to use port as identifier.
+        final DisplayInfo secondaryDisplayInfo = mSecondaryDisplay.getDisplayInfo();
+        final DisplayAddress.Physical displayAddress =
+                DisplayAddress.fromPortAndModel(DISPLAY_PORT, DISPLAY_MODEL);
+        secondaryDisplayInfo.address = displayAddress;
+
+        // Write some settings to storage.
+        DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
+                mBaseSettingsStorage, mOverrideSettingsStorage);
+        SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
+        overrideSettings.mShouldShowSystemDecors = true;
+        overrideSettings.mShouldShowIme = true;
+        provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+        assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
+
+        // Verify that settings were stored correctly.
+        assertEquals("Attribute value must be stored", "port:" + DISPLAY_PORT,
+                getStoredDisplayAttributeValue(mOverrideSettingsStorage, "name"));
+        assertEquals("Attribute value must be stored", "true",
+                getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowSystemDecors"));
+        assertEquals("Attribute value must be stored", "true",
+                getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowIme"));
+    }
+
+    /**
+     * Prepares display settings and stores in {@link #mOverrideSettingsStorage}. Uses provided
+     * display identifier and stores windowingMode=WINDOWING_MODE_PINNED.
+     */
+    private void prepareOverrideDisplaySettings(String displayIdentifier) {
+        prepareOverrideDisplaySettings(displayIdentifier, false /* usePortAsId */);
+    }
+
+    private void prepareOverrideDisplaySettings(String displayIdentifier, boolean usePortAsId) {
+        String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<display-settings>\n";
+        if (usePortAsId) {
+            contents += "  <config identifier=\"1\"/>\n";
+        }
+        if (displayIdentifier != null) {
+            contents += "  <display\n"
+                    + "    name=\"" + displayIdentifier + "\"\n"
+                    + "    windowingMode=\"" + WINDOWING_MODE_PINNED + "\"/>\n";
+        }
+        contents += "</display-settings>\n";
+
+        final InputStream is = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
+        mOverrideSettingsStorage.setReadStream(is);
+    }
+
+    private void readAndAssertExpectedSettings(DisplayContent displayContent,
+            SettingsEntry expectedSettings) {
+        final DisplayWindowSettingsProvider provider =
+                new DisplayWindowSettingsProvider(mBaseSettingsStorage, mOverrideSettingsStorage);
+        assertEquals(expectedSettings, provider.getSettings(displayContent.getDisplayInfo()));
+    }
+
+    @Nullable
+    private String getStoredDisplayAttributeValue(TestStorage storage, String attr)
+            throws Exception {
+        try (InputStream stream = storage.openRead()) {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(stream, StandardCharsets.UTF_8.name());
+            int type;
+            while ((type = parser.next()) != XmlPullParser.START_TAG
+                    && type != XmlPullParser.END_DOCUMENT) {
+                // Do nothing.
+            }
+
+            if (type != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("no start tag found");
+            }
+
+            int outerDepth = parser.getDepth();
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                    continue;
+                }
+
+                String tagName = parser.getName();
+                if (tagName.equals("display")) {
+                    return parser.getAttributeValue(null, attr);
+                }
+            }
+        } finally {
+            storage.closeRead();
+        }
+        return null;
+    }
+
+    private static boolean deleteRecursively(File file) {
+        boolean fullyDeleted = true;
+        if (file.isFile()) {
+            return file.delete();
+        } else if (file.isDirectory()) {
+            final File[] files = file.listFiles();
+            for (File child : files) {
+                fullyDeleted &= deleteRecursively(child);
+            }
+            fullyDeleted &= file.delete();
+        }
+        return fullyDeleted;
+    }
+
+    /** In-memory storage implementation. */
+    public class TestStorage implements DisplayWindowSettingsProvider.WritableSettingsStorage {
+        private InputStream mReadStream;
+        private ByteArrayOutputStream mWriteStream;
+
+        private boolean mWasSuccessful;
+
+        /**
+         * Returns input stream for reading. By default tries forward the output stream if previous
+         * write was successful.
+         * @see #closeRead()
+         */
+        @Override
+        public InputStream openRead() throws FileNotFoundException {
+            if (mReadStream == null && mWasSuccessful) {
+                mReadStream = new ByteArrayInputStream(mWriteStream.toByteArray());
+            }
+            if (mReadStream == null) {
+                throw new FileNotFoundException();
+            }
+            if (mReadStream.markSupported()) {
+                mReadStream.mark(Integer.MAX_VALUE);
+            }
+            return mReadStream;
+        }
+
+        /** Must be called after each {@link #openRead} to reset the position in the stream. */
+        void closeRead() throws IOException {
+            if (mReadStream == null) {
+                throw new FileNotFoundException();
+            }
+            if (mReadStream.markSupported()) {
+                mReadStream.reset();
+            }
+            mReadStream = null;
+        }
+
+        /**
+         * Creates new or resets existing output stream for write. Automatically closes previous
+         * read stream, since following reads should happen based on this new write.
+         */
+        @Override
+        public OutputStream startWrite() throws IOException {
+            if (mWriteStream == null) {
+                mWriteStream = new ByteArrayOutputStream();
+            } else {
+                mWriteStream.reset();
+            }
+            if (mReadStream != null) {
+                closeRead();
+            }
+            return mWriteStream;
+        }
+
+        @Override
+        public void finishWrite(OutputStream os, boolean success) {
+            mWasSuccessful = success;
+            try {
+                os.close();
+            } catch (IOException e) {
+                // This method can't throw IOException since the super implementation doesn't, so
+                // we just wrap it in a RuntimeException so we end up crashing the test all the
+                // same.
+                throw new RuntimeException(e);
+            }
+        }
+
+        /** Overrides the read stream of the injector. By default it uses current write stream. */
+        private void setReadStream(InputStream is) {
+            mReadStream = is;
+        }
+
+        private boolean wasWriteSuccessful() {
+            return mWasSuccessful;
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index a3d3739a..2ca5583 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -17,15 +17,12 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
 import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DISABLED;
 import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED;
 import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
 import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
 
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -40,12 +37,11 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Matchers.eq;
 
+import android.annotation.NonNull;
 import android.app.WindowConfiguration;
 import android.content.res.Configuration;
 import android.platform.test.annotations.Presubmit;
-import android.util.Xml;
 import android.view.Display;
-import android.view.DisplayAddress;
 import android.view.DisplayInfo;
 import android.view.Surface;
 
@@ -53,21 +49,14 @@
 
 import com.android.server.LocalServices;
 import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlPullParser;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Tests for the {@link DisplayWindowSettings} class.
@@ -80,12 +69,8 @@
 @WindowTestsBase.UseTestDisplay
 @RunWith(WindowTestRunner.class)
 public class DisplayWindowSettingsTests extends WindowTestsBase {
-
-    private static final int DISPLAY_PORT = 0xFF;
-    private static final long DISPLAY_MODEL = 0xEEEEEEEEL;
-
-    private static final File TEST_FOLDER = getInstrumentation().getTargetContext().getCacheDir();
-    private DisplayWindowSettings mTarget;
+    private TestSettingsProvider mSettingsProvider;
+    private DisplayWindowSettings mDisplayWindowSettings;
 
     private DisplayInfo mPrivateDisplayInfo;
 
@@ -93,18 +78,19 @@
     private DisplayContent mSecondaryDisplay;
     private DisplayContent mPrivateDisplay;
 
-    private TestStorage mStorage;
-
     @Before
     public void setUp() throws Exception {
-        deleteRecursively(TEST_FOLDER);
-
+        // TODO(b/121296525): We may want to restore other display settings (not only overscans in
+        // testPersistOverscan*test) on mPrimaryDisplay and mSecondaryDisplay back to default
+        // values after each test finishes, since we are going to reuse a singleton
+        // WindowManagerService instance among all tests that extend {@link WindowTestsBase} class
+        // (b/113239988).
         mWm.mAtmService.mSupportsFreeformWindowManagement = false;
         mWm.setIsPc(false);
         mWm.setForceDesktopModeOnExternalDisplays(false);
 
-        mStorage = new TestStorage();
-        mTarget = new DisplayWindowSettings(mWm, mStorage);
+        mSettingsProvider = new TestSettingsProvider();
+        mDisplayWindowSettings = new DisplayWindowSettings(mWm, mSettingsProvider);
 
         mPrimaryDisplay = mWm.getDefaultDisplayContentLocked();
         mSecondaryDisplay = mDisplayContent;
@@ -117,20 +103,9 @@
         assertNotEquals(mSecondaryDisplay.getDisplayId(), mPrivateDisplay.getDisplayId());
     }
 
-    @After
-    public void tearDown() {
-        deleteRecursively(TEST_FOLDER);
-
-        // TODO(b/121296525): We may want to restore other display settings (not only overscans in
-        // testPersistOverscan*test) on mPrimaryDisplay and mSecondaryDisplay back to default
-        // values after each test finishes, since we are going to reuse a singleton
-        // WindowManagerService instance among all tests that extend {@link WindowTestsBase} class
-        // (b/113239988).
-    }
-
     @Test
     public void testPrimaryDisplayDefaultToFullscreen_NoFreeformSupport() {
-        mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
 
         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
                 mPrimaryDisplay.getWindowingMode());
@@ -140,7 +115,7 @@
     public void testPrimaryDisplayDefaultToFullscreen_HasFreeformSupport_NonPc_NoDesktopMode() {
         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
 
-        mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
 
         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
                 mPrimaryDisplay.getWindowingMode());
@@ -151,7 +126,7 @@
         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
         mWm.setForceDesktopModeOnExternalDisplays(true);
 
-        mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
 
         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
                 mPrimaryDisplay.getWindowingMode());
@@ -162,20 +137,19 @@
         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
         mWm.setIsPc(true);
 
-        mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
 
-        assertEquals(WINDOWING_MODE_FREEFORM,
-                mPrimaryDisplay.getWindowingMode());
+        assertEquals(WINDOWING_MODE_FREEFORM, mPrimaryDisplay.getWindowingMode());
     }
 
     @Test
     public void testPrimaryDisplayUpdateToFreeform_HasFreeformSupport_IsPc() {
-        mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
 
         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
         mWm.setIsPc(true);
 
-        mTarget.updateSettingsForDisplay(mPrimaryDisplay);
+        mDisplayWindowSettings.updateSettingsForDisplay(mPrimaryDisplay);
 
         assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
                 mPrimaryDisplay.getWindowingMode());
@@ -183,7 +157,7 @@
 
     @Test
     public void testSecondaryDisplayDefaultToFullscreen_NoFreeformSupport() {
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
                 mSecondaryDisplay.getWindowingMode());
@@ -193,7 +167,7 @@
     public void testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_NonPc_NoDesktopMode() {
         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
 
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
                 mSecondaryDisplay.getWindowingMode());
@@ -204,7 +178,7 @@
         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
         mWm.setForceDesktopModeOnExternalDisplays(true);
 
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(WINDOWING_MODE_FREEFORM,
                 mSecondaryDisplay.getWindowingMode());
@@ -215,7 +189,7 @@
         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
         mWm.setIsPc(true);
 
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(WINDOWING_MODE_FREEFORM,
                 mSecondaryDisplay.getWindowingMode());
@@ -228,7 +202,7 @@
         final int originalDensity = mSecondaryDisplay.mBaseDisplayDensity;
         final boolean originalScalingDisabled = mSecondaryDisplay.mDisplayScalingDisabled;
 
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(originalWidth, mSecondaryDisplay.mBaseDisplayWidth);
         assertEquals(originalHeight, mSecondaryDisplay.mBaseDisplayHeight);
@@ -245,8 +219,9 @@
             return null;
         }).when(mWm.mDisplayManagerInternal).getNonOverrideDisplayInfo(anyInt(), any());
 
-        mTarget.setForcedSize(mSecondaryDisplay, 1000 /* width */, 2000 /* height */);
-        applySettingsToDisplayByNewInstance(mSecondaryDisplay);
+        mDisplayWindowSettings.setForcedSize(mSecondaryDisplay, 1000 /* width */,
+                2000 /* height */);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(1000 /* width */, mSecondaryDisplay.mBaseDisplayWidth);
         assertEquals(2000 /* height */, mSecondaryDisplay.mBaseDisplayHeight);
@@ -258,8 +233,9 @@
 
     @Test
     public void testSetForcedDensity() {
-        mTarget.setForcedDensity(mSecondaryDisplay, 600 /* density */, 0 /* userId */);
-        applySettingsToDisplayByNewInstance(mSecondaryDisplay);
+        mDisplayWindowSettings.setForcedDensity(mSecondaryDisplay, 600 /* density */,
+                0 /* userId */);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(600 /* density */, mSecondaryDisplay.mBaseDisplayDensity);
 
@@ -270,8 +246,9 @@
 
     @Test
     public void testSetForcedScalingMode() {
-        mTarget.setForcedScalingMode(mSecondaryDisplay, DisplayContent.FORCE_SCALING_MODE_DISABLED);
-        applySettingsToDisplayByNewInstance(mSecondaryDisplay);
+        mDisplayWindowSettings.setForcedScalingMode(mSecondaryDisplay,
+                DisplayContent.FORCE_SCALING_MODE_DISABLED);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertTrue(mSecondaryDisplay.mDisplayScalingDisabled);
 
@@ -282,7 +259,7 @@
 
     @Test
     public void testDefaultToFreeUserRotation() {
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
         assertEquals(WindowManagerPolicy.USER_ROTATION_FREE, rotation.getUserRotationMode());
@@ -291,7 +268,7 @@
 
     @Test
     public void testDefaultTo0DegRotation() {
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(Surface.ROTATION_0, mSecondaryDisplay.getDisplayRotation().getUserRotation());
     }
@@ -299,70 +276,68 @@
     @Test
     public void testPrivateDisplayDefaultToDestroyContent() {
         assertEquals(REMOVE_CONTENT_MODE_DESTROY,
-                mTarget.getRemoveContentModeLocked(mPrivateDisplay));
+                mDisplayWindowSettings.getRemoveContentModeLocked(mPrivateDisplay));
     }
 
     @Test
     public void testPublicDisplayDefaultToMoveToPrimary() {
         assertEquals(REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY,
-                mTarget.getRemoveContentModeLocked(mSecondaryDisplay));
+                mDisplayWindowSettings.getRemoveContentModeLocked(mSecondaryDisplay));
     }
 
     @Test
     public void testDefaultToNotShowWithInsecureKeyguard() {
-        assertFalse(mTarget.shouldShowWithInsecureKeyguardLocked(mPrivateDisplay));
-        assertFalse(mTarget.shouldShowWithInsecureKeyguardLocked(mSecondaryDisplay));
+        assertFalse(mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(mPrivateDisplay));
+        assertFalse(mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(mSecondaryDisplay));
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testPublicDisplayNotAllowSetShouldShowWithInsecureKeyguard() {
-        mTarget.setShouldShowWithInsecureKeyguardLocked(mSecondaryDisplay, true);
-
-        assertFalse(mTarget.shouldShowWithInsecureKeyguardLocked(mSecondaryDisplay));
+        mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(mSecondaryDisplay, true);
     }
 
     @Test
     public void testPrivateDisplayAllowSetShouldShowWithInsecureKeyguard() {
-        mTarget.setShouldShowWithInsecureKeyguardLocked(mPrivateDisplay, true);
+        mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(mPrivateDisplay, true);
 
-        assertTrue(mTarget.shouldShowWithInsecureKeyguardLocked(mPrivateDisplay));
+        assertTrue(mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(mPrivateDisplay));
     }
 
     @Test
     public void testPrimaryDisplayShouldShowSystemDecors() {
-        assertTrue(mTarget.shouldShowSystemDecorsLocked(mPrimaryDisplay));
+        assertTrue(mDisplayWindowSettings.shouldShowSystemDecorsLocked(mPrimaryDisplay));
 
-        mTarget.setShouldShowSystemDecorsLocked(mPrimaryDisplay, false);
+        mDisplayWindowSettings.setShouldShowSystemDecorsLocked(mPrimaryDisplay, false);
 
         // Default display should show system decors
-        assertTrue(mTarget.shouldShowSystemDecorsLocked(mPrimaryDisplay));
+        assertTrue(mDisplayWindowSettings.shouldShowSystemDecorsLocked(mPrimaryDisplay));
     }
 
     @Test
     public void testSecondaryDisplayDefaultToNotShowSystemDecors() {
-        assertFalse(mTarget.shouldShowSystemDecorsLocked(mSecondaryDisplay));
+        assertFalse(mDisplayWindowSettings.shouldShowSystemDecorsLocked(mSecondaryDisplay));
     }
 
     @Test
     public void testPrimaryDisplayShouldShowIme() {
-        assertTrue(mTarget.shouldShowImeLocked(mPrimaryDisplay));
+        assertTrue(mDisplayWindowSettings.shouldShowImeLocked(mPrimaryDisplay));
 
-        mTarget.setShouldShowImeLocked(mPrimaryDisplay, false);
+        mDisplayWindowSettings.setShouldShowImeLocked(mPrimaryDisplay, false);
 
-        assertTrue(mTarget.shouldShowImeLocked(mPrimaryDisplay));
+        assertTrue(mDisplayWindowSettings.shouldShowImeLocked(mPrimaryDisplay));
     }
 
     @Test
     public void testSecondaryDisplayDefaultToNotShowIme() {
-        assertFalse(mTarget.shouldShowImeLocked(mSecondaryDisplay));
+        assertFalse(mDisplayWindowSettings.shouldShowImeLocked(mSecondaryDisplay));
     }
 
     @Test
-    public void testPersistUserRotationModeInSameInstance() {
-        mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
-                Surface.ROTATION_90);
+    public void testSetUserRotationMode() {
+        mDisplayWindowSettings.setUserRotation(mSecondaryDisplay,
+                WindowManagerPolicy.USER_ROTATION_LOCKED, Surface.ROTATION_90);
 
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
         assertEquals(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation.getUserRotationMode());
@@ -370,48 +345,25 @@
     }
 
     @Test
-    public void testPersistUserRotationInSameInstance() {
-        mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
-                Surface.ROTATION_90);
+    public void testSetUserRotation() {
+        mDisplayWindowSettings.setUserRotation(mSecondaryDisplay,
+                WindowManagerPolicy.USER_ROTATION_LOCKED, Surface.ROTATION_90);
 
-        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
 
         assertEquals(Surface.ROTATION_90, mSecondaryDisplay.getDisplayRotation().getUserRotation());
     }
 
     @Test
-    public void testPersistUserRotationModeAcrossInstances() {
-        mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
-                Surface.ROTATION_270);
-
-        applySettingsToDisplayByNewInstance(mSecondaryDisplay);
-
-        final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
-        assertEquals(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation.getUserRotationMode());
-        assertTrue(rotation.isRotationFrozen());
-    }
-
-    @Test
-    public void testPersistUserRotationAcrossInstances() {
-        mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
-                Surface.ROTATION_270);
-
-        applySettingsToDisplayByNewInstance(mSecondaryDisplay);
-
-        assertEquals(Surface.ROTATION_270,
-                mSecondaryDisplay.getDisplayRotation().getUserRotation());
-    }
-
-    @Test
     public void testFixedToUserRotationDefault() {
-        mTarget.setUserRotation(mPrimaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
-                Surface.ROTATION_0);
+        mDisplayWindowSettings.setUserRotation(mPrimaryDisplay,
+                WindowManagerPolicy.USER_ROTATION_LOCKED, Surface.ROTATION_0);
 
         final DisplayRotation displayRotation = mock(DisplayRotation.class);
         spyOn(mPrimaryDisplay);
         doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation();
 
-        mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
 
         verify(displayRotation).restoreSettings(anyInt(), anyInt(),
                 eq(FIXED_TO_USER_ROTATION_DEFAULT));
@@ -419,13 +371,14 @@
 
     @Test
     public void testSetFixedToUserRotationDisabled() {
-        mTarget.setFixedToUserRotation(mPrimaryDisplay, FIXED_TO_USER_ROTATION_DISABLED);
+        mDisplayWindowSettings.setFixedToUserRotation(mPrimaryDisplay,
+                FIXED_TO_USER_ROTATION_DISABLED);
 
         final DisplayRotation displayRotation = mock(DisplayRotation.class);
         spyOn(mPrimaryDisplay);
         doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation();
 
-        applySettingsToDisplayByNewInstance(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
 
         verify(displayRotation).restoreSettings(anyInt(), anyInt(),
                 eq(FIXED_TO_USER_ROTATION_DISABLED));
@@ -433,120 +386,20 @@
 
     @Test
     public void testSetFixedToUserRotationEnabled() {
-        mTarget.setFixedToUserRotation(mPrimaryDisplay, FIXED_TO_USER_ROTATION_ENABLED);
+        mDisplayWindowSettings.setFixedToUserRotation(mPrimaryDisplay,
+                FIXED_TO_USER_ROTATION_ENABLED);
 
         final DisplayRotation displayRotation = mock(DisplayRotation.class);
         spyOn(mPrimaryDisplay);
         doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation();
 
-        applySettingsToDisplayByNewInstance(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
 
         verify(displayRotation).restoreSettings(anyInt(), anyInt(),
                 eq(FIXED_TO_USER_ROTATION_ENABLED));
     }
 
     @Test
-    public void testReadingDisplaySettingsFromStorage() {
-        final String displayIdentifier = mSecondaryDisplay.getDisplayInfo().uniqueId;
-        prepareDisplaySettings(displayIdentifier);
-
-        readAndAssertDisplaySettings(mPrimaryDisplay);
-    }
-
-    @Test
-    public void testReadingDisplaySettingsFromStorage_LegacyDisplayId() {
-        final String displayIdentifier = mPrimaryDisplay.getDisplayInfo().name;
-        prepareDisplaySettings(displayIdentifier);
-
-        readAndAssertDisplaySettings(mPrimaryDisplay);
-    }
-
-    @Test
-    public void testReadingDisplaySettingsFromStorage_LegacyDisplayId_UpdateAfterAccess()
-            throws Exception {
-        // Store display settings with legacy display identifier.
-        final String displayIdentifier = mPrimaryDisplay.getDisplayInfo().name;
-        prepareDisplaySettings(displayIdentifier);
-
-        // Update settings with new value, should trigger write to injector.
-        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
-        settings.setRemoveContentModeLocked(mPrimaryDisplay, REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY);
-        assertEquals("Settings value must be updated", REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY,
-                settings.getRemoveContentModeLocked(mPrimaryDisplay));
-        assertTrue(mStorage.wasWriteSuccessful());
-
-        // Verify that display identifier was updated.
-        final String newDisplayIdentifier = getStoredDisplayAttributeValue("name");
-        assertEquals("Display identifier must be updated to use uniqueId",
-                mPrimaryDisplay.getDisplayInfo().uniqueId, newDisplayIdentifier);
-    }
-
-    @Test
-    public void testReadingDisplaySettingsFromStorage_UsePortAsId() {
-        final DisplayAddress.Physical displayAddress =
-                DisplayAddress.fromPortAndModel(DISPLAY_PORT, DISPLAY_MODEL);
-        mPrimaryDisplay.getDisplayInfo().address = displayAddress;
-
-        final String displayIdentifier = "port:" + DISPLAY_PORT;
-        prepareDisplaySettings(displayIdentifier, true /* usePortAsId */);
-
-        readAndAssertDisplaySettings(mPrimaryDisplay);
-    }
-
-    @Test
-    public void testReadingDisplaySettingsFromStorage_UsePortAsId_IncorrectAddress() {
-        final String displayIdentifier = mPrimaryDisplay.getDisplayInfo().uniqueId;
-        prepareDisplaySettings(displayIdentifier, true /* usePortAsId */);
-
-        mPrimaryDisplay.getDisplayInfo().address = DisplayAddress.fromPhysicalDisplayId(123456);
-
-        // Verify that the entry is not matched and default settings are returned instead.
-        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm);
-        assertNotEquals("Default setting must be returned for new entry",
-                WINDOWING_MODE_PINNED, settings.getWindowingModeLocked(mPrimaryDisplay));
-    }
-
-    @Test
-    public void testWritingDisplaySettingsToStorage() throws Exception {
-        // Write some settings to storage.
-        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
-        settings.setShouldShowSystemDecorsLocked(mSecondaryDisplay, true);
-        settings.setShouldShowImeLocked(mSecondaryDisplay, true);
-        assertTrue(mStorage.wasWriteSuccessful());
-
-        // Verify that settings were stored correctly.
-        assertEquals("Attribute value must be stored", mSecondaryDisplay.getDisplayInfo().uniqueId,
-                getStoredDisplayAttributeValue("name"));
-        assertEquals("Attribute value must be stored", "true",
-                getStoredDisplayAttributeValue("shouldShowSystemDecors"));
-        assertEquals("Attribute value must be stored", "true",
-                getStoredDisplayAttributeValue("shouldShowIme"));
-    }
-
-    @Test
-    public void testWritingDisplaySettingsToStorage_UsePortAsId() throws Exception {
-        // Store config to use port as identifier.
-        final DisplayAddress.Physical displayAddress =
-                DisplayAddress.fromPortAndModel(DISPLAY_PORT, DISPLAY_MODEL);
-        mSecondaryDisplay.getDisplayInfo().address = displayAddress;
-        prepareDisplaySettings(null /* displayIdentifier */, true /* usePortAsId */);
-
-        // Write some settings.
-        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
-        settings.setShouldShowSystemDecorsLocked(mSecondaryDisplay, true);
-        settings.setShouldShowImeLocked(mSecondaryDisplay, true);
-        assertTrue(mStorage.wasWriteSuccessful());
-
-        // Verify that settings were stored correctly.
-        assertEquals("Attribute value must be stored", "port:" + DISPLAY_PORT,
-                getStoredDisplayAttributeValue("name"));
-        assertEquals("Attribute value must be stored", "true",
-                getStoredDisplayAttributeValue("shouldShowSystemDecors"));
-        assertEquals("Attribute value must be stored", "true",
-                getStoredDisplayAttributeValue("shouldShowIme"));
-    }
-
-    @Test
     public void testShouldShowImeWithinForceDesktopMode() {
         try {
             // Presume display enabled force desktop mode from developer options.
@@ -567,14 +420,13 @@
     public void testDisplayWindowSettingsAppliedOnDisplayReady() {
         // Set forced densities for two displays in DisplayWindowSettings
         final DisplayContent dc = createMockSimulatedDisplay();
-        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
-        settings.setForcedDensity(mPrimaryDisplay, 123, 0 /* userId */);
-        settings.setForcedDensity(dc, 456, 0 /* userId */);
+        mDisplayWindowSettings.setForcedDensity(mPrimaryDisplay, 123, 0 /* userId */);
+        mDisplayWindowSettings.setForcedDensity(dc, 456, 0 /* userId */);
 
         // Apply settings to displays - the settings will be stored, but config will not be
         // recalculated immediately.
-        settings.applySettingsToDisplayLocked(mPrimaryDisplay);
-        settings.applySettingsToDisplayLocked(dc);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
+        mDisplayWindowSettings.applySettingsToDisplayLocked(dc);
         assertFalse(mPrimaryDisplay.mWaitingForConfig);
         assertFalse(dc.mWaitingForConfig);
 
@@ -589,173 +441,34 @@
         assertEquals(456, config.densityDpi);
     }
 
-    /**
-     * Prepares display settings and stores in {@link #mStorage}. Uses provided display identifier
-     * and stores windowingMode=WINDOWING_MODE_PINNED.
-     */
-    private void prepareDisplaySettings(String displayIdentifier) {
-        prepareDisplaySettings(displayIdentifier, false /* usePortAsId */);
-    }
+    public final class TestSettingsProvider implements DisplayWindowSettings.SettingsProvider {
+        Map<DisplayInfo, SettingsEntry> mOverrideSettingsCache = new HashMap<>();
 
-    private void prepareDisplaySettings(String displayIdentifier, boolean usePortAsId) {
-        String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
-                + "<display-settings>\n";
-        if (usePortAsId) {
-            contents += "  <config identifier=\"1\"/>\n";
-        }
-        if (displayIdentifier != null) {
-            contents += "  <display\n"
-                    + "    name=\"" + displayIdentifier + "\"\n"
-                    + "    windowingMode=\"" + WINDOWING_MODE_PINNED + "\"/>\n";
-        }
-        contents += "</display-settings>\n";
-
-        final InputStream is = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
-        mStorage.setReadStream(is);
-    }
-
-    private void readAndAssertDisplaySettings(DisplayContent displayContent) {
-        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
-        assertEquals("Stored setting must be read",
-                WINDOWING_MODE_PINNED, settings.getWindowingModeLocked(displayContent));
-        assertEquals("Not stored setting must be set to default value",
-                REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY,
-                settings.getRemoveContentModeLocked(displayContent));
-    }
-
-    private String getStoredDisplayAttributeValue(String attr) throws Exception {
-        try (InputStream stream = mStorage.openRead()) {
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(stream, StandardCharsets.UTF_8.name());
-            int type;
-            while ((type = parser.next()) != XmlPullParser.START_TAG
-                    && type != XmlPullParser.END_DOCUMENT) {
-                // Do nothing.
-            }
-
-            if (type != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("no start tag found");
-            }
-
-            int outerDepth = parser.getDepth();
-            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
-                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                    continue;
-                }
-
-                String tagName = parser.getName();
-                if (tagName.equals("display")) {
-                    return parser.getAttributeValue(null, attr);
-                }
-            }
-        } finally {
-            mStorage.closeRead();
-        }
-        return null;
-    }
-
-    /**
-     * This method helps to ensure read and write persistent settings successfully because the
-     * constructor of {@link DisplayWindowSettings} should read the persistent file from the given
-     * path that also means the previous state must be written correctly.
-     */
-    private void applySettingsToDisplayByNewInstance(DisplayContent display) {
-        // Assert that prior write completed successfully.
-        assertTrue(mStorage.wasWriteSuccessful());
-
-        // Read and apply settings.
-        new DisplayWindowSettings(mWm, mStorage).applySettingsToDisplayLocked(display);
-    }
-
-    private static boolean deleteRecursively(File file) {
-        boolean fullyDeleted = true;
-        if (file.isFile()) {
-            return file.delete();
-        } else if (file.isDirectory()) {
-            final File[] files = file.listFiles();
-            for (File child : files) {
-                fullyDeleted &= deleteRecursively(child);
-            }
-            fullyDeleted &= file.delete();
-        }
-        return fullyDeleted;
-    }
-
-    /** In-memory storage implementation. */
-    public class TestStorage implements DisplayWindowSettings.SettingPersister {
-        private InputStream mReadStream;
-        private ByteArrayOutputStream mWriteStream;
-
-        private boolean mWasSuccessful;
-
-        /**
-         * Returns input stream for reading. By default tries forward the output stream if previous
-         * write was successful.
-         * @see #closeRead()
-         */
         @Override
-        public InputStream openRead() throws FileNotFoundException {
-            if (mReadStream == null && mWasSuccessful) {
-                mReadStream = new ByteArrayInputStream(mWriteStream.toByteArray());
-            }
-            if (mReadStream == null) {
-                throw new FileNotFoundException();
-            }
-            if (mReadStream.markSupported()) {
-                mReadStream.mark(Integer.MAX_VALUE);
-            }
-            return mReadStream;
-        }
-
-        /** Must be called after each {@link #openRead} to reset the position in the stream. */
-        void closeRead() throws IOException {
-            if (mReadStream == null) {
-                throw new FileNotFoundException();
-            }
-            if (mReadStream.markSupported()) {
-                mReadStream.reset();
-            }
-            mReadStream = null;
-        }
-
-        /**
-         * Creates new or resets existing output stream for write. Automatically closes previous
-         * read stream, since following reads should happen based on this new write.
-         */
-        @Override
-        public OutputStream startWrite() throws IOException {
-            if (mWriteStream == null) {
-                mWriteStream = new ByteArrayOutputStream();
-            } else {
-                mWriteStream.reset();
-            }
-            if (mReadStream != null) {
-                closeRead();
-            }
-            return mWriteStream;
+        public SettingsEntry getSettings(@NonNull DisplayInfo info) {
+            return getOverrideSettings(info);
         }
 
         @Override
-        public void finishWrite(OutputStream os, boolean success) {
-            mWasSuccessful = success;
-            try {
-                os.close();
-            } catch (IOException e) {
-                // This method can't throw IOException since the super implementation doesn't, so
-                // we just wrap it in a RuntimeException so we end up crashing the test all the
-                // same.
-                throw new RuntimeException(e);
+        public SettingsEntry getOverrideSettings(@NonNull DisplayInfo info) {
+            SettingsEntry result = new SettingsEntry();
+            SettingsEntry overrideSettings = mOverrideSettingsCache.get(info);
+            if (overrideSettings != null) {
+                result.setTo(overrideSettings);
             }
+            return result;
         }
 
-        /** Override the read stream of the injector. By default it uses current write stream. */
-        private void setReadStream(InputStream is) {
-            mReadStream = is;
-        }
+        @Override
+        public void updateOverrideSettings(@NonNull DisplayInfo info,
+                @NonNull SettingsEntry settings) {
+            SettingsEntry overrideSettings = mOverrideSettingsCache.get(info);
+            if (overrideSettings == null) {
+                overrideSettings = new SettingsEntry();
+                mOverrideSettingsCache.put(info, overrideSettings);
+            }
 
-        private boolean wasWriteSuccessful() {
-            return mWasSuccessful;
+            overrideSettings.setTo(settings);
         }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
index 823aef0..5641fe2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
@@ -83,6 +83,8 @@
 public class DragDropControllerTests extends WindowTestsBase {
     private static final int TIMEOUT_MS = 3000;
     private static final int TEST_UID = 12345;
+    private static final int TEST_PID = 67890;
+    private static final String TEST_PACKAGE = "com.test.package";
 
     private TestDragDropController mTarget;
     private WindowState mWindow;
@@ -118,7 +120,7 @@
      * Creates a window state which can be used as a drop target.
      */
     private WindowState createDropTargetWindow(String name, int ownerId) {
-        final ActivityRecord activity = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         final Task stack = createTaskStackOnDisplay(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent);
         final Task task = createTaskInStack(stack, ownerId);
@@ -243,21 +245,16 @@
         });
         try {
             session.validateAndResolveDragMimeTypeExtras(
-                    createClipDataForActivity(null, null), 0);
-            fail("Expected failure without pending intent and user");
-        } catch (IllegalArgumentException e) {
-            // Expected failure
-        }
-        try {
-            session.validateAndResolveDragMimeTypeExtras(
-                    createClipDataForActivity(mock(PendingIntent.class), null), 0);
+                    createClipDataForActivity(mock(PendingIntent.class), null), TEST_UID, TEST_PID,
+                    TEST_PACKAGE);
             fail("Expected failure without user");
         } catch (IllegalArgumentException e) {
             // Expected failure
         }
         try {
             session.validateAndResolveDragMimeTypeExtras(
-                    createClipDataForActivity(null, mock(UserHandle.class)), 0);
+                    createClipDataForActivity(null, mock(UserHandle.class)), TEST_UID, TEST_PID,
+                    TEST_PACKAGE);
             fail("Expected failure without pending intent");
         } catch (IllegalArgumentException e) {
             // Expected failure
@@ -286,15 +283,48 @@
             public void onAnimatorScaleChanged(float scale) {}
         });
         try {
-            final ClipData clipData = new ClipData(
-                    new ClipDescription("drag", new String[] { MIMETYPE_APPLICATION_SHORTCUT }),
-                    new ClipData.Item(new Intent()));
-
-            session.validateAndResolveDragMimeTypeExtras(clipData, TEST_UID);
+            session.validateAndResolveDragMimeTypeExtras(
+                    createClipDataForShortcut(null, "test_shortcut_id", mock(UserHandle.class)),
+                    TEST_UID, TEST_PID, TEST_PACKAGE);
+            fail("Expected failure without package name");
+        } catch (IllegalArgumentException e) {
+            // Expected failure
+        }
+        try {
+            session.validateAndResolveDragMimeTypeExtras(
+                    createClipDataForShortcut("test_package", null, mock(UserHandle.class)),
+                    TEST_UID, TEST_PID, TEST_PACKAGE);
             fail("Expected failure without shortcut id");
         } catch (IllegalArgumentException e) {
             // Expected failure
         }
+        try {
+            session.validateAndResolveDragMimeTypeExtras(
+                    createClipDataForShortcut("test_package", "test_shortcut_id", null),
+                    TEST_UID, TEST_PID, TEST_PACKAGE);
+            fail("Expected failure without package name");
+        } catch (IllegalArgumentException e) {
+            // Expected failure
+        }
+    }
+
+    private ClipData createClipDataForShortcut(String packageName, String shortcutId,
+            UserHandle user) {
+        final Intent data = new Intent();
+        if (packageName != null) {
+            data.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
+        }
+        if (shortcutId != null) {
+            data.putExtra(Intent.EXTRA_SHORTCUT_ID, shortcutId);
+        }
+        if (user != null) {
+            data.putExtra(Intent.EXTRA_USER, user);
+        }
+        final ClipData clipData = new ClipData(
+                new ClipDescription("drag", new String[] {
+                        MIMETYPE_APPLICATION_SHORTCUT}),
+                new ClipData.Item(data));
+        return clipData;
     }
 
     @Test
@@ -308,7 +338,8 @@
                     new ClipDescription("drag", new String[] { MIMETYPE_APPLICATION_TASK }),
                     new ClipData.Item(new Intent()));
 
-            session.validateAndResolveDragMimeTypeExtras(clipData, TEST_UID);
+            session.validateAndResolveDragMimeTypeExtras(clipData, TEST_UID, TEST_PID,
+                    TEST_PACKAGE);
             fail("Expected failure without task id");
         } catch (IllegalArgumentException e) {
             // Expected failure
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index a1606d3..02d9c42 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -82,7 +82,7 @@
         addWindow(TYPE_STATUS_BAR, "statusBar");
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
-        final WindowState win = createWindowOnStack(null, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
+        final WindowState win = createWindow(null, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
                 ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
         final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);
 
@@ -95,7 +95,7 @@
         addWindow(TYPE_STATUS_BAR, "statusBar");
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
-        final WindowState win = createWindowOnStack(null, WINDOWING_MODE_FREEFORM,
+        final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM,
                 ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
         final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index 044f819..bf718a7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -50,6 +50,11 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_ALLOWLISTED;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_DONT_LOCK;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
+import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_PINNABLE;
 import static com.android.server.wm.LockTaskController.STATUS_BAR_MASK_LOCKED;
 import static com.android.server.wm.LockTaskController.STATUS_BAR_MASK_PINNED;
 
@@ -169,7 +174,7 @@
     @Test
     public void testStartLockTaskMode_once() throws Exception {
         // GIVEN a task record with allowlisted auth
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
 
         // WHEN calling setLockTaskMode for LOCKED mode without resuming
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
@@ -186,8 +191,8 @@
     @Test
     public void testStartLockTaskMode_twice() throws Exception {
         // GIVEN two task records with allowlisted auth
-        Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
-        Task tr2 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr1 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr2 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
 
         // WHEN calling setLockTaskMode for LOCKED mode on both tasks
         mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
@@ -206,7 +211,7 @@
     @Test
     public void testStartLockTaskMode_pinningRequest() {
         // GIVEN a task record that is not allowlisted, i.e. with pinned auth
-        Task tr = getTask(Task.LOCK_TASK_AUTH_PINNABLE);
+        Task tr = getTask(LOCK_TASK_AUTH_PINNABLE);
 
         // WHEN calling startLockTaskMode
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
@@ -218,7 +223,7 @@
     @Test
     public void testStartLockTaskMode_pinnedBySystem() throws Exception {
         // GIVEN a task record with pinned auth
-        Task tr = getTask(Task.LOCK_TASK_AUTH_PINNABLE);
+        Task tr = getTask(LOCK_TASK_AUTH_PINNABLE);
 
         // WHEN the system calls startLockTaskMode
         mLockTaskController.startLockTaskMode(tr, true, SYSTEM_UID);
@@ -237,41 +242,39 @@
     @Test
     public void testLockTaskViolation() {
         // GIVEN one task record with allowlisted auth that is in lock task mode
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // THEN it's not a lock task violation to try and launch this task without clearing
         assertFalse(mLockTaskController.isLockTaskModeViolation(tr, false));
 
         // THEN it's a lock task violation to launch another task that is not allowlisted
-        assertTrue(mLockTaskController.isLockTaskModeViolation(getTask(
-                Task.LOCK_TASK_AUTH_PINNABLE)));
+        assertTrue(mLockTaskController.isLockTaskModeViolation(getTask(LOCK_TASK_AUTH_PINNABLE)));
         // THEN it's a lock task violation to launch another task that is disallowed from lock task
-        assertTrue(mLockTaskController.isLockTaskModeViolation(getTask(
-                Task.LOCK_TASK_AUTH_DONT_LOCK)));
+        assertTrue(mLockTaskController.isLockTaskModeViolation(getTask(LOCK_TASK_AUTH_DONT_LOCK)));
 
         // THEN it's no a lock task violation to launch another task that is allowlisted
         assertFalse(mLockTaskController.isLockTaskModeViolation(getTask(
-                Task.LOCK_TASK_AUTH_ALLOWLISTED)));
+                LOCK_TASK_AUTH_ALLOWLISTED)));
         assertFalse(mLockTaskController.isLockTaskModeViolation(getTask(
-                Task.LOCK_TASK_AUTH_LAUNCHABLE)));
+                LOCK_TASK_AUTH_LAUNCHABLE)));
         // THEN it's not a lock task violation to launch another task that is priv launchable
         assertFalse(mLockTaskController.isLockTaskModeViolation(getTask(
-                Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV)));
+                LOCK_TASK_AUTH_LAUNCHABLE_PRIV)));
     }
 
     @Test
     public void testLockTaskViolation_emergencyCall() {
         // GIVEN one task record with allowlisted auth that is in lock task mode
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // GIVEN tasks necessary for emergency calling
         Task keypad = getTask(new Intent().setComponent(EMERGENCY_DIALER_COMPONENT),
-                Task.LOCK_TASK_AUTH_PINNABLE);
+                LOCK_TASK_AUTH_PINNABLE);
         Task callAction = getTask(new Intent(Intent.ACTION_CALL_EMERGENCY),
-                Task.LOCK_TASK_AUTH_PINNABLE);
-        Task dialer = getTask("com.example.dialer", Task.LOCK_TASK_AUTH_PINNABLE);
+                LOCK_TASK_AUTH_PINNABLE);
+        Task dialer = getTask("com.example.dialer", LOCK_TASK_AUTH_PINNABLE);
         when(mTelecomManager.getSystemDialerPackage())
                 .thenReturn(dialer.intent.getComponent().getPackageName());
 
@@ -295,7 +298,7 @@
     @Test
     public void testStopLockTaskMode() throws Exception {
         // GIVEN one task record with allowlisted auth that is in lock task mode
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // WHEN the same caller calls stopLockTaskMode
@@ -312,7 +315,7 @@
     @Test(expected = SecurityException.class)
     public void testStopLockTaskMode_differentCaller() {
         // GIVEN one task record with allowlisted auth that is in lock task mode
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // WHEN a different caller calls stopLockTaskMode
@@ -324,7 +327,7 @@
     @Test
     public void testStopLockTaskMode_systemCaller() {
         // GIVEN one task record with allowlisted auth that is in lock task mode
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // WHEN system calls stopLockTaskMode
@@ -337,8 +340,8 @@
     @Test
     public void testStopLockTaskMode_twoTasks() throws Exception {
         // GIVEN two task records with allowlisted auth that is in lock task mode
-        Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
-        Task tr2 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr1 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr2 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
         mLockTaskController.startLockTaskMode(tr2, false, TEST_UID);
 
@@ -358,8 +361,8 @@
     @Test
     public void testStopLockTaskMode_rootTask() throws Exception {
         // GIVEN two task records with allowlisted auth that is in lock task mode
-        Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
-        Task tr2 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr1 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr2 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
         mLockTaskController.startLockTaskMode(tr2, false, TEST_UID);
 
@@ -379,7 +382,7 @@
     @Test
     public void testStopLockTaskMode_pinned() throws Exception {
         // GIVEN one task records that is in pinned mode
-        Task tr = getTask(Task.LOCK_TASK_AUTH_PINNABLE);
+        Task tr = getTask(LOCK_TASK_AUTH_PINNABLE);
         mLockTaskController.startLockTaskMode(tr, true, SYSTEM_UID);
         // GIVEN that the keyguard is required to show after unlocking
         Settings.Secure.putInt(mContext.getContentResolver(),
@@ -406,8 +409,8 @@
     @Test
     public void testClearLockedTasks() throws Exception {
         // GIVEN two task records with allowlisted auth that is in lock task mode
-        Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
-        Task tr2 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr1 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr2 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
         mLockTaskController.startLockTaskMode(tr2, false, TEST_UID);
 
@@ -434,7 +437,7 @@
                 .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
 
         // AND there is a task record
-        Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr1 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr1, true, TEST_UID);
 
         // WHEN calling clearLockedTasks on the root task
@@ -454,7 +457,7 @@
                 .thenReturn(true);
 
         // AND there is a task record
-        Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr1 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr1, true, TEST_UID);
 
         // WHEN calling clearLockedTasks on the root task
@@ -471,7 +474,7 @@
                 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, 1, mContext.getUserId());
 
         // AND there is a task record
-        Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr1 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr1, true, TEST_UID);
 
         // WHEN calling clearLockedTasks on the root task
@@ -488,7 +491,7 @@
                 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, 0, mContext.getUserId());
 
         // AND there is a task record
-        Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr1 = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr1, true, TEST_UID);
 
         // WHEN calling clearLockedTasks on the root task
@@ -574,7 +577,7 @@
     @Test
     public void testUpdateLockTaskFeatures() throws Exception {
         // GIVEN a locked task
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // THEN lock task mode should be started with default status bar masks
@@ -616,7 +619,7 @@
     @Test
     public void testUpdateLockTaskFeatures_differentUser() throws Exception {
         // GIVEN a locked task
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // THEN lock task mode should be started with default status bar masks
@@ -638,7 +641,7 @@
     @Test
     public void testUpdateLockTaskFeatures_keyguard() {
         // GIVEN a locked task
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // THEN keyguard should be disabled
@@ -704,7 +707,7 @@
                 TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT));
 
         // Start lock task mode
-        Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED);
+        Task tr = getTask(LOCK_TASK_AUTH_ALLOWLISTED);
         mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
 
         // WHEN LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK is not enabled
@@ -758,14 +761,13 @@
      * @param isAppAware {@code true} if the app has marked if allowlisted in its manifest
      */
     private Task getTaskForUpdate(String pkg, boolean isAppAware) {
-        final int authIfAllowlisted = isAppAware
-                ? Task.LOCK_TASK_AUTH_LAUNCHABLE
-                : Task.LOCK_TASK_AUTH_ALLOWLISTED;
+        final int authIfAllowlisted =
+                isAppAware ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_ALLOWLISTED;
         Task tr = getTask(pkg, authIfAllowlisted);
         doAnswer((invocation) -> {
             boolean isAllowlisted =
                     mLockTaskController.isPackageAllowlisted(TEST_USER_ID, pkg);
-            tr.mLockTaskAuth = isAllowlisted ? authIfAllowlisted : Task.LOCK_TASK_AUTH_PINNABLE;
+            tr.mLockTaskAuth = isAllowlisted ? authIfAllowlisted : LOCK_TASK_AUTH_PINNABLE;
             return null;
         }).when(tr).setLockTaskAuth();
         return tr;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index bea0d8e..d348389 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -474,6 +474,28 @@
     }
 
     @Test
+    public void testAppendOrganizedChildTaskInfo() {
+        final Task root = createTaskBuilder(".CreatedByOrganizerRoot").build();
+        root.mCreatedByOrganizer = true;
+        // Add organized and non-organized child.
+        final Task child1 = createTaskBuilder(".Task1").setParentTask(root).build();
+        final Task child2 = createTaskBuilder(".Task2").setParentTask(root).build();
+        doReturn(true).when(child1).isOrganized();
+        doReturn(false).when(child2).isOrganized();
+        mRecentTasks.add(root);
+
+        doNothing().when(mRecentTasks).loadUserRecentsLocked(anyInt());
+        doReturn(true).when(mRecentTasks).isUserRunning(anyInt(), anyInt());
+        final List<RecentTaskInfo> infos = mRecentTasks.getRecentTasks(MAX_VALUE, 0 /* flags */,
+                true /* getTasksAllowed */, TEST_USER_0_ID, 0 /* callingUid */).getList();
+
+        // Make sure only organized child will be appended.
+        final List<RecentTaskInfo> childrenTaskInfos = infos.get(0).childrenTaskInfos;
+        assertEquals(childrenTaskInfos.size(), 1);
+        assertEquals(childrenTaskInfos.get(0).taskId, child1.mTaskId);
+    }
+
+    @Test
     public void testAddTasksHomeClearUntrackedTasks_expectFinish() {
         // There may be multiple tasks with the same base intent by flags (FLAG_ACTIVITY_NEW_TASK |
         // FLAG_ACTIVITY_MULTIPLE_TASK). If the previous task is still active, it should be removed
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 8094c97..cc92ddd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -107,8 +105,7 @@
 
     @Test
     public void testRemovedBeforeStarted_expectCanceled() throws Exception {
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         AnimationAdapter adapter = mController.addAnimation(activity.getTask(),
                 false /* isRecentTaskInvisible */);
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_RECENTS,
@@ -127,8 +124,7 @@
 
     @Test
     public void testCancelAfterRemove_expectIgnored() {
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         AnimationAdapter adapter = mController.addAnimation(activity.getTask(),
                 false /* isRecentTaskInvisible */);
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_RECENTS,
@@ -149,10 +145,8 @@
     public void testIncludedApps_expectTargetAndVisible() {
         mWm.setRecentsAnimationController(mController);
         final ActivityRecord homeActivity = createHomeActivity();
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        final ActivityRecord hiddenActivity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
+        final ActivityRecord hiddenActivity = createActivityRecord(mDefaultDisplay);
         hiddenActivity.setVisible(false);
         mDefaultDisplay.getConfiguration().windowConfiguration.setRotation(
                 mDefaultDisplay.getRotation());
@@ -168,8 +162,7 @@
     public void testWallpaperIncluded_expectTarget() throws Exception {
         mWm.setRecentsAnimationController(mController);
         final ActivityRecord homeActivity = createHomeActivity();
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
         activity.addWindow(win1);
         final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
@@ -191,8 +184,7 @@
     public void testWallpaperAnimatorCanceled_expectAnimationKeepsRunning() throws Exception {
         mWm.setRecentsAnimationController(mController);
         final ActivityRecord homeActivity = createHomeActivity();
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
         activity.addWindow(win1);
         final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
@@ -218,8 +210,7 @@
         final ActivityRecord homeActivity = createHomeActivity();
         final WindowState hwin1 = createWindow(null, TYPE_BASE_APPLICATION, homeActivity, "hwin1");
         homeActivity.addWindow(hwin1);
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
         activity.addWindow(win1);
         final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
@@ -246,8 +237,7 @@
     @Test
     public void testDeferCancelAnimation() throws Exception {
         mWm.setRecentsAnimationController(mController);
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
         activity.addWindow(win1);
         assertEquals(activity.getTask().getTopVisibleActivity(), activity);
@@ -269,8 +259,7 @@
     @Test
     public void testDeferCancelAnimationWithScreenShot() throws Exception {
         mWm.setRecentsAnimationController(mController);
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
         activity.addWindow(win1);
         assertEquals(activity.getTask().getTopVisibleActivity(), activity);
@@ -301,8 +290,7 @@
     @Test
     public void testShouldAnimateWhenNoCancelWithDeferredScreenshot() {
         mWm.setRecentsAnimationController(mController);
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
         activity.addWindow(win1);
         assertEquals(activity.getTask().getTopVisibleActivity(), activity);
@@ -325,8 +313,7 @@
         final ActivityRecord homeActivity = createHomeActivity();
         homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 
-        final ActivityRecord landActivity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord landActivity = createActivityRecord(mDefaultDisplay);
         landActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
         final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, landActivity, "win1");
         landActivity.addWindow(win1);
@@ -365,8 +352,7 @@
     private ActivityRecord prepareFixedRotationLaunchingAppWithRecentsAnim() {
         final ActivityRecord homeActivity = createHomeActivity();
         homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         // Add a window so it can be animated by the recents.
         final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
         activity.addWindow(win);
@@ -441,8 +427,7 @@
         homeWindow.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
 
         // Landscape application
-        final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
         final WindowState applicationWindow = createWindow(null, TYPE_BASE_APPLICATION, activity,
                 "applicationWindow");
         activity.addWindow(applicationWindow);
@@ -513,7 +498,7 @@
 
     private ActivityRecord createHomeActivity() {
         final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
-                .setStack(mRootHomeTask)
+                .setParentTask(mRootHomeTask)
                 .setCreateTask(true)
                 .build();
         // Avoid {@link RecentsAnimationController.TaskAnimationAdapter#createRemoteAnimationTarget}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index c10d4fa..137cedd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -93,8 +93,7 @@
                 ACTIVITY_TYPE_RECENTS, true /* onTop */);
         ActivityRecord recentActivity = new ActivityBuilder(mAtm)
                 .setComponent(mRecentsComponent)
-                .setCreateTask(true)
-                .setStack(recentsStack)
+                .setTask(recentsStack)
                 .build();
         ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
         topActivity.getRootTask().moveToFront("testRecentsActivityVisiblility");
@@ -124,7 +123,7 @@
         ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
         if (topRunningHomeActivity == null) {
             topRunningHomeActivity = new ActivityBuilder(mAtm)
-                    .setStack(homeStack)
+                    .setParentTask(homeStack)
                     .setCreateTask(true)
                     .build();
         }
@@ -182,7 +181,7 @@
         Task recentsStack = defaultTaskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_RECENTS, true /* onTop */);
         ActivityRecord recentActivity = new ActivityBuilder(mAtm).setComponent(
-                mRecentsComponent).setCreateTask(true).setStack(recentsStack).build();
+                mRecentsComponent).setCreateTask(true).setParentTask(recentsStack).build();
         WindowProcessController app = recentActivity.app;
         recentActivity.app = null;
 
@@ -214,7 +213,7 @@
         if (targetActivity == null) {
             targetActivity = new ActivityBuilder(mAtm)
                     .setCreateTask(true)
-                    .setStack(homeStack)
+                    .setParentTask(homeStack)
                     .build();
         }
 
@@ -222,7 +221,7 @@
         ActivityRecord anotherHomeActivity = new ActivityBuilder(mAtm)
                 .setComponent(new ComponentName(mContext.getPackageName(), "Home2"))
                 .setCreateTask(true)
-                .setStack(homeStack)
+                .setParentTask(homeStack)
                 .build();
         // Start an activity on top so the recents activity can be started.
         new ActivityBuilder(mAtm)
@@ -255,21 +254,21 @@
         new ActivityBuilder(mAtm)
                 .setComponent(new ComponentName(mContext.getPackageName(), "App1"))
                 .setCreateTask(true)
-                .setStack(fullscreenStack)
+                .setParentTask(fullscreenStack)
                 .build();
         Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_RECENTS, true /* onTop */);
         new ActivityBuilder(mAtm)
                 .setComponent(mRecentsComponent)
                 .setCreateTask(true)
-                .setStack(recentsStack)
+                .setParentTask(recentsStack)
                 .build();
         Task fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, true /* onTop */);
         new ActivityBuilder(mAtm)
                 .setComponent(new ComponentName(mContext.getPackageName(), "App2"))
                 .setCreateTask(true)
-                .setStack(fullscreenStack2)
+                .setParentTask(fullscreenStack2)
                 .build();
 
         // Start the recents animation
@@ -296,21 +295,21 @@
         new ActivityBuilder(mAtm)
                 .setComponent(new ComponentName(mContext.getPackageName(), "App1"))
                 .setCreateTask(true)
-                .setStack(fullscreenStack)
+                .setParentTask(fullscreenStack)
                 .build();
         Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_RECENTS, true /* onTop */);
         new ActivityBuilder(mAtm)
                 .setComponent(mRecentsComponent)
                 .setCreateTask(true)
-                .setStack(recentsStack)
+                .setParentTask(recentsStack)
                 .build();
         Task fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, true /* onTop */);
         new ActivityBuilder(mAtm)
                 .setComponent(new ComponentName(mContext.getPackageName(), "App2"))
                 .setCreateTask(true)
-                .setStack(fullscreenStack2)
+                .setParentTask(fullscreenStack2)
                 .build();
 
         // Start the recents animation
@@ -331,7 +330,7 @@
         Task homeStack = taskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED,
                 ACTIVITY_TYPE_HOME);
         ActivityRecord otherUserHomeActivity = new ActivityBuilder(mAtm)
-                .setStack(homeStack)
+                .setParentTask(homeStack)
                 .setCreateTask(true)
                 .setComponent(new ComponentName(mContext.getPackageName(), "Home2"))
                 .build();
@@ -342,7 +341,7 @@
         new ActivityBuilder(mAtm)
                 .setComponent(new ComponentName(mContext.getPackageName(), "App1"))
                 .setCreateTask(true)
-                .setStack(fullscreenStack)
+                .setParentTask(fullscreenStack)
                 .build();
 
         doReturn(TEST_USER_ID).when(mAtm).getCurrentUserId();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 901ed36..4b8bbc1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -38,7 +38,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
-import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
+import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE;
 import static com.android.server.wm.Task.ActivityState.STOPPED;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
 
@@ -107,7 +107,7 @@
     public void testRestoringInvalidTask() {
         mRootWindowContainer.getDefaultDisplay().removeAllTasks();
         Task task = mRootWindowContainer.anyTaskForId(0 /*taskId*/,
-                MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, null, false /* onTop */);
+                MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, null, false /* onTop */);
         assertNull(task);
     }
 
@@ -117,12 +117,10 @@
      */
     @Test
     public void testReplacingTaskInPinnedStack() {
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(mFullscreenStack).build();
-        final Task task = firstActivity.getTask();
-
-        final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(task)
-                .setStack(mFullscreenStack).build();
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(mFullscreenStack).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(mFullscreenStack).build();
 
         mFullscreenStack.moveToFront("testReplacingTaskInPinnedStack");
 
@@ -152,12 +150,12 @@
 
     @Test
     public void testMovingBottomMostStackActivityToPinnedStack() {
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(mFullscreenStack).build();
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(mFullscreenStack).build();
         final Task task = firstActivity.getTask();
 
-        final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setTask(task)
-                .setStack(mFullscreenStack).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(mFullscreenStack).build();
 
         mFullscreenStack.moveTaskToBack(task);
 
@@ -287,8 +285,7 @@
         final int originalStackCount = defaultTaskDisplayArea.getStackCount();
         final Task stack = defaultTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(stack).build();
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(stack).build();
 
         assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getStackCount());
 
@@ -311,17 +308,15 @@
         final int originalStackCount = defaultTaskDisplayArea.getStackCount();
         final Task stack = defaultTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(stack).build();
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(stack).build();
         assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getStackCount());
 
         final DisplayContent dc = defaultTaskDisplayArea.getDisplayContent();
-        final TaskDisplayArea secondTaskDisplayArea = WindowTestsBase.createTaskDisplayArea(
+        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
                 dc, mRootWindowContainer.mWmService, "TestTaskDisplayArea", FEATURE_VENDOR_FIRST);
         final Task secondStack = secondTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        new ActivityBuilder(mAtm).setCreateTask(true).setStack(secondStack)
-                .setUseProcess(firstActivity.app).build();
+        new ActivityBuilder(mAtm).setTask(secondStack).setUseProcess(firstActivity.app).build();
         assertEquals(1, secondTaskDisplayArea.getStackCount());
 
         // Let's pretend that the app has crashed.
@@ -339,8 +334,7 @@
                 .getDefaultTaskDisplayArea();
         final Task stack = defaultTaskDisplayArea.createStack(
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(stack).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
 
         // Created stacks are focusable by default.
         assertTrue(stack.isTopActivityFocusable());
@@ -353,8 +347,8 @@
 
         final Task pinnedStack = defaultTaskDisplayArea.createStack(
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(pinnedStack).build();
+        final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
+                .setTask(pinnedStack).build();
 
         // We should not be focusable when in pinned mode
         assertFalse(pinnedStack.isTopActivityFocusable());
@@ -363,13 +357,9 @@
         // Add flag forcing focusability.
         pinnedActivity.info.flags |= FLAG_ALWAYS_FOCUSABLE;
 
-        // We should not be focusable when in pinned mode
+        // Task with FLAG_ALWAYS_FOCUSABLE should be focusable.
         assertTrue(pinnedStack.isTopActivityFocusable());
         assertTrue(pinnedActivity.isFocusable());
-
-        // Without the overridding activity, stack should not be focusable.
-        pinnedStack.removeChild(pinnedActivity.getTask(), "testFocusability");
-        assertFalse(pinnedStack.isTopActivityFocusable());
     }
 
     /**
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index cc8b2a1..62aa02f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -16,8 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -152,8 +150,7 @@
         DisplayContent displayContent = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
         TaskDisplayArea taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
         Task stack = taskDisplayArea.getStackAt(0);
-        ActivityRecord activity = createActivityRecord(displayContent,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        ActivityRecord activity = createActivityRecord(displayContent);
         stack.mPausingActivity = activity;
 
         activity.setState(PAUSING, "test PAUSING");
@@ -176,7 +173,7 @@
     public void testTaskLayerRank() {
         final Task rootTask = new TaskBuilder(mSupervisor).build();
         final Task task1 = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
-        new ActivityBuilder(mAtm).setStack(task1).build().mVisibleRequested = true;
+        new ActivityBuilder(mAtm).setTask(task1).build().mVisibleRequested = true;
         // RootWindowContainer#invalidateTaskLayers should post to update.
         waitHandlerIdle(mWm.mH);
 
@@ -185,7 +182,7 @@
         assertEquals(Task.LAYER_RANK_INVISIBLE, rootTask.mLayerRank);
 
         final Task task2 = new TaskBuilder(mSupervisor).build();
-        new ActivityBuilder(mAtm).setStack(task2).build().mVisibleRequested = true;
+        new ActivityBuilder(mAtm).setTask(task2).build().mVisibleRequested = true;
         waitHandlerIdle(mWm.mH);
 
         // Note that ensureActivitiesVisible is disabled in SystemServicesTestRule, so both the
@@ -208,8 +205,8 @@
         final WindowProcessController wpc = activity.app;
         final ActivityRecord[] activities = {
                 activity,
-                new ActivityBuilder(mWm.mAtmService).setStack(task).setUseProcess(wpc).build(),
-                new ActivityBuilder(mWm.mAtmService).setStack(task).setUseProcess(wpc).build()
+                new ActivityBuilder(mWm.mAtmService).setTask(task).setUseProcess(wpc).build(),
+                new ActivityBuilder(mWm.mAtmService).setTask(task).setUseProcess(wpc).build()
         };
         activities[0].detachFromProcess();
         activities[1].finishing = true;
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 d68dde5..ddc29f5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -41,6 +41,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doCallRealMethod;
 
 import android.app.ActivityManager;
@@ -702,7 +703,6 @@
         // size compat cache.
         verify(mTask).onDescendantOrientationChanged(any(), same(newActivity));
         verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
-        verify(newActivity).clearSizeCompatMode(false /* recomputeTask */);
 
         final Rect displayBounds = display.getBounds();
         final Rect taskBounds = mTask.getBounds();
@@ -744,7 +744,6 @@
         // size compat cache.
         verify(mTask).onDescendantOrientationChanged(any(), same(newActivity));
         verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
-        verify(newActivity).clearSizeCompatMode(false /* recomputeTask */);
 
         final Rect displayBounds = display.getBounds();
         final Rect taskBounds = mTask.getBounds();
@@ -761,6 +760,40 @@
         assertEquals(taskBounds, newActivityBounds);
     }
 
+    @Test
+    public void testDisplayIgnoreOrientationRequest_pausedAppNotLostSizeCompat() {
+        // Set up a display in landscape and ignoring orientation request.
+        setUpDisplaySizeWithApp(2800, 1400);
+        final DisplayContent display = mActivity.mDisplayContent;
+        display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        // Portrait fixed app.
+        prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+        clearInvocations(mActivity);
+
+        assertTrue(mTask.isTaskLetterboxed());
+        assertFalse(mActivity.inSizeCompatMode());
+        assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity);
+
+        // Rotate display to portrait.
+        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+
+        // App should be in size compat.
+        assertFalse(mTask.isTaskLetterboxed());
+        assertScaled();
+        assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity);
+
+        final Rect activityBounds = new Rect(mActivity.getBounds());
+        mStack.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */);
+
+        // App still in size compat, and the bounds don't change.
+        verify(mActivity, never()).clearSizeCompatMode();
+        assertFalse(mTask.isTaskLetterboxed());
+        assertScaled();
+        assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity);
+        assertEquals(activityBounds, mActivity.getBounds());
+    }
+
     private static WindowState addWindowToActivity(ActivityRecord activity) {
         final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
         params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -768,7 +801,7 @@
         params.setFitInsetsTypes(0);
         final TestWindowState w = new TestWindowState(
                 activity.mWmService, mock(Session.class), new TestIWindow(), params, activity);
-        WindowTestsBase.makeWindowVisible(w);
+        makeWindowVisible(w);
         w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
         activity.addWindow(w);
         return w;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 6f5389d..a79a519 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -88,6 +88,7 @@
 
 import java.io.File;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Supplier;
 
 /**
  * JUnit test rule to correctly setting up system services like {@link WindowManagerService}
@@ -112,6 +113,7 @@
     private WindowState.PowerManagerWrapper mPowerManagerWrapper;
     private InputManagerService mImService;
     private InputChannel mInputChannel;
+    private Supplier<Surface> mSurfaceFactory = () -> mock(Surface.class);
     /**
      * Spied {@link SurfaceControl.Transaction} class than can be used to verify calls.
      */
@@ -286,7 +288,7 @@
         DisplayThread.getHandler().post(StrictMode::allowThreadDiskWritesMask);
         mWmService = WindowManagerService.main(
                 mContext, mImService, false, false, mWMPolicy, mAtmService, StubTransaction::new,
-                () -> mock(Surface.class), (unused) -> new MockSurfaceControlBuilder());
+                () -> mSurfaceFactory.get(), (unused) -> new MockSurfaceControlBuilder());
         spyOn(mWmService);
         spyOn(mWmService.mRoot);
         // Invoked during {@link ActivityStack} creation.
@@ -296,6 +298,7 @@
         // Called when moving activity to pinned stack.
         doNothing().when(mWmService.mRoot).ensureActivitiesVisible(any(),
                 anyInt(), anyBoolean(), anyBoolean());
+        spyOn(mWmService.mDisplayWindowSettings);
 
         // Setup factory classes to prevent calls to native code.
         mTransaction = spy(StubTransaction.class);
@@ -395,6 +398,10 @@
         return mPowerManagerWrapper;
     }
 
+    void setSurfaceFactory(Supplier<Surface> factory) {
+        mSurfaceFactory = factory;
+    }
+
     void cleanupWindowManagerHandlers() {
         final WindowManagerService wm = getWindowManagerService();
         if (wm == null) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index 8b025e3..4bd8edd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -79,7 +79,7 @@
         // Stack should contain visible app window to be considered visible.
         final Task pinnedTask = createTaskInStack(mPinnedStack, 0 /* userId */);
         assertFalse(mPinnedStack.isVisible());
-        final ActivityRecord pinnedApp = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord pinnedApp = createNonAttachedActivityRecord(mDisplayContent);
         pinnedTask.addChild(pinnedApp, 0 /* addPos */);
         assertTrue(mPinnedStack.isVisible());
     }
@@ -94,7 +94,7 @@
         final Task stack = createTaskStackOnDisplay(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent);
         final Task task = createTaskInStack(stack, 0 /* userId */);
-        final ActivityRecord activity = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         task.addChild(activity, 0 /* addPos */);
         final TaskDisplayArea taskDisplayArea = activity.getDisplayArea();
         activity.mNeedsAnimationBoundsLayer = true;
@@ -236,7 +236,7 @@
         ActivityRecord homeActivity = rootHomeTask.getTopNonFinishingActivity();
         if (homeActivity == null) {
             homeActivity = new ActivityBuilder(mWm.mAtmService)
-                    .setStack(rootHomeTask).setCreateTask(true).build();
+                    .setParentTask(rootHomeTask).setCreateTask(true).build();
         }
         homeActivity.setVisible(false);
         homeActivity.mVisibleRequested = true;
@@ -255,10 +255,10 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
         final Task secondStack = secondTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(firstStack).build();
-        final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(secondStack).build();
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(firstStack).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(secondStack).build();
 
         // Activity on TDA1 is focused
         mDisplayContent.setFocusedApp(firstActivity);
@@ -284,8 +284,7 @@
         final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
         final Task stack = taskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(stack).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
 
         mDisplayContent.setFocusedApp(activity);
         activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -297,6 +296,37 @@
         assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
     }
 
+    @Test
+    @UseTestDisplay
+    public void testRemove_reparentToDefault() {
+        final Task task = createTaskStackOnDisplay(mDisplayContent);
+        final TaskDisplayArea displayArea = task.getDisplayArea();
+        displayArea.remove();
+        assertTrue(displayArea.isRemoved());
+        assertFalse(displayArea.hasChild());
+
+        final RootWindowContainer rootWindowContainer = mWm.mAtmService.mRootWindowContainer;
+        final TaskDisplayArea defaultTaskDisplayArea =
+                rootWindowContainer.getDefaultTaskDisplayArea();
+        assertTrue(defaultTaskDisplayArea.mChildren.contains(task));
+    }
+
+    @Test
+    @UseTestDisplay
+    public void testRemove_stackCreatedByOrganizer() {
+        final Task task = createTaskStackOnDisplay(mDisplayContent);
+        task.mCreatedByOrganizer = true;
+        final TaskDisplayArea displayArea = task.getDisplayArea();
+        displayArea.remove();
+        assertTrue(displayArea.isRemoved());
+        assertFalse(displayArea.hasChild());
+
+        final RootWindowContainer rootWindowContainer = mWm.mAtmService.mRootWindowContainer;
+        final TaskDisplayArea defaultTaskDisplayArea =
+                rootWindowContainer.getDefaultTaskDisplayArea();
+        assertFalse(defaultTaskDisplayArea.mChildren.contains(task));
+    }
+
     private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask,
             boolean reuseCandidate) {
         final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 1d32e17..a1097d2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -1351,7 +1351,7 @@
     private ActivityRecord createSourceActivity(TestDisplayContent display) {
         final Task stack = display.getDefaultTaskDisplayArea()
                 .createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
-        return new ActivityBuilder(mAtm).setStack(stack).setCreateTask(true).build();
+        return new ActivityBuilder(mAtm).setTask(stack).build();
     }
 
     private void addFreeformTaskTo(TestDisplayContent display, Rect bounds) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
index 27cae2f..7abe369 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
@@ -76,11 +76,8 @@
         mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm);
         removeGlobalMinSizeRestriction();
 
-        final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity = new ActivityBuilder(stack.mAtmService)
-                .setStack(stack)
-                // In real case, there is no additional level for freeform mode.
-                .setCreateTask(false)
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
                 .build();
         final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "window");
         mPositioner = new TaskPositioner(mWm);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 2fa7589..f7e68ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -269,7 +269,8 @@
         assertEquals(fullScreenBounds.height(), task.getBounds().height());
 
         // Top activity gets used
-        final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).setStack(stack).build();
+        final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).setParentTask(stack)
+                .build();
         assertEquals(top, task.getTopNonFinishingActivity());
         top.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
         assertThat(task.getBounds().width()).isGreaterThan(task.getBounds().height());
@@ -1001,7 +1002,8 @@
 
     @Test
     public void testNotSpecifyOrientationByFloatingTask() {
-        final Task task = getTestTask();
+        final Task task = new TaskBuilder(mSupervisor)
+                .setCreateActivity(true).setCreateParentTask(true).build();
         final ActivityRecord activity = task.getTopMostActivity();
         final WindowContainer<?> parentContainer = task.getParent();
         final TaskDisplayArea taskDisplayArea = task.getDisplayArea();
@@ -1027,10 +1029,10 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
         final Task secondStack = secondTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(firstStack).build();
-        final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(secondStack).build();
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(firstStack).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(secondStack).build();
         firstActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
         secondActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index b4a1337..5ea73b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -20,17 +20,23 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 
+import android.app.ActivityManager;
 import android.app.ActivityManager.TaskDescription;
 import android.app.ActivityManager.TaskSnapshot;
 import android.content.ComponentName;
@@ -41,14 +47,18 @@
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
 import android.platform.test.annotations.Presubmit;
+import android.view.Display;
+import android.view.IWindowSession;
 import android.view.InsetsState;
 import android.view.Surface;
 import android.view.SurfaceControl;
+import android.view.WindowManager;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.TaskSnapshotSurface.Window;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -67,9 +77,6 @@
 
     private void setupSurface(int width, int height, Rect contentInsets, int sysuiVis,
             int windowFlags, Rect taskBounds) {
-        final HardwareBuffer buffer = HardwareBuffer.create(width, height, HardwareBuffer.RGBA_8888,
-                1, HardwareBuffer.USAGE_CPU_READ_RARELY);
-
         // Previously when constructing TaskSnapshots for this test, scale was 1.0f, so to mimic
         // this behavior set the taskSize to be the same as the taskBounds width and height. The
         // taskBounds passed here are assumed to be the same task bounds as when the snapshot was
@@ -79,16 +86,24 @@
         assertEquals(height, taskBounds.height());
         Point taskSize = new Point(taskBounds.width(), taskBounds.height());
 
-        final TaskSnapshot snapshot = new TaskSnapshot(
+        final TaskSnapshot snapshot = createTaskSnapshot(width, height, taskSize, contentInsets);
+        mSurface = new TaskSnapshotSurface(mWm, Display.DEFAULT_DISPLAY, new Window(),
+                new SurfaceControl(), snapshot, "Test", createTaskDescription(Color.WHITE,
+                Color.RED, Color.BLUE), sysuiVis, windowFlags, 0, taskBounds, ORIENTATION_PORTRAIT,
+                ACTIVITY_TYPE_STANDARD, new InsetsState());
+    }
+
+    private ActivityManager.TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize,
+            Rect contentInsets) {
+        final HardwareBuffer buffer = HardwareBuffer.create(width, height, HardwareBuffer.RGBA_8888,
+                1, HardwareBuffer.USAGE_CPU_READ_RARELY);
+        return new TaskSnapshot(
                 System.currentTimeMillis(),
                 new ComponentName("", ""), buffer,
                 ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
                 Surface.ROTATION_0, taskSize, contentInsets, false,
                 true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN,
                 0 /* systemUiVisibility */, false /* isTranslucent */);
-        mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test",
-                createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0,
-                taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState());
     }
 
     private static TaskDescription createTaskDescription(int background, int statusBar,
@@ -105,6 +120,35 @@
                 new Rect(0, 0, width, height));
     }
 
+    private boolean isTrustedOverlay(WindowManager.LayoutParams params) {
+        return (params.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mSystemServicesTestRule.setSurfaceFactory(() -> {
+            Surface surface = mock(Surface.class);
+            when(surface.isValid()).thenReturn(true);
+            return surface;
+        });
+    }
+
+    @Test
+    public void createSurface_asTrustedOverlay() throws Exception {
+        Point task = new Point(200, 100);
+        ActivityRecord activityRecord = createActivityRecord(mDisplayContent);
+        createWindow(null, TYPE_BASE_APPLICATION, activityRecord, "window");
+        TaskSnapshot taskSnapshot = createTaskSnapshot(task.x, task.y, task, new Rect());
+        IWindowSession session = mock(IWindowSession.class);
+
+        TaskSnapshotSurface surface = TaskSnapshotSurface.create(mWm, activityRecord, taskSnapshot,
+                session);
+
+        assertThat(surface).isNotNull();
+        verify(session).addToDisplay(any(), argThat(this::isTrustedOverlay), anyInt(), anyInt(),
+                any(), any(), any(), any(), any(), any());
+    }
+
     @Test
     public void fillEmptyBackground_fillHorizontally() {
         setupSurface(200, 100);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
index 7cf30c0..4041412 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
@@ -85,12 +85,12 @@
     public void testClosingAppDifferentStackOrientation() {
         final Task stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task1 = createTaskInStack(stack, 0 /* userId */);
-        ActivityRecord activity1 = createTestActivityRecord(mDisplayContent);
+        ActivityRecord activity1 = createNonAttachedActivityRecord(mDisplayContent);
         task1.addChild(activity1, 0);
         activity1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         final Task task2 = createTaskInStack(stack, 1 /* userId */);
-        ActivityRecord activity2 = createTestActivityRecord(mDisplayContent);
+        ActivityRecord activity2 = createNonAttachedActivityRecord(mDisplayContent);
         task2.addChild(activity2, 0);
         activity2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
 
@@ -103,12 +103,12 @@
     public void testMoveTaskToBackDifferentStackOrientation() {
         final Task stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task1 = createTaskInStack(stack, 0 /* userId */);
-        ActivityRecord activity1 = createTestActivityRecord(mDisplayContent);
+        ActivityRecord activity1 = createNonAttachedActivityRecord(mDisplayContent);
         task1.addChild(activity1, 0);
         activity1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         final Task task2 = createTaskInStack(stack, 1 /* userId */);
-        ActivityRecord activity2 = createTestActivityRecord(mDisplayContent);
+        ActivityRecord activity2 = createNonAttachedActivityRecord(mDisplayContent);
         task2.addChild(activity2, 0);
         activity2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
         assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
@@ -217,7 +217,7 @@
     public void testActivityAndTaskGetsProperType() {
         final Task stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task1 = createTaskInStack(stack, 0 /* userId */);
-        ActivityRecord activity1 = createTestActivityRecord(mDisplayContent);
+        ActivityRecord activity1 = createNonAttachedActivityRecord(mDisplayContent);
 
         // First activity should become standard
         task1.addChild(activity1, 0);
@@ -225,7 +225,7 @@
         assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, task1.getActivityType());
 
         // Second activity should also become standard
-        ActivityRecord activity2 = createTestActivityRecord(mDisplayContent);
+        ActivityRecord activity2 = createNonAttachedActivityRecord(mDisplayContent);
         task1.addChild(activity2, WindowContainer.POSITION_TOP);
         assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, activity2.getActivityType());
         assertEquals(WindowConfiguration.ACTIVITY_TYPE_STANDARD, task1.getActivityType());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index b6b3d66..238f314 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -63,7 +63,7 @@
     public void testRemoveContainer() {
         final Task stackController1 = createTaskStackOnDisplay(mDisplayContent);
         final Task task = createTaskInStack(stackController1, 0 /* userId */);
-        final ActivityRecord activity = createActivityRecordInTask(mDisplayContent, task);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
 
         task.removeIfPossible();
         // Assert that the container was removed.
@@ -76,7 +76,7 @@
     public void testRemoveContainer_deferRemoval() {
         final Task stackController1 = createTaskStackOnDisplay(mDisplayContent);
         final Task task = createTaskInStack(stackController1, 0 /* userId */);
-        final ActivityRecord activity = createActivityRecordInTask(mDisplayContent, task);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
 
         doReturn(true).when(task).shouldDeferRemoval();
 
@@ -158,8 +158,8 @@
     public void testIsInStack() {
         final Task task1 = createTaskStackOnDisplay(mDisplayContent);
         final Task task2 = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, task1);
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, task2);
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent, task1);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent, task2);
         assertEquals(activity1, task1.isInTask(activity1));
         assertNull(task1.isInTask(activity2));
     }
@@ -168,9 +168,9 @@
     public void testRemoveChildForOverlayTask() {
         final Task task = createTaskStackOnDisplay(mDisplayContent);
         final int taskId = task.mTaskId;
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, task);
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, task);
-        final ActivityRecord activity3 = createActivityRecordInTask(mDisplayContent, task);
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent, task);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent, task);
+        final ActivityRecord activity3 = createActivityRecord(mDisplayContent, task);
         activity1.setTaskOverlay(true);
         activity2.setTaskOverlay(true);
         activity3.setTaskOverlay(true);
@@ -207,8 +207,8 @@
         final Task rootTask = createTaskStackOnDisplay(mDisplayContent);
         final Task leafTask1 = createTaskInStack(rootTask, 0 /* userId */);
         final Task leafTask2 = createTaskInStack(rootTask, 0 /* userId */);
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, leafTask1);
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, leafTask2);
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent, leafTask1);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent, leafTask2);
 
         // Check visibility of occluded tasks
         doReturn(false).when(leafTask1).shouldBeVisible(any());
@@ -257,4 +257,24 @@
         task.resolveOverrideConfiguration(parentConfig);
         assertThat(resolvedOverride.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED);
     }
+
+    @Test
+    public void testCleanUpActivityReferences_clearLastTaskBoundsComputeActivity() {
+        final Task rootTask = createTaskStackOnDisplay(mDisplayContent);
+        final Task leafTask = createTaskInStack(rootTask, 0 /* userId */);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent, leafTask);
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent, leafTask);
+        activity1.finishing = false;
+        leafTask.resolveOverrideConfiguration(rootTask.getConfiguration());
+
+        assertEquals(activity1, leafTask.getLastTaskBoundsComputeActivity());
+
+        leafTask.cleanUpActivityReferences(activity2);
+
+        assertNotNull(leafTask.getLastTaskBoundsComputeActivity());
+
+        leafTask.cleanUpActivityReferences(activity1);
+
+        assertNull(leafTask.getLastTaskBoundsComputeActivity());
+    }
 }
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 feb509c..ef56c13 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -51,8 +51,8 @@
                 ACTIVITY_TYPE_STANDARD, mDisplayContent);
         newTask.setHasBeenVisible(true);
         oldTask.setHasBeenVisible(false);
-        final ActivityRecord closing = createActivityRecordInTask(oldTask);
-        final ActivityRecord opening = createActivityRecordInTask(newTask);
+        final ActivityRecord closing = createActivityRecord(oldTask);
+        final ActivityRecord opening = createActivityRecord(newTask);
         closing.setVisible(true);
         closing.mVisibleRequested = false;
         opening.setVisible(false);
@@ -102,9 +102,9 @@
                 ACTIVITY_TYPE_STANDARD, mDisplayContent);
         newTask.setHasBeenVisible(true);
         oldTask.setHasBeenVisible(false);
-        final ActivityRecord closing = createActivityRecordInTask(oldTask);
-        final ActivityRecord opening = createActivityRecordInTask(newNestedTask);
-        final ActivityRecord opening2 = createActivityRecordInTask(newNestedTask2);
+        final ActivityRecord closing = createActivityRecord(oldTask);
+        final ActivityRecord opening = createActivityRecord(newNestedTask);
+        final ActivityRecord opening2 = createActivityRecord(newNestedTask2);
         closing.setVisible(true);
         closing.mVisibleRequested = false;
         opening.setVisible(false);
@@ -144,8 +144,8 @@
         final DisplayArea tda = showTask.getDisplayArea();
         showTask.setHasBeenVisible(true);
         showTask2.setHasBeenVisible(true);
-        final ActivityRecord showing = createActivityRecordInTask(showNestedTask);
-        final ActivityRecord showing2 = createActivityRecordInTask(showTask2);
+        final ActivityRecord showing = createActivityRecord(showNestedTask);
+        final ActivityRecord showing2 = createActivityRecord(showTask2);
         showing.setVisible(false);
         showing.mVisibleRequested = true;
         showing2.setVisible(false);
diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 78dfd40..45e1141 100644
--- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -44,7 +44,7 @@
 
     @Test
     public void testFlow() {
-        final ActivityRecord activity = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
         mDisplayContent.mUnknownAppVisibilityController.notifyAppResumedFinished(activity);
         mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(activity);
@@ -56,7 +56,7 @@
 
     @Test
     public void testSkipResume() {
-        final ActivityRecord activity = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         activity.mLaunchTaskBehind = true;
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
         mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(activity);
@@ -68,8 +68,8 @@
 
     @Test
     public void testMultiple() {
-        final ActivityRecord activity1 = createTestActivityRecord(mDisplayContent);
-        final ActivityRecord activity2 = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity1 = createNonAttachedActivityRecord(mDisplayContent);
+        final ActivityRecord activity2 = createNonAttachedActivityRecord(mDisplayContent);
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity1);
         mDisplayContent.mUnknownAppVisibilityController.notifyAppResumedFinished(activity1);
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity2);
@@ -84,7 +84,7 @@
 
     @Test
     public void testClear() {
-        final ActivityRecord activity = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
         mDisplayContent.mUnknownAppVisibilityController.clear();
         assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
@@ -92,7 +92,7 @@
 
     @Test
     public void testRemoveFinishingInvisibleActivityFromUnknown() {
-        final ActivityRecord activity = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
         activity.finishing = true;
         activity.mVisibleRequested = true;
@@ -102,7 +102,7 @@
 
     @Test
     public void testAppRemoved() {
-        final ActivityRecord activity = createTestActivityRecord(mDisplayContent);
+        final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent);
         mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity);
         mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(activity);
         assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 63367ac..a91a137 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -296,8 +296,7 @@
 
     private WindowState createWallpaperTargetWindow(DisplayContent dc) {
         final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
-                .setStack(dc.getDefaultTaskDisplayArea().getRootHomeTask())
-                .setCreateTask(true)
+                .setTask(dc.getDefaultTaskDisplayArea().getRootHomeTask())
                 .build();
         homeActivity.setVisibility(true);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index f5d6889..e0c72fb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -810,7 +810,7 @@
     public void testOnDisplayChanged() {
         final Task stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task = createTaskInStack(stack, 0 /* userId */);
-        final ActivityRecord activity = createActivityRecordInTask(mDisplayContent, task);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
 
         final DisplayContent newDc = createNewDisplay();
         stack.getDisplayArea().removeStack(stack);
@@ -853,17 +853,17 @@
     public void testTaskCanApplyAnimation() {
         final Task stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task = createTaskInStack(stack, 0 /* userId */);
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, task);
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, task);
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent, task);
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent, task);
         verifyWindowContainerApplyAnimation(task, activity1, activity2);
     }
 
     @Test
     public void testStackCanApplyAnimation() {
         final Task stack = createTaskStackOnDisplay(mDisplayContent);
-        final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent,
+        final ActivityRecord activity2 = createActivityRecord(mDisplayContent,
                 createTaskInStack(stack, 0 /* userId */));
-        final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent,
+        final ActivityRecord activity1 = createActivityRecord(mDisplayContent,
                 createTaskInStack(stack, 0 /* userId */));
         verifyWindowContainerApplyAnimation(stack, activity1, activity2);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
index 47e4559..78e873e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
@@ -49,10 +49,10 @@
     @UseTestDisplay(addWindows = { W_DOCK_DIVIDER, W_INPUT_METHOD })
     @Test
     public void testDockedDividerPosition() {
-        final WindowState splitScreenWindow = createWindowOnStack(null,
+        final WindowState splitScreenWindow = createWindow(null,
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
                 mDisplayContent, "splitScreenWindow");
-        final WindowState splitScreenSecondaryWindow = createWindowOnStack(null,
+        final WindowState splitScreenSecondaryWindow = createWindow(null,
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
                 TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
index 8d5363c..ba144dd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
@@ -20,12 +20,16 @@
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
+import static android.provider.Settings.Global.DEVELOPMENT_IGNORE_VENDOR_DISPLAY_SETTINGS;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.content.ContentResolver;
@@ -37,6 +41,9 @@
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.List;
 
 /**
  * Test for {@link WindowManagerService.SettingsObserver}.
@@ -124,6 +131,36 @@
         }
     }
 
+    @Test
+    public void testEnabledIgnoreVendorDisplaySettings() {
+        try (SettingsSession ignoreVendorDisplaySettingsSession = new
+                SettingsSession(DEVELOPMENT_IGNORE_VENDOR_DISPLAY_SETTINGS)) {
+            final boolean ignoreVendorDisplaySettings =
+                    !ignoreVendorDisplaySettingsSession.getSetting();
+            final Uri ignoreVendorDisplaySettingUri =
+                    ignoreVendorDisplaySettingsSession.setSetting(ignoreVendorDisplaySettings);
+
+            clearInvocations(mWm.mRoot);
+            clearInvocations(mWm.mDisplayWindowSettings);
+
+            mWm.mSettingsObserver.onChange(false /* selfChange */, ignoreVendorDisplaySettingUri);
+
+            assertEquals(mWm.mDisplayWindowSettingsProvider.getVendorSettingsIgnored(),
+                    ignoreVendorDisplaySettings);
+
+            ArgumentCaptor<DisplayContent> captor =
+                    ArgumentCaptor.forClass(DisplayContent.class);
+            verify(mWm.mDisplayWindowSettings, times(mWm.mRoot.mChildren.size()))
+                    .applySettingsToDisplayLocked(captor.capture());
+            List<DisplayContent> configuredDisplays = captor.getAllValues();
+            for (DisplayContent dc : mWm.mRoot.mChildren) {
+                assertTrue(configuredDisplays.contains(dc));
+            }
+
+            verify(mWm.mRoot, atLeastOnce()).performSurfacePlacement();
+        }
+    }
+
     private class SettingsSession implements AutoCloseable {
 
         private static final int SETTING_VALUE_OFF = 0;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index f1d49d5..7a41c02 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -389,8 +389,7 @@
         final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
         final Task stack = taskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(stack).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
         taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mDisplayContent.setFocusedApp(activity);
         activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -428,8 +427,7 @@
         final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
         final Task stack = taskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
-                .setStack(stack).build();
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
         mDisplayContent.setFocusedApp(activity);
         activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
@@ -780,7 +778,7 @@
     };
 
     private ActivityRecord makePipableActivity() {
-        final ActivityRecord record = createActivityRecord(mDisplayContent,
+        final ActivityRecord record = createActivityRecordWithParentTask(mDisplayContent,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         record.info.flags |= ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
         spyOn(record);
@@ -849,7 +847,7 @@
 
         final Task stack = createStack();
         final Task task = createTask(stack);
-        final ActivityRecord record = createActivityRecordInTask(stack.mDisplayContent, task);
+        final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
 
         stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
@@ -885,10 +883,10 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task stack = createStack();
         final Task task = createTask(stack);
-        final ActivityRecord activity = createActivityRecordInTask(stack.mDisplayContent, task);
+        final ActivityRecord activity = createActivityRecord(stack.mDisplayContent, task);
         final Task stack2 = createStack();
         final Task task2 = createTask(stack2);
-        final ActivityRecord activity2 = createActivityRecordInTask(stack.mDisplayContent, task2);
+        final ActivityRecord activity2 = createActivityRecord(stack.mDisplayContent, task2);
 
         assertTrue(stack.isOrganized());
         assertTrue(stack2.isOrganized());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 94bbfca..21be6ef 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -291,25 +291,19 @@
         assertEquals(1 /* minTaskLayer */, mWpc.computeOomAdjFromActivities(callback));
         assertEquals(visible, callbackResult[0]);
 
-        // The oom state will be updated in handler from activity state change.
         callbackResult[0] = 0;
         activity.mVisibleRequested = false;
         activity.setState(Task.ActivityState.PAUSED, "test");
-        waitHandlerIdle(mAtm.mH);
         mWpc.computeOomAdjFromActivities(callback);
         assertEquals(paused, callbackResult[0]);
 
-        // updateProcessInfo with updateOomAdj=true should refresh the state immediately.
         callbackResult[0] = 0;
         activity.setState(Task.ActivityState.STOPPING, "test");
-        mWpc.updateProcessInfo(false /* updateServiceConnectionActivities */,
-                true /* activityChange */, true /* updateOomAdj */, false /* addPendingTopUid */);
         mWpc.computeOomAdjFromActivities(callback);
         assertEquals(stopping, callbackResult[0]);
 
         callbackResult[0] = 0;
         activity.setState(Task.ActivityState.STOPPED, "test");
-        waitHandlerIdle(mAtm.mH);
         mWpc.computeOomAdjFromActivities(callback);
         assertEquals(other, callbackResult[0]);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 2691ae8..88a3f97 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
@@ -63,15 +62,18 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.when;
 
 import android.graphics.Insets;
 import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.util.Size;
 import android.view.DisplayCutout;
+import android.view.InputWindowHandle;
 import android.view.InsetsState;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
@@ -318,8 +320,7 @@
     public void testPrepareWindowToDisplayDuringRelayout() {
         // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before
         // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same activity.
-        final ActivityRecord activity = createActivityRecord(mDisplayContent,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord activity = createActivityRecord(mDisplayContent);
         final WindowState first = createWindow(null, TYPE_APPLICATION, activity, "first");
         final WindowState second = createWindow(null, TYPE_APPLICATION, activity, "second");
 
@@ -466,10 +467,10 @@
     public void testDisplayIdUpdatedOnReparent() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         // fake a different display
-        app.mInputWindowHandle.displayId = mDisplayContent.getDisplayId() + 1;
+        app.mInputWindowHandle.setDisplayId(mDisplayContent.getDisplayId() + 1);
         app.onDisplayChanged(mDisplayContent);
 
-        assertThat(app.mInputWindowHandle.displayId, is(mDisplayContent.getDisplayId()));
+        assertThat(app.mInputWindowHandle.getDisplayId(), is(mDisplayContent.getDisplayId()));
         assertThat(app.getDisplayId(), is(mDisplayContent.getDisplayId()));
     }
 
@@ -680,6 +681,56 @@
         assertFalse(win0.canReceiveTouchInput());
     }
 
+    @Test
+    public void testUpdateInputWindowHandle() {
+        final WindowState win = createWindow(null, TYPE_APPLICATION, "win");
+        win.mAttrs.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+        final InputWindowHandle handle = new InputWindowHandle(
+                win.mInputWindowHandle.getInputApplicationHandle(), win.getDisplayId());
+        final InputWindowHandleWrapper handleWrapper = new InputWindowHandleWrapper(handle);
+        final IBinder inputChannelToken = mock(IBinder.class);
+        win.mInputChannelToken = inputChannelToken;
+
+        mDisplayContent.getInputMonitor().populateInputWindowHandle(handleWrapper, win);
+
+        assertTrue(handleWrapper.isChanged());
+        // The window of standard resizable task should not use surface crop as touchable region.
+        assertFalse(handle.replaceTouchableRegionWithCrop);
+        assertEquals(inputChannelToken, handle.token);
+        assertEquals(win.mActivityRecord.getInputApplicationHandle(false /* update */),
+                handle.inputApplicationHandle);
+        assertEquals(win.mAttrs.inputFeatures, handle.inputFeatures);
+        assertEquals(win.isVisible(), handle.visible);
+
+        final SurfaceControl sc = mock(SurfaceControl.class);
+        final SurfaceControl.Transaction transaction = mSystemServicesTestRule.mTransaction;
+        InputMonitor.setInputWindowInfoIfNeeded(transaction, sc, handleWrapper);
+
+        // The fields of input window handle are changed, so it must set input window info
+        // successfully. And then the changed flag should be reset.
+        verify(transaction).setInputWindowInfo(eq(sc), eq(handle));
+        assertFalse(handleWrapper.isChanged());
+        // Populate the same states again, the handle should not detect change.
+        mDisplayContent.getInputMonitor().populateInputWindowHandle(handleWrapper, win);
+        assertFalse(handleWrapper.isChanged());
+
+        // Apply the no change handle, the invocation of setInputWindowInfo should be skipped.
+        clearInvocations(transaction);
+        InputMonitor.setInputWindowInfoIfNeeded(transaction, sc, handleWrapper);
+        verify(transaction, never()).setInputWindowInfo(any(), any());
+
+        // Populate as an overlay to disable the input of window.
+        InputMonitor.populateOverlayInputInfo(handleWrapper, false /* isVisible */);
+        // The overlay attributes should be set.
+        assertTrue(handleWrapper.isChanged());
+        assertFalse(handle.focusable);
+        assertFalse(handle.visible);
+        assertNull(handle.token);
+        assertEquals(0L, handle.dispatchingTimeoutMillis);
+        assertEquals(WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL,
+                handle.inputFeatures);
+    }
+
     @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testNeedsRelativeLayeringToIme_notAttached() {
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 62f04a1..d5fb3c5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -47,7 +47,6 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
-import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -82,7 +81,6 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.window.ITaskOrganizer;
-import android.window.WindowContainerToken;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.server.AttributeCache;
@@ -248,48 +246,19 @@
         return createActivityRecord(dc, windowingMode, activityType);
     }
 
-    ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode, int activityType) {
-        return createTestActivityRecord(dc, windowingMode, activityType);
+    WindowState createAppWindow(Task task, int type, String name) {
+        final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent());
+        task.addChild(activity, 0);
+        return createWindow(null, type, activity, name);
     }
 
-    ActivityRecord createTestActivityRecord(DisplayContent dc, int windowingMode,
-            int activityType) {
-        final Task stack = createTaskStackOnDisplay(windowingMode, activityType, dc);
-        return createTestActivityRecord(stack);
-    }
-
-    /** Creates an {@link ActivityRecord} and adds it to the specified {@link Task}. */
-    static ActivityRecord createActivityRecordInTask(DisplayContent dc, Task task) {
-        final ActivityRecord activity = createTestActivityRecord(dc);
-        task.addChild(activity, POSITION_TOP);
-        return activity;
-    }
-
-    /** Creates an {@link ActivityRecord} and adds it to the specified {@link Task}. */
-    static ActivityRecord createActivityRecordInTask(Task task) {
-        return createActivityRecordInTask(task.getDisplayContent(), task);
-    }
-
-    static ActivityRecord createTestActivityRecord(DisplayContent dc) {
-        final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService).build();
-        postCreateActivitySetup(activity, dc);
-        return activity;
-    }
-
-    static ActivityRecord createTestActivityRecord(Task stack) {
-        final ActivityRecord activity = new ActivityBuilder(stack.mAtmService)
-                .setStack(stack)
-                .setCreateTask(true)
-                .build();
-        postCreateActivitySetup(activity, stack.getDisplayContent());
-        return activity;
-    }
-
-    private static void postCreateActivitySetup(ActivityRecord activity, DisplayContent dc) {
-        activity.onDisplayChanged(dc);
-        activity.setOccludesParent(true);
-        activity.setVisible(true);
-        activity.mVisibleRequested = true;
+    // TODO: Move these calls to a builder?
+    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
+            IWindow iwindow) {
+        final WindowToken token = createWindowToken(
+                dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
+        return createWindow(parent, type, token, name, 0 /* ownerId */,
+                false /* ownerCanAddInternalSystemWindow */, iwindow);
     }
 
     WindowState createWindow(WindowState parent, int type, String name) {
@@ -304,31 +273,15 @@
                 : createWindow(parent, type, parent.mToken, name, ownerId);
     }
 
-    WindowState createWindowOnStack(WindowState parent, int windowingMode, int activityType,
+    WindowState createWindow(WindowState parent, int windowingMode, int activityType,
             int type, DisplayContent dc, String name) {
         final WindowToken token = createWindowToken(dc, windowingMode, activityType, type);
         return createWindow(parent, type, token, name);
     }
 
-    WindowState createAppWindow(Task task, int type, String name) {
-        final ActivityRecord activity = createTestActivityRecord(task.getDisplayContent());
-        task.addChild(activity, 0);
-        return createWindow(null, type, activity, name);
-    }
-
-    // TODO: Move these calls to a builder?
-    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
-            IWindow iwindow) {
-        final WindowToken token = createWindowToken(
-                dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
-        return createWindow(parent, type, token, name, 0 /* ownerId */,
-                false /* ownerCanAddInternalSystemWindow */, iwindow);
-    }
-
     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
-        final WindowToken token = createWindowToken(
-                dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
-        return createWindow(parent, type, token, name, 0 /* ownerId */);
+        return createWindow(
+                parent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type, dc, name);
     }
 
     WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
@@ -446,6 +399,87 @@
         return task;
     }
 
+    /** Creates an {@link ActivityRecord}. */
+    static ActivityRecord createNonAttachedActivityRecord(DisplayContent dc) {
+        final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService)
+                .setOnTop(true)
+                .build();
+        postCreateActivitySetup(activity, dc);
+        return activity;
+    }
+
+    /**
+     * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
+     * [Task] - [ActivityRecord]
+     */
+    ActivityRecord createActivityRecord(DisplayContent dc) {
+        return createActivityRecord(dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+    }
+
+    /**
+     * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
+     * [Task] - [ActivityRecord]
+     */
+    ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode,
+            int activityType) {
+        final Task task = createTaskStackOnDisplay(windowingMode, activityType, dc);
+        return createActivityRecord(dc, task);
+    }
+
+    /**
+     *  Creates an {@link ActivityRecord} and adds it to the specified {@link Task}.
+     * [Task] - [ActivityRecord]
+     */
+    static ActivityRecord createActivityRecord(Task task) {
+        return createActivityRecord(task.getDisplayContent(), task);
+    }
+
+    /**
+     * Creates an {@link ActivityRecord} and adds it to the specified {@link Task}.
+     * [Task] - [ActivityRecord]
+     */
+    static ActivityRecord createActivityRecord(DisplayContent dc, Task task) {
+        final ActivityRecord activity = new ActivityBuilder(dc.mWmService.mAtmService)
+                .setTask(task)
+                .setOnTop(true)
+                .build();
+        postCreateActivitySetup(activity, dc);
+        return activity;
+    }
+
+    /**
+     * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
+     * Then adds the new created {@link Task} to a new created parent {@link Task}
+     * [Task1] - [Task2] - [ActivityRecord]
+     */
+    ActivityRecord createActivityRecordWithParentTask(DisplayContent dc, int windowingMode,
+            int activityType) {
+        final Task task = createTaskStackOnDisplay(windowingMode, activityType, dc);
+        return createActivityRecordWithParentTask(task);
+    }
+
+    /**
+     * Creates an {@link ActivityRecord} and adds it to a new created {@link Task}.
+     * Then adds the new created {@link Task} to the specified parent {@link Task}
+     * [Task1] - [Task2] - [ActivityRecord]
+     */
+    static ActivityRecord createActivityRecordWithParentTask(Task parentTask) {
+        final ActivityRecord activity = new ActivityBuilder(parentTask.mAtmService)
+                .setParentTask(parentTask)
+                .setCreateTask(true)
+                .setOnTop(true)
+                .build();
+        postCreateActivitySetup(activity, parentTask.getDisplayContent());
+        return activity;
+    }
+
+    private static void postCreateActivitySetup(ActivityRecord activity, DisplayContent dc) {
+        activity.onDisplayChanged(dc);
+        activity.setOccludesParent(true);
+        activity.setVisible(true);
+        activity.mVisibleRequested = true;
+    }
+
     /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
     DisplayContent createNewDisplay() {
         return createNewDisplay(true /* supportIme */);
@@ -614,19 +648,20 @@
         private String mProcessName = "name";
         private String mAffinity;
         private int mUid = 12345;
-        private boolean mCreateTask;
-        private Task mStack;
+        private boolean mCreateTask = false;
+        private Task mParentTask;
         private int mActivityFlags;
         private int mLaunchMode;
         private int mResizeMode = RESIZE_MODE_RESIZEABLE;
         private float mMaxAspectRatio;
         private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-        private boolean mLaunchTaskBehind;
+        private boolean mLaunchTaskBehind = false;
         private int mConfigChanges;
         private int mLaunchedFromPid;
         private int mLaunchedFromUid;
         private WindowProcessController mWpc;
         private Bundle mIntentExtras;
+        private boolean mOnTop = false;
 
         ActivityBuilder(ActivityTaskManagerService service) {
             mService = service;
@@ -667,8 +702,8 @@
             return this;
         }
 
-        ActivityBuilder setStack(Task stack) {
-            mStack = stack;
+        ActivityBuilder setParentTask(Task parentTask) {
+            mParentTask = parentTask;
             return this;
         }
 
@@ -732,6 +767,11 @@
             return this;
         }
 
+        ActivityBuilder setOnTop(boolean onTop) {
+            mOnTop = onTop;
+            return this;
+        }
+
         ActivityRecord build() {
             SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
             try {
@@ -752,11 +792,11 @@
             if (mCreateTask) {
                 mTask = new TaskBuilder(mService.mStackSupervisor)
                         .setComponent(mComponent)
-                        .setParentTask(mStack).build();
-            } else if (mTask == null && mStack != null && DisplayContent.alwaysCreateStack(
-                    mStack.getWindowingMode(), mStack.getActivityType())) {
+                        .setParentTask(mParentTask).build();
+            } else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateStack(
+                    mParentTask.getWindowingMode(), mParentTask.getActivityType())) {
                 // The stack can be the task root.
-                mTask = mStack;
+                mTask = mParentTask;
             }
 
             Intent intent = new Intent();
@@ -800,6 +840,9 @@
                 // to set it somewhere else since we can't mock resources.
                 doReturn(true).when(activity).occludesParent();
                 doReturn(true).when(activity).fillsParent();
+                if (mOnTop) {
+                    mTask.moveToFront("createActivity");
+                }
                 mTask.addChild(activity);
                 // Make visible by default...
                 activity.setVisible(true);
@@ -992,8 +1035,7 @@
             // Create child task with activity.
             if (mCreateActivity) {
                 new ActivityBuilder(mSupervisor.mService)
-                        .setCreateTask(true)
-                        .setStack(task)
+                        .setTask(task)
                         .build();
                 if (mOnTop) {
                     // We move the task to front again in order to regain focus after activity
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 dfb7280..e44d47a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -345,16 +345,16 @@
     @Test
     public void testStackLayers() {
         final WindowState anyWindow1 = createWindow("anyWindow");
-        final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
+        final WindowState pinnedStackWindow = createWindow(null, WINDOWING_MODE_PINNED,
                 ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION, mDisplayContent,
                 "pinnedStackWindow");
-        final WindowState dockedStackWindow = createWindowOnStack(null,
+        final WindowState dockedStackWindow = createWindow(null,
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
                 mDisplayContent, "dockedStackWindow");
-        final WindowState assistantStackWindow = createWindowOnStack(null,
+        final WindowState assistantStackWindow = createWindow(null,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
                 mDisplayContent, "assistantStackWindow");
-        final WindowState homeActivityWindow = createWindowOnStack(null, WINDOWING_MODE_FULLSCREEN,
+        final WindowState homeActivityWindow = createWindow(null, WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_HOME, TYPE_BASE_APPLICATION,
                 mDisplayContent, "homeActivityWindow");
         final WindowState anyWindow2 = createWindow("anyWindow2");
@@ -432,16 +432,16 @@
 
     @Test
     public void testDockedDividerPosition() {
-        final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
+        final WindowState pinnedStackWindow = createWindow(null, WINDOWING_MODE_PINNED,
                 ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION, mDisplayContent,
                 "pinnedStackWindow");
-        final WindowState splitScreenWindow = createWindowOnStack(null,
+        final WindowState splitScreenWindow = createWindow(null,
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
                 mDisplayContent, "splitScreenWindow");
-        final WindowState splitScreenSecondaryWindow = createWindowOnStack(null,
+        final WindowState splitScreenSecondaryWindow = createWindow(null,
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
                 TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");
-        final WindowState assistantStackWindow = createWindowOnStack(null,
+        final WindowState assistantStackWindow = createWindow(null,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
                 mDisplayContent, "assistantStackWindow");
 
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index a85eb53..1238e7b 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1468,8 +1468,11 @@
 
         /**
          * Writes the string {@param input} into the outgoing text stream for this RTT call. Since
-         * RTT transmits text in real-time, this method should be called once for each character
-         * the user enters into the device.
+         * RTT transmits text in real-time, this method should be called once for each user action.
+         * For example, when the user enters text as discrete characters using the keyboard, this
+         * method should be called once for each character. However, if the user enters text by
+         * pasting or autocomplete, the entire contents of the pasted or autocompleted text should
+         * be sent in one call to this method.
          *
          * This method is not thread-safe -- calling it from multiple threads simultaneously may
          * lead to interleaved text.
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 7f87019..83e63ef 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1365,6 +1365,7 @@
      * include those that were inserted before, maybe empty but not null.
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
     public List<SubscriptionInfo> getAllSubscriptionInfoList() {
         if (VDBG) logd("[getAllSubscriptionInfoList]+");
@@ -1382,7 +1383,7 @@
         }
 
         if (result == null) {
-            result = new ArrayList<>();
+            result = Collections.emptyList();
         }
         return result;
     }
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index 3e2a6ee..b054dfc 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -240,6 +240,12 @@
      */
     @Deprecated
     public int getSuggestedRetryTime() {
+        // To match the pre-deprecated getSuggestedRetryTime() behavior.
+        if (mSuggestedRetryTime == RETRY_INTERVAL_UNDEFINED) {
+            return 0;
+        } else if (mSuggestedRetryTime > Integer.MAX_VALUE) {
+            return Integer.MAX_VALUE;
+        }
         return (int) mSuggestedRetryTime;
     }
 
diff --git a/telephony/java/android/telephony/ims/AudioCodecAttributes.aidl b/telephony/java/android/telephony/ims/AudioCodecAttributes.aidl
new file mode 100644
index 0000000..bbab548
--- /dev/null
+++ b/telephony/java/android/telephony/ims/AudioCodecAttributes.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+
+package android.telephony.ims;
+
+parcelable AudioCodecAttributes;
diff --git a/telephony/java/android/telephony/ims/AudioCodecAttributes.java b/telephony/java/android/telephony/ims/AudioCodecAttributes.java
new file mode 100644
index 0000000..7b6ab00
--- /dev/null
+++ b/telephony/java/android/telephony/ims/AudioCodecAttributes.java
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Range;
+
+/**
+ * Parcelable object to handle audio codec attributes.
+ * It provides the audio codec bitrate, bandwidth and their upper/lower bound.
+ *
+ * @hide
+ */
+@SystemApi
+public final class AudioCodecAttributes implements Parcelable {
+    // The audio codec bitrate in kbps.
+    private float mBitrateKbps;
+    // The range of the audio codec bitrate in kbps.
+    private Range<Float> mBitrateRangeKbps;
+    // The audio codec bandwidth in kHz.
+    private float mBandwidthKhz;
+    // The range of the audio codec bandwidth in kHz.
+    private Range<Float> mBandwidthRangeKhz;
+
+
+    /**
+     * Constructor.
+     *
+     * @param bitrateKbps        The audio codec bitrate in kbps.
+     * @param bitrateRangeKbps  The range of the audio codec bitrate in kbps.
+     * @param bandwidthKhz      The audio codec bandwidth in kHz.
+     * @param bandwidthRangeKhz The range of the audio codec bandwidth in kHz.
+     */
+
+    public AudioCodecAttributes(float bitrateKbps, @NonNull Range<Float> bitrateRangeKbps,
+            float bandwidthKhz, @NonNull Range<Float> bandwidthRangeKhz) {
+        mBitrateKbps = bitrateKbps;
+        mBitrateRangeKbps = bitrateRangeKbps;
+        mBandwidthKhz = bandwidthKhz;
+        mBandwidthRangeKhz = bandwidthRangeKhz;
+    }
+
+    private AudioCodecAttributes(Parcel in) {
+        mBitrateKbps = in.readFloat();
+        mBitrateRangeKbps = new Range<>(in.readFloat(), in.readFloat());
+        mBandwidthKhz = in.readFloat();
+        mBandwidthRangeKhz = new Range<>(in.readFloat(), in.readFloat());
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeFloat(mBitrateKbps);
+        out.writeFloat(mBitrateRangeKbps.getLower());
+        out.writeFloat(mBitrateRangeKbps.getUpper());
+        out.writeFloat(mBandwidthKhz);
+        out.writeFloat(mBandwidthRangeKhz.getLower());
+        out.writeFloat(mBandwidthRangeKhz.getUpper());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Creator<AudioCodecAttributes> CREATOR =
+            new Creator<AudioCodecAttributes>() {
+                @Override
+                public AudioCodecAttributes createFromParcel(Parcel in) {
+                    return new AudioCodecAttributes(in);
+                }
+
+                @Override
+                public AudioCodecAttributes[] newArray(int size) {
+                    return new AudioCodecAttributes[size];
+                }
+            };
+
+    /**
+     * @return the exact value of the audio codec bitrate in kbps.
+     */
+    public float getBitrateKbps() {
+        return mBitrateKbps;
+    }
+
+    /**
+     * @return the range of the audio codec bitrate in kbps
+     */
+    public @NonNull Range<Float> getBitrateRangeKbps() {
+        return mBitrateRangeKbps;
+    }
+
+    /**
+     * @return the exact value of the audio codec bandwidth in kHz.
+     */
+    public float getBandwidthKhz() {
+        return mBandwidthKhz;
+    }
+
+    /**
+     * @return the range of the audio codec bandwidth in kHz.
+     */
+    public @NonNull Range<Float> getBandwidthRangeKhz() {
+        return mBandwidthRangeKhz;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "{ bitrateKbps=" + mBitrateKbps
+                + ", bitrateRangeKbps=" + mBitrateRangeKbps
+                + ", bandwidthKhz=" + mBandwidthKhz
+                + ", bandwidthRangeKhz=" + mBandwidthRangeKhz + " }";
+    }
+}
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 5b54719..9a55cec 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -29,6 +29,8 @@
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
+import android.telephony.ims.feature.MmTelFeature;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -38,7 +40,10 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * A Parcelable object to handle the IMS call profile, which provides the service, call type, and
@@ -445,6 +450,10 @@
     /** Indicates if we have known the intent of the user for the call is emergency */
     private boolean mHasKnownUserIntentEmergency = false;
 
+    private Set<RtpHeaderExtensionType> mOfferedRtpHeaderExtensionTypes = new ArraySet<>();
+
+    private Set<RtpHeaderExtensionType> mAcceptedRtpHeaderExtensionTypes = new ArraySet<>();
+
     /**
      * Extras associated with this {@link ImsCallProfile}.
      * <p>
@@ -683,6 +692,8 @@
         out.writeBoolean(mHasKnownUserIntentEmergency);
         out.writeInt(mRestrictCause);
         out.writeInt(mCallerNumberVerificationStatus);
+        out.writeArray(mOfferedRtpHeaderExtensionTypes.toArray());
+        out.writeArray(mAcceptedRtpHeaderExtensionTypes.toArray());
     }
 
     private void readFromParcel(Parcel in) {
@@ -697,9 +708,16 @@
         mHasKnownUserIntentEmergency = in.readBoolean();
         mRestrictCause = in.readInt();
         mCallerNumberVerificationStatus = in.readInt();
+        Object[] offered = in.readArray(RtpHeaderExtensionType.class.getClassLoader());
+        mOfferedRtpHeaderExtensionTypes = Arrays.stream(offered)
+                .map(o -> (RtpHeaderExtensionType) o).collect(Collectors.toSet());
+        Object[] accepted = in.readArray(RtpHeaderExtensionType.class.getClassLoader());
+        mAcceptedRtpHeaderExtensionTypes = Arrays.stream(accepted)
+                .map(o -> (RtpHeaderExtensionType) o).collect(Collectors.toSet());
     }
 
-    public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() {
+    public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR =
+            new Creator<ImsCallProfile>() {
         @Override
         public ImsCallProfile createFromParcel(Parcel in) {
             return new ImsCallProfile(in);
@@ -1086,4 +1104,66 @@
     public boolean hasKnownUserIntentEmergency() {
         return mHasKnownUserIntentEmergency;
     }
+
+    /**
+     * For an incoming or outgoing call, indicates the {@link RtpHeaderExtensionType}s which the
+     * caller is offering to make available.
+     * <p>
+     * For outgoing calls, an {@link ImsService} will reserve
+     * {@link RtpHeaderExtensionType#getLocalIdentifier()} identifiers the telephony stack has
+     * proposed to use and not use these same local identifiers.  The offered header extension
+     * types for an outgoing call can be found in the
+     * {@link ImsCallProfile#getOfferedRtpHeaderExtensionTypes()} and will be available to the
+     * {@link ImsService} in {@link MmTelFeature#createCallSession(ImsCallProfile)}.
+     * The {@link ImsService} sets the accepted {@link #setAcceptedRtpHeaderExtensionTypes(Set)}
+     * when the SDP offer/accept process has completed.
+     * <p>
+     * According to RFC8285, RTP header extensions available to a call are determined using the
+     * offer/accept phase of the SDP protocol (see RFC4566).
+     *
+     * @return the {@link RtpHeaderExtensionType}s which were offered by other end of the call.
+     */
+    public @NonNull Set<RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes() {
+        return mOfferedRtpHeaderExtensionTypes;
+    }
+
+    /**
+     * Sets the offered {@link RtpHeaderExtensionType}s for this call.
+     * <p>
+     * According to RFC8285, RTP header extensions available to a call are determined using the
+     * offer/accept phase of the SDP protocol (see RFC4566).
+     *
+     * @param rtpHeaderExtensions the {@link RtpHeaderExtensionType}s which are offered.
+     */
+    public void setOfferedRtpHeaderExtensionTypes(@NonNull Set<RtpHeaderExtensionType>
+                    rtpHeaderExtensions) {
+        mOfferedRtpHeaderExtensionTypes.clear();
+        mOfferedRtpHeaderExtensionTypes.addAll(rtpHeaderExtensions);
+    }
+
+    /**
+     * Gets the {@link RtpHeaderExtensionType}s which have been accepted by both ends of the call.
+     * <p>
+     * According to RFC8285, RTP header extensions available to a call are determined using the
+     * offer/accept phase of the SDP protocol (see RFC4566).
+     *
+     * @return the {@link RtpHeaderExtensionType}s which were accepted by the other end of the call.
+     */
+    public @NonNull Set<RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes() {
+        return mAcceptedRtpHeaderExtensionTypes;
+    }
+
+    /**
+     * Sets the accepted {@link RtpHeaderExtensionType}s for this call.
+     * <p>
+     * According to RFC8285, RTP header extensions available to a call are determined using the
+     * offer/accept phase of the SDP protocol (see RFC4566).
+     *
+     * @param rtpHeaderExtensions
+     */
+    public void setAcceptedRtpHeaderExtensionTypes(@NonNull Set<RtpHeaderExtensionType>
+            rtpHeaderExtensions) {
+        mAcceptedRtpHeaderExtensionTypes.clear();
+        mAcceptedRtpHeaderExtensionTypes.addAll(rtpHeaderExtensions);
+    }
 }
diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java
index 8857b9b..a3efb79 100755
--- a/telephony/java/android/telephony/ims/ImsCallSession.java
+++ b/telephony/java/android/telephony/ims/ImsCallSession.java
@@ -22,11 +22,16 @@
 import android.os.RemoteException;
 import android.telephony.CallQuality;
 import android.telephony.ims.aidl.IImsCallSessionListener;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsVideoCallProvider;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Provides the call initiation/termination, and media exchange between two IMS endpoints.
  * It directly communicates with IMS service which implements the IMS protocol behavior.
@@ -468,11 +473,31 @@
         }
 
         /**
+         * Informs the framework of a DTMF digit which was received from the network.
+         * <p>
+         * According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833 sec 3.10</a>,
+         * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to
+         * 12 ~ 15.
+         * @param digit the DTMF digit
+         */
+        public void callSessionDtmfReceived(char digit) {
+            // no-op
+        }
+
+        /**
          * Called when the IMS service reports a change to the call quality.
          */
         public void callQualityChanged(CallQuality callQuality) {
             // no-op
         }
+
+        /**
+         * Called when the IMS service reports incoming RTP header extension data.
+         */
+        public void callSessionRtpHeaderExtensionsReceived(
+                @NonNull Set<RtpHeaderExtension> extensions) {
+            // no-op
+        }
     }
 
     private final IImsCallSession miSession;
@@ -1119,6 +1144,31 @@
     }
 
     /**
+     * Requests that {@code rtpHeaderExtensions} are sent as a header extension with the next
+     * RTP packet sent by the IMS stack.
+     * <p>
+     * The {@link RtpHeaderExtensionType}s negotiated during SDP (Session Description Protocol)
+     * signalling determine the {@link RtpHeaderExtension}s which can be sent using this method.
+     * See RFC8285 for more information.
+     * <p>
+     * By specification, the RTP header extension is an unacknowledged transmission and there is no
+     * guarantee that the header extension will be delivered by the network to the other end of the
+     * call.
+     * @param rtpHeaderExtensions The header extensions to be included in the next RTP header.
+     */
+    public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
+        if (mClosed) {
+            return;
+        }
+
+        try {
+            miSession.sendRtpHeaderExtensions(
+                    new ArrayList<RtpHeaderExtension>(rtpHeaderExtensions));
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
      * A listener type for receiving notification on IMS call session events.
      * When an event is generated for an {@link IImsCallSession},
      * the application is notified by having one of the methods called on
@@ -1477,6 +1527,17 @@
         }
 
         /**
+         * DTMF digit received.
+         * @param dtmf The DTMF digit.
+         */
+        @Override
+        public void callSessionDtmfReceived(char dtmf) {
+            if (mListener != null) {
+                mListener.callSessionDtmfReceived(dtmf);
+            }
+        }
+
+        /**
          * Call quality updated
          */
         @Override
@@ -1485,6 +1546,19 @@
                 mListener.callQualityChanged(callQuality);
             }
         }
+
+        /**
+         * RTP header extension data received.
+         * @param extensions The header extension data.
+         */
+        @Override
+        public void callSessionRtpHeaderExtensionsReceived(
+                @NonNull List<RtpHeaderExtension> extensions) {
+            if (mListener != null) {
+                mListener.callSessionRtpHeaderExtensionsReceived(
+                        new ArraySet<RtpHeaderExtension>(extensions));
+            }
+        }
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index 2fdd195..86bb5d9 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -28,6 +28,10 @@
 
 import com.android.ims.internal.IImsCallSession;
 
+import java.util.ArrayList;
+import java.util.Objects;
+import java.util.Set;
+
 /**
  * Listener interface for notifying the Framework's {@link ImsCallSession} for updates to an ongoing
  * IMS call.
@@ -683,6 +687,59 @@
     }
 
     /**
+     * The {@link ImsService} calls this method to inform the framework of a DTMF digit which was
+     * received from the network.
+     * <p>
+     * According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833 sec 3.10</a>,
+     * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15.
+     * <p>
+     * <em>Note:</em> Alpha DTMF digits are converted from lower-case to upper-case.
+     *
+     * @param dtmf The DTMF digit received, '0'-'9', *, #, A, B, C, or D.
+     * @throws IllegalArgumentException If an invalid DTMF character is provided.
+     */
+    public void callSessionDtmfReceived(char dtmf) {
+        if (!(dtmf >= '0' && dtmf <= '9'
+                || dtmf >= 'A' && dtmf <= 'D'
+                || dtmf >= 'a' && dtmf <= 'd'
+                || dtmf == '*'
+                || dtmf == '#')) {
+            throw new IllegalArgumentException("DTMF digit must be 0-9, *, #, A, B, C, D");
+        }
+        try {
+            mListener.callSessionDtmfReceived(Character.toUpperCase(dtmf));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * The {@link ImsService} calls this method to inform the framework of RTP header extension data
+     * which was received from the network.
+     * <p>
+     * The set of {@link RtpHeaderExtension} data are identified by local identifiers which were
+     * negotiated during SDP signalling.  See RFC8285,
+     * {@link ImsCallProfile#getAcceptedRtpHeaderExtensionTypes()} and
+     * {@link RtpHeaderExtensionType} for more information.
+     * <p>
+     * By specification, the RTP header extension is an unacknowledged transmission and there is no
+     * guarantee that the header extension will be delivered by the network to the other end of the
+     * call.
+     *
+     * @param extensions The RTP header extension data received.
+     */
+    public void callSessionRtpHeaderExtensionsReceived(
+            @NonNull Set<RtpHeaderExtension> extensions) {
+        Objects.requireNonNull(extensions, "extensions are required.");
+        try {
+            mListener.callSessionRtpHeaderExtensionsReceived(
+                    new ArrayList<RtpHeaderExtension>(extensions));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Notifies the result of transfer request.
      * @hide
      */
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index a7586ec..5a32075 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -29,12 +29,10 @@
 import android.provider.Settings;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsController;
 import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.util.Log;
 
@@ -77,7 +75,7 @@
             "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
 
     /**
-     * Receives RCS availability status updates from the ImsService.
+     * Receives RCS Feature availability status updates from the ImsService.
      *
      * @see #isAvailable(int)
      * @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
@@ -101,8 +99,7 @@
 
                 final long callingIdentity = Binder.clearCallingIdentity();
                 try {
-                    mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(
-                            new RcsFeature.RcsImsCapabilities(config)));
+                    mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(config));
                 } finally {
                     restoreCallingIdentity(callingIdentity);
                 }
@@ -137,7 +134,7 @@
          *
          * @param capabilities The new availability of the capabilities.
          */
-        public void onAvailabilityChanged(@NonNull RcsFeature.RcsImsCapabilities capabilities) {
+        public void onAvailabilityChanged(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
         }
 
         /**@hide*/
@@ -394,7 +391,7 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+    public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
         if (imsRcsController == null) {
@@ -428,7 +425,7 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+    public boolean isAvailable(@RcsUceAdapter.RcsImsCapabilityFlag int capability)
             throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
         if (imsRcsController == null) {
diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
index 2792f79..d924bae 100644
--- a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
+++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
@@ -17,6 +17,7 @@
 package android.telephony.ims;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -90,6 +91,9 @@
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public int mAudioDirection;
+    // Audio codec attributes
+    private AudioCodecAttributes mAudioCodecAttributes;
+
     // Video related information
     /** @hide */
     public int mVideoQuality;
@@ -191,6 +195,7 @@
     public void copyFrom(ImsStreamMediaProfile profile) {
         mAudioQuality = profile.mAudioQuality;
         mAudioDirection = profile.mAudioDirection;
+        mAudioCodecAttributes = profile.mAudioCodecAttributes;
         mVideoQuality = profile.mVideoQuality;
         mVideoDirection = profile.mVideoDirection;
         mRttMode = profile.mRttMode;
@@ -199,12 +204,13 @@
     @NonNull
     @Override
     public String toString() {
-        return "{ audioQuality=" + mAudioQuality +
-                ", audioDirection=" + mAudioDirection +
-                ", videoQuality=" + mVideoQuality +
-                ", videoDirection=" + mVideoDirection +
-                ", rttMode=" + mRttMode +
-                ", hasRttAudioSpeech=" + mIsReceivingRttAudio + " }";
+        return "{ audioQuality=" + mAudioQuality
+                + ", audioDirection=" + mAudioDirection
+                + ", audioCodecAttribute=" + mAudioCodecAttributes
+                + ", videoQuality=" + mVideoQuality
+                + ", videoDirection=" + mVideoDirection
+                + ", rttMode=" + mRttMode
+                + ", hasRttAudioSpeech=" + mIsReceivingRttAudio + " }";
     }
 
     @Override
@@ -216,6 +222,7 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mAudioQuality);
         out.writeInt(mAudioDirection);
+        out.writeTypedObject(mAudioCodecAttributes, flags);
         out.writeInt(mVideoQuality);
         out.writeInt(mVideoDirection);
         out.writeInt(mRttMode);
@@ -225,6 +232,7 @@
     private void readFromParcel(Parcel in) {
         mAudioQuality = in.readInt();
         mAudioDirection = in.readInt();
+        mAudioCodecAttributes = in.readTypedObject(AudioCodecAttributes.CREATOR);
         mVideoQuality = in.readInt();
         mVideoDirection = in.readInt();
         mRttMode = in.readInt();
@@ -275,6 +283,23 @@
         return mAudioDirection;
     }
 
+    /**
+     * Get the audio codec attributes {@link AudioCodecAttributes} which may be {@code null} if
+     * ImsService doesn't support this information.
+     * @return audio codec attributes
+     */
+    public @Nullable AudioCodecAttributes getAudioCodecAttributes() {
+        return mAudioCodecAttributes;
+    }
+
+    /**
+     * Set the audio codec attributes {@link AudioCodecAttributes} which includes bitrate and
+     * bandwidth information.
+     */
+    public void setAudioCodecAttributes(@NonNull AudioCodecAttributes audioCodecAttributes) {
+        mAudioCodecAttributes = audioCodecAttributes;
+    }
+
     public int getVideoQuality() {
         return mVideoQuality;
     }
diff --git a/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl
new file mode 100644
index 0000000..cd1ee84
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+
+package android.telephony.ims;
+
+parcelable RcsContactTerminatedReason;
diff --git a/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java
new file mode 100644
index 0000000..ee02564
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * When the resource for the presence subscribe event has been terminated, the method
+ * SubscribeResponseCallback#onResourceTerminated wil be called with a list of
+ * RcsContactTerminatedReason.
+ * @hide
+ */
+public final class RcsContactTerminatedReason implements Parcelable {
+    private final Uri mContactUri;
+    private final String mReason;
+
+    public RcsContactTerminatedReason(Uri contact, String reason) {
+        mContactUri = contact;
+        mReason = reason;
+    }
+
+    private RcsContactTerminatedReason(Parcel in) {
+        mContactUri = in.readParcelable(Uri.class.getClassLoader());
+        mReason = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeParcelable(mContactUri, flags);
+        out.writeString(mReason);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Creator<RcsContactTerminatedReason> CREATOR =
+            new Creator<RcsContactTerminatedReason>() {
+                @Override
+                public RcsContactTerminatedReason createFromParcel(Parcel in) {
+                    return new RcsContactTerminatedReason(in);
+                }
+
+                @Override
+                public RcsContactTerminatedReason[] newArray(int size) {
+                    return new RcsContactTerminatedReason[size];
+                }
+            };
+
+    public Uri getContactUri() {
+        return mContactUri;
+    }
+
+    public String getReason() {
+        return mReason;
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index c2ddcea..0aeaecc 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -47,6 +47,30 @@
     private static final String TAG = "RcsUceAdapter";
 
     /**
+     * This carrier supports User Capability Exchange as, defined by the framework using
+     * SIP OPTIONS. If set, the RcsFeature should support capability exchange. If not set, this
+     * RcsFeature should not publish capabilities or service capability requests.
+     * @hide
+     */
+    public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0;
+
+    /**
+     * This carrier supports User Capability Exchange as, defined by the framework using a
+     * presence server. If set, the RcsFeature should support capability exchange. If not set, this
+     * RcsFeature should not publish capabilities or service capability requests.
+     * @hide
+     */
+    public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "CAPABILITY_TYPE_", value = {
+            CAPABILITY_TYPE_OPTIONS_UCE,
+            CAPABILITY_TYPE_PRESENCE_UCE
+    })
+    public @interface RcsImsCapabilityFlag {}
+
+    /**
      * An unknown error has caused the request to fail.
      * @hide
      */
@@ -106,11 +130,6 @@
      * @hide
      */
     public static final int ERROR_LOST_NETWORK = 12;
-    /**
-     * The request has failed because the same request has already been added to the queue.
-     * @hide
-     */
-    public static final int ERROR_ALREADY_IN_QUEUE = 13;
 
     /**@hide*/
     @Retention(RetentionPolicy.SOURCE)
@@ -125,12 +144,90 @@
             ERROR_REQUEST_TOO_LARGE,
             ERROR_REQUEST_TIMEOUT,
             ERROR_INSUFFICIENT_MEMORY,
-            ERROR_LOST_NETWORK,
-            ERROR_ALREADY_IN_QUEUE
+            ERROR_LOST_NETWORK
     })
     public @interface ErrorCode {}
 
     /**
+     * A capability update has been requested due to the Entity Tag (ETag) expiring.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0;
+    /**
+     * A capability update has been requested due to moving to LTE with VoPS disabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1;
+    /**
+     * A capability update has been requested due to moving to LTE with VoPS enabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2;
+    /**
+     * A capability update has been requested due to moving to eHRPD.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3;
+    /**
+     * A capability update has been requested due to moving to HSPA+.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4;
+    /**
+     * A capability update has been requested due to moving to 3G.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5;
+    /**
+     * A capability update has been requested due to moving to 2G.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6;
+    /**
+     * A capability update has been requested due to moving to WLAN
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7;
+    /**
+     * A capability update has been requested due to moving to IWLAN
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8;
+    /**
+     * A capability update has been requested but the reason is unknown.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 9;
+    /**
+     * A capability update has been requested due to moving to 5G NR with VoPS disabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10;
+    /**
+     * A capability update has been requested due to moving to 5G NR with VoPS enabled.
+     * @hide
+     */
+    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "ERROR_", value = {
+            CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN,
+            CAPABILITY_UPDATE_TRIGGER_UNKNOWN,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED,
+            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED
+    })
+    public @interface StackPublishTriggerType {}
+
+    /**
      * The last publish has resulted in a "200 OK" response or the device is using SIP OPTIONS for
      * UCE.
      * @hide
@@ -238,38 +335,49 @@
     }
 
     /**
-     * Provides a one-time callback for the response to a UCE request. After this callback is called
-     * by the framework, the reference to this callback will be discarded on the service side.
+     * A callback for the response to a UCE request. The method
+     * {@link CapabilitiesCallback#onCapabilitiesReceived} will be called zero or more times as the
+     * capabilities are received for each requested contact.
+     * <p>
+     * This request will take a varying amount of time depending on if the contacts requested are
+     * cached or if it requires a network query. The timeout time of these requests can vary
+     * depending on the network, however in poor cases it could take up to a minute for a request
+     * to timeout. In that time only a subset of capabilities may have been retrieved.
+     * <p>
+     * After {@link CapabilitiesCallback#onComplete} or {@link CapabilitiesCallback#onError} has
+     * been called, the reference to this callback will be discarded on the service side.
      * @see #requestCapabilities(Executor, List, CapabilitiesCallback)
      * @hide
      */
-    public static class CapabilitiesCallback {
+    public interface CapabilitiesCallback {
 
         /**
-         * Notify this application that the pending capability request has returned successfully.
+         * Notify this application that the pending capability request has returned successfully
+         * for one or more of the requested contacts.
          * @param contactCapabilities List of capabilities associated with each contact requested.
          */
-        public void onCapabilitiesReceived(
-                @NonNull List<RcsContactUceCapability> contactCapabilities) {
+        void onCapabilitiesReceived(@NonNull List<RcsContactUceCapability> contactCapabilities);
 
-        }
+        /**
+         * The pending request has completed successfully due to all requested contacts information
+         * being delivered.
+         */
+        void onComplete();
 
         /**
          * The pending request has resulted in an error and may need to be retried, depending on the
          * error code.
          * @param errorCode The reason for the framework being unable to process the request.
          */
-        public void onError(@ErrorCode int errorCode) {
-
-        }
+        void onError(@ErrorCode int errorCode);
     }
 
     private final Context mContext;
     private final int mSubId;
 
     /**
-     * Not to be instantiated directly, use
-     * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
+     * Not to be instantiated directly, use {@link ImsRcsManager#getUceAdapter()} to instantiate
+     * this manager class.
      * @hide
      */
     RcsUceAdapter(Context context, int subId) {
@@ -280,6 +388,9 @@
     /**
      * Request the User Capability Exchange capabilities for one or more contacts.
      * <p>
+     * This will return the cached capabilities of the contact and will not perform a capability
+     * poll on the network unless there are contacts being queried with stale information.
+     * <p>
      * Be sure to check the availability of this feature using
      * {@link ImsRcsManager#isAvailable(int)} and ensuring
      * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
@@ -302,7 +413,7 @@
             @NonNull List<Uri> contactNumbers,
             @NonNull CapabilitiesCallback c) throws ImsException {
         if (c == null) {
-            throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
+            throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
         }
         if (executor == null) {
             throw new IllegalArgumentException("Must include a non-null Executor.");
@@ -330,6 +441,15 @@
                 }
             }
             @Override
+            public void onComplete() {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onComplete());
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
             public void onError(int errorCode) {
                 final long callingIdentity = Binder.clearCallingIdentity();
                 try {
@@ -351,6 +471,88 @@
     }
 
     /**
+     * Ignore the device cache and perform a capability discovery for one contact, also called
+     * "availability fetch."
+     * <p>
+     * This will always perform a query to the network as long as requests are over the carrier
+     * availability fetch throttling threshold. If too many network requests are sent too quickly,
+     * #ERROR_TOO_MANY_REQUESTS will be returned.
+     *
+     * <p>
+     * Be sure to check the availability of this feature using
+     * {@link ImsRcsManager#isAvailable(int)} and ensuring
+     * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
+     * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is
+     * enabled or else this operation will fail with
+     * {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
+     *
+     * @param contactNumber The contact of the capabilities is being requested for.
+     * @param c A one-time callback for when the request for capabilities completes or there is
+     * an error processing the request.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void requestNetworkAvailability(@NonNull @CallbackExecutor Executor executor,
+            @NonNull Uri contactNumber, @NonNull CapabilitiesCallback c) throws ImsException {
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        if (contactNumber == null) {
+            throw new IllegalArgumentException("Must include non-null contact number.");
+        }
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
+        }
+
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "requestNetworkAvailability: IImsRcsController is null");
+            throw new ImsException("Cannot find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
+            @Override
+            public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() ->
+                            c.onCapabilitiesReceived(contactCapabilities));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
+            public void onComplete() {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onComplete());
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+            @Override
+            public void onError(int errorCode) {
+                final long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onError(errorCode));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+        };
+
+        try {
+            imsRcsController.requestNetworkAvailability(mSubId, mContext.getOpPackageName(),
+                    mContext.getAttributionTag(), contactNumber, internalCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#requestNetworkAvailability", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+    }
+
+    /**
      * Gets the last publish result from the UCE service if the device is using an RCS presence
      * server.
      * @return The last publish result from the UCE service. If the device is using SIP OPTIONS,
diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtension.aidl b/telephony/java/android/telephony/ims/RtpHeaderExtension.aidl
new file mode 100644
index 0000000..cbf79d3
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RtpHeaderExtension.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims;
+
+parcelable RtpHeaderExtension;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtension.java b/telephony/java/android/telephony/ims/RtpHeaderExtension.java
new file mode 100644
index 0000000..f9ab701
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RtpHeaderExtension.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A representation of an RTP header extension.
+ * <p>
+ * Per RFC8285, an RTP header extension consists of both a local identifier in the range 1-14, an
+ * 8-bit length indicator and a number of extension data bytes equivalent to the stated length.
+ * @hide
+ */
+@SystemApi
+public final class RtpHeaderExtension implements Parcelable {
+    private int mLocalIdentifier;
+    private byte[] mExtensionData;
+
+    /**
+     * Creates a new {@link RtpHeaderExtension}.
+     * @param localIdentifier The local identifier for this RTP header extension.
+     * @param extensionData The data for this RTP header extension.
+     * @throws IllegalArgumentException if {@code extensionId} is not in the range 1-14.
+     * @throws NullPointerException if {@code extensionData} is null.
+     */
+    public RtpHeaderExtension(@IntRange(from = 1, to = 14) int localIdentifier,
+            @NonNull byte[] extensionData) {
+        if (localIdentifier < 1 || localIdentifier > 13) {
+            throw new IllegalArgumentException("localIdentifier must be in range 1-14");
+        }
+        if (extensionData == null) {
+            throw new NullPointerException("extensionDa is required.");
+        }
+        mLocalIdentifier = localIdentifier;
+        mExtensionData = extensionData;
+    }
+
+    /**
+     * Creates a new instance of {@link RtpHeaderExtension} from a parcel.
+     * @param in The parceled data to read.
+     */
+    private RtpHeaderExtension(@NonNull Parcel in) {
+        mLocalIdentifier = in.readInt();
+        mExtensionData = in.createByteArray();
+    }
+
+    /**
+     * The local identifier for the RTP header extension.
+     * <p>
+     * Per RFC8285, the extension ID is a value in the range 1-14 (0 is reserved for padding and
+     * 15 is reserved for the one-byte header form.
+     * <p>
+     * Within the current call, this extension ID will match one of the
+     * {@link RtpHeaderExtensionType#getLocalIdentifier()}s.
+     *
+     * @return The local identifier for this RTP header extension.
+     */
+    @IntRange(from = 1, to = 14)
+    public int getLocalIdentifier() {
+        return mLocalIdentifier;
+    }
+
+    /**
+     * The data payload for the RTP header extension.
+     * <p>
+     * Per RFC8285 Sec 4.3, an RTP header extension includes an 8-bit length field which indicate
+     * how many bytes of data are present in the RTP header extension.  The extension includes this
+     * many bytes of actual data.
+     * <p>
+     * We represent this as a byte array who's length is equivalent to the 8-bit length field.
+     * @return RTP header extension data payload.  The payload may be up to 255 bytes in length.
+     */
+    public @NonNull byte[] getExtensionData() {
+        return mExtensionData;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mLocalIdentifier);
+        dest.writeByteArray(mExtensionData);
+    }
+
+    public static final @NonNull Creator<RtpHeaderExtension> CREATOR =
+            new Creator<RtpHeaderExtension>() {
+                @Override
+                public RtpHeaderExtension createFromParcel(@NonNull Parcel in) {
+                    return new RtpHeaderExtension(in);
+                }
+
+                @Override
+                public RtpHeaderExtension[] newArray(int size) {
+                    return new RtpHeaderExtension[size];
+                }
+            };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RtpHeaderExtension that = (RtpHeaderExtension) o;
+        return mLocalIdentifier == that.mLocalIdentifier
+                && Arrays.equals(mExtensionData, that.mExtensionData);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(mLocalIdentifier);
+        result = 31 * result + Arrays.hashCode(mExtensionData);
+        return result;
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtensionType.aidl b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.aidl
new file mode 100644
index 0000000..3e62fff
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims;
+
+parcelable RtpHeaderExtensionType;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java
new file mode 100644
index 0000000..e1d39c2
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Defines a mapping between a local identifier and a {@link Uri} which identifies an RTP header
+ * extension.
+ * <p>
+ * According to RFC8285, SDP (Session Description Protocol) signalling for a call provides a means
+ * for the supported RTP header extensions for a call to be negotiated at call initiation time.
+ * The types of RTP header extensions potentially usable in a session are identified by a local
+ * identifier ({@link #getLocalIdentifier()}) when RTP header extensions are present on RTP packets.
+ * A {@link Uri} ({@link #getUri()}) provides a unique identifier for the RTP header extension
+ * format which parties in a call can use to identify supported RTP header extensions.
+ * @hide
+ */
+@SystemApi
+public final class RtpHeaderExtensionType implements Parcelable {
+    private int mLocalIdentifier;
+    private Uri mUri;
+
+    /**
+     * Create a new RTP header extension type.
+     * @param localIdentifier the local identifier.
+     * @param uri the {@link Uri} identifying the RTP header extension type.
+     * @throws IllegalArgumentException if {@code localIdentifier} is out of the expected range.
+     * @throws NullPointerException if {@code uri} is null.
+     */
+    public RtpHeaderExtensionType(@IntRange(from = 1, to = 14) int localIdentifier,
+            @NonNull Uri uri) {
+        if (localIdentifier < 1 || localIdentifier > 13) {
+            throw new IllegalArgumentException("localIdentifier must be in range 1-14");
+        }
+        if (uri == null) {
+            throw new NullPointerException("uri is required.");
+        }
+        mLocalIdentifier = localIdentifier;
+        mUri = uri;
+    }
+
+    private RtpHeaderExtensionType(Parcel in) {
+        mLocalIdentifier = in.readInt();
+        mUri = in.readParcelable(Uri.class.getClassLoader());
+    }
+
+    public static final @NonNull Creator<RtpHeaderExtensionType> CREATOR =
+            new Creator<RtpHeaderExtensionType>() {
+                @Override
+                public RtpHeaderExtensionType createFromParcel(@NonNull Parcel in) {
+                    return new RtpHeaderExtensionType(in);
+                }
+
+                @Override
+                public @NonNull RtpHeaderExtensionType[] newArray(int size) {
+                    return new RtpHeaderExtensionType[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mLocalIdentifier);
+        dest.writeParcelable(mUri, flags);
+    }
+
+    /**
+     * The local identifier for this RTP header extension type.
+     * <p>
+     * {@link RtpHeaderExtension}s which indicate a {@link RtpHeaderExtension#getLocalIdentifier()}
+     * matching this local identifier will have the format specified by {@link #getUri()}.
+     * <p>
+     * Per RFC8285, the extension ID is a value in the range 1-14 (0 is reserved for padding and
+     * 15 is reserved for the one-byte header form.
+     *
+     * @return The local identifier associated with this {@link #getUri()}.
+     */
+    public @IntRange(from = 1, to = 14) int getLocalIdentifier() {
+        return mLocalIdentifier;
+    }
+
+    /**
+     * A {@link Uri} which identifies the format of the RTP extension header.
+     * <p>
+     * According to RFC8285 section 5, URIs MUST be absolute and SHOULD contain a month/date pair
+     * in the form mmyyyy to indicate versioning of the extension.  Extension headers defined in an
+     * RFC are typically defined using URNs starting with {@code urn:ietf:params:rtp-hdrext:}.
+     * For example, RFC6464 defines {@code urn:ietf:params:rtp-hdrext:ssrc-audio-level} which is an
+     * RTP header extension for communicating client to mixer audio level indications.
+     *
+     * @return A unique {@link Uri} identifying the format of the RTP extension header.
+     */
+    public @NonNull Uri getUri() {
+        return mUri;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RtpHeaderExtensionType that = (RtpHeaderExtensionType) o;
+        return mLocalIdentifier == that.mLocalIdentifier
+                && mUri.equals(that.mUri);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mLocalIdentifier, mUri);
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
new file mode 100644
index 0000000..a4ffbef
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.aidl.IOptionsRequestCallback;
+
+import java.util.List;
+
+/**
+ * Listener interface for the ImsService to use to notify the framework of UCE events.
+ * {@hide}
+ */
+oneway interface ICapabilityExchangeEventListener {
+    /**
+     * Trigger the framework to provide a capability update using
+     * {@link RcsCapabilityExchangeImplBase#publishCapabilities}.
+     * <p>
+     * This is typically used when trying to generate an initial PUBLISH for a new
+     * subscription to the network. The device will cache all presence publications
+     * after boot until this method is called the first time.
+     * @param publishTriggerType {@link StackPublishTriggerType} The reason for the
+     * capability update request.
+     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is
+     * not currently connected to the framework. This can happen if the
+     * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+     * {@link RcsFeature} has not received the
+     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
+     * cases when the Telephony stack has crashed.
+     */
+    void onRequestPublishCapabilities(int publishTriggerType);
+
+    /**
+     * Notify the framework that the device's capabilities have been unpublished from the network.
+     *
+     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
+     * connected to the framework. This can happen if the {@link RcsFeature} is not
+     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
+     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
+     * Telephony stack has crashed.
+     */
+    void onUnpublish();
+
+    /**
+     * Inform the framework of a query for this device's UCE capabilities.
+     * <p>
+     * The framework will respond via the
+     * {@link IOptionsRequestCallback#respondToCapabilityRequest} or
+     * {@link IOptionsRequestCallback#respondToCapabilityRequestWithError} method.
+     * @param contactUri The URI associated with the remote contact that is requesting capabilities.
+     * @param remoteCapabilities The remote contact's capability information.
+     * @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not currently
+     * connected to the framework. This can happen if the {@link RcsFeature} is not
+     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+     * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when
+     * the Telephony stack has crashed.
+     */
+    void onRemoteCapabilityRequest(in Uri contactUri,
+            in List<String> remoteCapabilities,
+            IOptionsRequestCallback cb);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
index 36d2067..ed895b7 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
@@ -21,9 +21,12 @@
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsConferenceState;
+import android.telephony.ims.RtpHeaderExtension;
 import com.android.ims.internal.IImsCallSession;
 import android.telephony.ims.ImsSuppServiceNotification;
 
+import java.util.List;
+
 /**
  * A listener type for receiving notification on IMS call session events.
  * When an event is generated for an {@link IImsCallSession}, the application is notified
@@ -153,9 +156,17 @@
     void callSessionTransferred();
     void callSessionTransferFailed(in ImsReasonInfo reasonInfo);
 
+    void callSessionDtmfReceived(char dtmf);
+
     /**
      * Notifies of a change to the call quality.
      * @param callQuality then updated call quality
      */
     void callQualityChanged(in CallQuality callQuality);
+
+    /**
+     * Notifies of incoming RTP header extensions from the network.
+     * @param extensions the RTP header extensions received.
+     */
+    void callSessionRtpHeaderExtensionsReceived(in List<RtpHeaderExtension> extensions);
 }
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
index 6d25a09..8e84e93 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -47,6 +47,9 @@
     // ImsUceAdapter specific
     void requestCapabilities(int subId, String callingPackage, String callingFeatureId,
             in List<Uri> contactNumbers, IRcsUceControllerCallback c);
+    void requestNetworkAvailability(int subId, String callingPackage,
+            String callingFeatureId, in Uri contactNumber,
+            IRcsUceControllerCallback c);
     int getUcePublishState(int subId);
     boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId);
     void setUceSettingEnabled(int subId, boolean isEnabled);
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
index 4b98b79..b47e3c7 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
@@ -18,8 +18,12 @@
 
 import android.net.Uri;
 import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IOptionsResponseCallback;
+import android.telephony.ims.aidl.IPublishResponseCallback;
 import android.telephony.ims.aidl.IRcsFeatureListener;
+import android.telephony.ims.aidl.ISubscribeResponseCallback;
 import android.telephony.ims.feature.CapabilityChangeRequest;
 
 import java.util.List;
@@ -40,6 +44,12 @@
             IImsCapabilityCallback c);
     oneway void queryCapabilityConfiguration(int capability, int radioTech,
             IImsCapabilityCallback c);
+    // RcsCapabilityExchangeImplBase specific api
+    oneway void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener);
+    oneway void publishCapabilities(in String pidfXml, IPublishResponseCallback cb);
+    oneway void subscribeForCapabilities(in List<Uri> uris, ISubscribeResponseCallback cb);
+    oneway void sendOptionsCapabilityRequest(in Uri contactUri,
+            in List<String> myCapabilities, IOptionsResponseCallback cb);
     // RcsPresenceExchangeImplBase specific api
     oneway void requestCapabilities(in List<Uri> uris, int operationToken);
     oneway void updateCapabilities(in RcsContactUceCapability capabilities, int operationToken);
@@ -50,4 +60,4 @@
             in RcsContactUceCapability ownCapabilities, int operationToken);
     oneway void respondToCapabilityRequestWithError(in Uri contactUri, int code, in String reason,
             int operationToken);
-}
\ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl b/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl
new file mode 100644
index 0000000..d55670d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IOptionsRequestCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.telephony.ims.RcsContactUceCapability;
+
+/**
+ * Interface used by the framework to respond to OPTIONS requests.
+ * {@hide}
+ */
+oneway interface IOptionsRequestCallback {
+    /**
+     * Respond to a remote capability request from the contact specified with the capabilities
+     * of this device.
+     * @param ownCapabilities The capabilities of this device.
+     */
+    void respondToCapabilityRequest(in RcsContactUceCapability ownCapabilities);
+
+    /**
+     * Respond to a remote capability request from the contact specified with the
+     * specified error.
+     * @param contactUri A URI containing the remote contact.
+     * @param code The SIP response code to respond with.
+     * @param reason A non-null String containing the reason associated with the SIP code.
+     */
+    void respondToCapabilityRequestWithError(int code, String reason);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt b/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
copy to telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
index 24768cd..a8c8329 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
+++ b/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
@@ -13,17 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
 
-import android.annotation.DimenRes
-import android.annotation.UserIdInt
+package android.telephony.ims.aidl;
 
-data class BubbleEntity(
-    @UserIdInt val userId: Int,
-    val packageName: String,
-    val shortcutId: String,
-    val key: String,
-    val desiredHeight: Int,
-    @DimenRes val desiredHeightResId: Int,
-    val title: String? = null
-)
+import java.util.List;
+
+/**
+ * Interface used by the framework to receive the response from the remote user
+ * through {@link RcsCapabilityExchangeImplBase#sendOptionsCapabilityRequest}
+ * {@hide}
+ */
+oneway interface IOptionsResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, String reason, in List<String> theirCaps);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
similarity index 62%
copy from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
copy to telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
index 24768cd..481e7f8 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
+++ b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
@@ -13,17 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
 
-import android.annotation.DimenRes
-import android.annotation.UserIdInt
+package android.telephony.ims.aidl;
 
-data class BubbleEntity(
-    @UserIdInt val userId: Int,
-    val packageName: String,
-    val shortcutId: String,
-    val key: String,
-    val desiredHeight: Int,
-    @DimenRes val desiredHeightResId: Int,
-    val title: String? = null
-)
+import java.util.List;
+
+/**
+ * Interface used by the framework to receive the response of the publish
+ * request through {@link RcsCapabilityExchangeImplBase#publishCapabilities}
+ * {@hide}
+ */
+oneway interface IPublishResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, String reason);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
index 5975930..0bd3e5e 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
@@ -25,5 +25,6 @@
  */
 oneway interface IRcsUceControllerCallback {
     void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities);
+    void onComplete();
     void onError(int errorCode);
 }
diff --git a/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
new file mode 100644
index 0000000..4deaba1
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/ISubscribeResponseCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.RcsContactTerminatedReason;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Interface used by the framework to receive the response of the subscribe
+ * request through {@link RcsCapabilityExchangeImplBase#subscribeForCapabilities}
+ * {@hide}
+ */
+oneway interface ISubscribeResponseCallback {
+    void onCommandError(int code);
+    void onNetworkResponse(int code, in String reason);
+    void onNotifyCapabilitiesUpdate(in List<String> pidfXmls);
+    void onResourceTerminated(in List<RcsContactTerminatedReason> uriTerminatedReason);
+    void onTerminated(in String reason, in String retryAfter);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java
new file mode 100644
index 0000000..47a96af
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsOptionsResponseAidlWrapper.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback;
+
+import java.util.List;
+
+/**
+ * Implementation of the callback OptionsResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsOptionsResponseAidlWrapper implements OptionsResponseCallback {
+
+    private final IOptionsResponseCallback mResponseBinder;
+
+    public RcsOptionsResponseAidlWrapper(IOptionsResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason, List<String> theirCaps)
+            throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason, theirCaps);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
new file mode 100644
index 0000000..22985d0
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsPublishResponseAidlWrapper.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback;
+
+/**
+ * Implementation of the callback PublishResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsPublishResponseAidlWrapper implements PublishResponseCallback {
+
+    private final IPublishResponseCallback mResponseBinder;
+
+    public RcsPublishResponseAidlWrapper(IPublishResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason) throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
new file mode 100644
index 0000000..37588ed
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/RcsSubscribeResponseAidlWrapper.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.os.RemoteException;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.RcsContactTerminatedReason;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of the callback OptionsResponseCallback by wrapping the internal AIDL from
+ * telephony.
+ * @hide
+ */
+public class RcsSubscribeResponseAidlWrapper implements SubscribeResponseCallback {
+
+    private final ISubscribeResponseCallback mResponseBinder;
+
+    public RcsSubscribeResponseAidlWrapper(ISubscribeResponseCallback responseBinder) {
+        mResponseBinder = responseBinder;
+    }
+
+    @Override
+    public void onCommandError(int code) {
+        try {
+            mResponseBinder.onCommandError(code);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNetworkResponse(int code, String reason) throws ImsException {
+        try {
+            mResponseBinder.onNetworkResponse(code, reason);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onNotifyCapabilitiesUpdate(List<String> pidfXmls) throws ImsException {
+        try {
+            mResponseBinder.onNotifyCapabilitiesUpdate(pidfXmls);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
+    public void onResourceTerminated(List<Pair<Uri, String>> uriTerminatedReason)
+            throws ImsException {
+        try {
+            mResponseBinder.onResourceTerminated(getTerminatedReasonList(uriTerminatedReason));
+        } catch (RemoteException e) {
+        }
+    }
+
+    private List<RcsContactTerminatedReason> getTerminatedReasonList(
+            List<Pair<Uri, String>> uriTerminatedReason) {
+        List<RcsContactTerminatedReason> uriTerminatedReasonList = new ArrayList<>();
+        if (uriTerminatedReason != null) {
+            for (Pair<Uri, String> pair : uriTerminatedReason) {
+                RcsContactTerminatedReason reason =
+                        new RcsContactTerminatedReason(pair.first, pair.second);
+                uriTerminatedReasonList.add(reason);
+            }
+        }
+        return uriTerminatedReasonList;
+    }
+
+    @Override
+    public void onTerminated(String reason, String retryAfter) throws ImsException {
+        try {
+            mResponseBinder.onTerminated(reason, retryAfter);
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
index 4b8f398..8dcd711 100755
--- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
@@ -30,11 +30,14 @@
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.ImsSuppServiceNotification;
+import android.telephony.ims.RtpHeaderExtension;
 import android.telephony.ims.aidl.IImsCallSessionListener;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsVideoCallProvider;
 
+import java.util.List;
+
 /**
  * Compat implementation of ImsCallSessionImplBase for older implementations.
  *
@@ -405,6 +408,15 @@
     }
 
     /**
+     * Device sends RTP header extensions.
+     * @param headerExtensions The header extensions to send.
+     */
+    @Override
+    public void sendRtpHeaderExtensions(@NonNull List<RtpHeaderExtension> headerExtensions) {
+        // no-op; not supported in compat layer.
+    }
+
+    /**
      * There are two different ImsCallSessionListeners that need to reconciled here, we need to
      * convert the "old" version of the com.android.ims.internal.IImsCallSessionListener to the
      * "new" version of the Listener android.telephony.ims.ImsCallSessionListener when calling
diff --git a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
index 87a5094..87a6873 100644
--- a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
+++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
@@ -28,8 +28,8 @@
 import java.util.Set;
 
 /**
- * Request to send to IMS provider, which will try to enable/disable capabilities that are added to
- * the request.
+ * Used by the framework to enable and disable MMTEL and RCS capabilities. See
+ * MmTelFeature#changeEnabledCapabilities and RcsFeature#changeEnabledCapabilities.
  * {@hide}
  */
 @SystemApi
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index b8ae146..5de2ddc 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -23,12 +23,22 @@
 import android.net.Uri;
 import android.os.RemoteException;
 import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IOptionsResponseCallback;
+import android.telephony.ims.aidl.IPublishResponseCallback;
 import android.telephony.ims.aidl.IRcsFeatureListener;
+import android.telephony.ims.aidl.ISubscribeResponseCallback;
+import android.telephony.ims.aidl.RcsOptionsResponseAidlWrapper;
+import android.telephony.ims.aidl.RcsPublishResponseAidlWrapper;
+import android.telephony.ims.aidl.RcsSubscribeResponseAidlWrapper;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
-import android.telephony.ims.stub.RcsSipOptionsImplBase;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback;
 import android.util.Log;
 
 import com.android.internal.telephony.util.TelephonyUtils;
@@ -64,9 +74,14 @@
             mExecutor = executor;
         }
 
+        /**
+         * @deprecated This method is deprecated. Please call the method
+         * setCapabilityExchangeEventListener instead.
+         */
         @Override
+        @Deprecated
         public void setListener(IRcsFeatureListener listener) {
-            mReference.setListener(listener);
+            Log.w(LOG_TAG, "The method setListener is deprecated");
         }
 
         @Override
@@ -106,44 +121,66 @@
             return executeMethodAsyncForResult(mReference::getFeatureState, "getFeatureState");
         }
 
+        // RcsCapabilityExchangeImplBase specific APIs
+        @Override
+        public void setCapabilityExchangeEventListener(
+                @NonNull ICapabilityExchangeEventListener listener) throws RemoteException {
+            executeMethodAsync(() -> mReference.setCapabilityExchangeEventListener(listener),
+                    "setCapabilityExchangeEventListener");
+        }
+
+        @Override
+        public void publishCapabilities(@NonNull String pidfXml,
+                @NonNull IPublishResponseCallback callback) throws RemoteException {
+            PublishResponseCallback callbackWrapper = new RcsPublishResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .publishCapabilities(pidfXml, callbackWrapper), "publishCapabilities");
+        }
+
+        @Override
+        public void subscribeForCapabilities(@NonNull List<Uri> uris,
+                @NonNull ISubscribeResponseCallback callback) throws RemoteException {
+            SubscribeResponseCallback wrapper = new RcsSubscribeResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .subscribeForCapabilities(uris, wrapper), "subscribeForCapabilities");
+        }
+
+        @Override
+        public void sendOptionsCapabilityRequest(@NonNull Uri contactUri,
+                @NonNull List<String> myCapabilities, @NonNull IOptionsResponseCallback callback)
+                throws RemoteException {
+            OptionsResponseCallback callbackWrapper = new RcsOptionsResponseAidlWrapper(callback);
+            executeMethodAsync(() -> mReference.getCapabilityExchangeImplBaseInternal()
+                    .sendOptionsCapabilityRequest(contactUri, myCapabilities, callbackWrapper),
+                    "sendOptionsCapabilityRequest");
+        }
+
         // RcsPresenceExchangeImplBase specific APIS
         @Override
         public void requestCapabilities(List<Uri> uris, int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getPresenceExchangeInternal()
-                    .requestCapabilities(uris, operationToken), "requestCapabilities");
+            throw new RemoteException("Unsupported operation: requestCapabilities");
         }
         @Override
         public void updateCapabilities(RcsContactUceCapability capabilities, int operationToken)
                 throws RemoteException {
-            executeMethodAsync(() -> mReference.getPresenceExchangeInternal()
-                            .updateCapabilities(capabilities, operationToken),
-                    "updateCapabilities");
-
+            throw new RemoteException("Unsupported operation: updateCapabilities");
         }
         // RcsSipOptionsImplBase specific APIS
         @Override
         public void sendCapabilityRequest(Uri contactUri, RcsContactUceCapability capabilities,
                 int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .sendCapabilityRequest(contactUri, capabilities, operationToken),
-                    "sendCapabilityRequest");
-
+            throw new RemoteException("Unsupported operation: sendCapabilityRequest");
         }
         @Override
         public void respondToCapabilityRequest(String contactUri,
                 RcsContactUceCapability ownCapabilities, int operationToken)
                 throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .respondToCapabilityRequest(contactUri, ownCapabilities,
-                                    operationToken), "respondToCapabilityRequest");
-
+            throw new RemoteException("Unsupported operation: respondToCapabilityRequest");
         }
         @Override
         public void respondToCapabilityRequestWithError(Uri contactUri, int code, String reason,
                 int operationToken) throws RemoteException {
-            executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
-                            .respondToCapabilityRequestWithError(contactUri, code, reason,
-                                    operationToken), "respondToCapabilityRequestWithError");
+            throw new RemoteException("Unsupported operation: respondToCapabilityRequestWithError");
         }
 
         // Call the methods with a clean calling identity on the executor and wait indefinitely for
@@ -182,8 +219,8 @@
      * Contains the capabilities defined and supported by a {@link RcsFeature} in the
      * form of a bitmask. The capabilities that are used in the RcsFeature are
      * defined as:
-     * {@link RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
-     * {@link RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
+     * {@link RcsUceAdatper.RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
+     * {@link RceUceAdapter.RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
      *
      * The enabled capabilities of this RcsFeature will be set by the framework
      * using {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}.
@@ -223,7 +260,7 @@
          */
         public static final int CAPABILITY_TYPE_PRESENCE_UCE =  1 << 1;
 
-        public RcsImsCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public RcsImsCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super(capabilities);
         }
 
@@ -232,25 +269,24 @@
         }
 
         @Override
-        public void addCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public void addCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super.addCapabilities(capabilities);
         }
 
         @Override
-        public void removeCapabilities(@RcsImsCapabilityFlag int capabilities) {
+        public void removeCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             super.removeCapabilities(capabilities);
         }
 
         @Override
-        public boolean isCapable(@RcsImsCapabilityFlag int capabilities) {
+        public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
             return super.isCapable(capabilities);
         }
     }
 
     private final RcsFeatureBinder mImsRcsBinder;
-    private IRcsFeatureListener mListenerBinder;
-    private RcsPresenceExchangeImplBase mPresExchange;
-    private RcsSipOptionsImplBase mSipOptions;
+    private RcsCapabilityExchangeImplBase mCapabilityExchangeImpl;
+    private ICapabilityExchangeEventListener mCapExchangeEventListener;
 
     /**
      * Create a new RcsFeature.
@@ -314,7 +350,7 @@
      * @hide
      */
     public boolean queryCapabilityConfiguration(
-            @RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+            @RcsUceAdapter.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
         // Base Implementation - Override to provide functionality
         return false;
@@ -342,37 +378,22 @@
     }
 
     /**
-     * Retrieve the implementation of SIP OPTIONS for this {@link RcsFeature}.
-     * <p>
-     * Will only be requested by the framework if capability exchange via SIP OPTIONS is
-     * configured as capable during a
+     * Retrieve the implementation of UCE for this {@link RcsFeature}, which can use either
+     * presence or OPTIONS for capability exchange.
+     *
+     * Will only be requested by the framework if capability exchange is configured
+     * as capable during a
      * {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
      * operation and the RcsFeature sets the status of the capability to true using
      * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
      *
-     * @return An instance of {@link RcsSipOptionsImplBase} that implements SIP options exchange if
-     * it is supported by the device.
-     * @hide
-     */
-    public @NonNull RcsSipOptionsImplBase getOptionsExchangeImpl() {
-        // Base Implementation, override to implement functionality
-        return new RcsSipOptionsImplBase();
-    }
-
-    /**
-     * Retrieve the implementation of UCE presence for this {@link RcsFeature}.
-     * Will only be requested by the framework if presence exchang is configured as capable during
-     * a {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
-     * operation and the RcsFeature sets the status of the capability to true using
-     * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
-     *
-     * @return An instance of {@link RcsPresenceExchangeImplBase} that implements presence
+     * @return An instance of {@link RcsCapabilityExchangeImplBase} that implements presence
      * exchange if it is supported by the device.
      * @hide
      */
-    public @NonNull RcsPresenceExchangeImplBase getPresenceExchangeImpl() {
-        // Base Implementation, override to implement functionality.
-        return new RcsPresenceExchangeImplBase();
+    public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl() {
+        // Base Implementation, override to implement functionality
+        return new RcsCapabilityExchangeImplBase();
     }
 
     /**{@inheritDoc}*/
@@ -395,39 +416,20 @@
         return mImsRcsBinder;
     }
 
-    /**@hide*/
-    public IRcsFeatureListener getListener() {
-        synchronized (mLock) {
-            return mListenerBinder;
+    private void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener) {
+        mCapExchangeEventListener = listener;
+        if (mCapExchangeEventListener != null) {
+            onFeatureReady();
         }
     }
 
-    private void setListener(IRcsFeatureListener listener) {
+    private RcsCapabilityExchangeImplBase getCapabilityExchangeImplBaseInternal() {
         synchronized (mLock) {
-            mListenerBinder = listener;
-            if (mListenerBinder != null) {
-                onFeatureReady();
+            if (mCapabilityExchangeImpl == null) {
+                mCapabilityExchangeImpl = createCapabilityExchangeImpl();
+                mCapabilityExchangeImpl.setEventListener(mCapExchangeEventListener);
             }
-        }
-    }
-
-    private RcsPresenceExchangeImplBase getPresenceExchangeInternal() {
-        synchronized (mLock) {
-            if (mPresExchange == null) {
-                mPresExchange = getPresenceExchangeImpl();
-                mPresExchange.initialize(this);
-            }
-            return mPresExchange;
-        }
-    }
-
-    private RcsSipOptionsImplBase getOptionsExchangeInternal() {
-        synchronized (mLock) {
-            if (mSipOptions == null) {
-                mSipOptions = getOptionsExchangeImpl();
-                mSipOptions.initialize(this);
-            }
-            return mSipOptions;
+            return mCapabilityExchangeImpl;
         }
     }
 }
diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
index 1cebdd5..a3a6cb8 100644
--- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java
@@ -26,10 +26,17 @@
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.ImsVideoCallProvider;
+import android.telephony.ims.RtpHeaderExtension;
+import android.telephony.ims.RtpHeaderExtensionType;
 import android.telephony.ims.aidl.IImsCallSessionListener;
+import android.util.ArraySet;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsVideoCallProvider;
+
+import java.util.List;
+import java.util.Set;
+
 /**
  * Base implementation of IImsCallSession, which implements stub versions of the methods available.
  *
@@ -277,6 +284,12 @@
         public void sendRttMessage(String rttMessage) {
             ImsCallSessionImplBase.this.sendRttMessage(rttMessage);
         }
+
+        @Override
+        public void sendRtpHeaderExtensions(@NonNull List<RtpHeaderExtension> extensions) {
+            ImsCallSessionImplBase.this.sendRtpHeaderExtensions(
+                    new ArraySet<RtpHeaderExtension>(extensions));
+        }
     };
 
     /**
@@ -636,6 +649,22 @@
     public void sendRttMessage(String rttMessage) {
     }
 
+    /**
+     * Device requests that {@code rtpHeaderExtensions} are sent as a header extension with the next
+     * RTP packet sent by the IMS stack.
+     * <p>
+     * The {@link RtpHeaderExtensionType}s negotiated during SDP (Session Description Protocol)
+     * signalling determine the {@link RtpHeaderExtension}s which can be sent using this method.
+     * See RFC8285 for more information.
+     * <p>
+     * By specification, the RTP header extension is an unacknowledged transmission and there is no
+     * guarantee that the header extension will be delivered by the network to the other end of the
+     * call.
+     * @param rtpHeaderExtensions The RTP header extensions to be included in the next RTP header.
+     */
+    public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
+    }
+
     /** @hide */
     public IImsCallSession getServiceImpl() {
         return mServiceImpl;
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
index fda295a..0b13efb 100644
--- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
@@ -87,12 +87,8 @@
 
     /** @hide */
     protected final IRcsFeatureListener getListener() throws ImsException {
-        IRcsFeatureListener listener = mFeature.getListener();
-        if (listener == null) {
-            throw new ImsException("Connection to Framework has not been established, wait for "
-                    + "onFeatureReady().", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-        return mFeature.getListener();
+        throw new ImsException("This method is deprecated.",
+                ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
     }
 
     /**
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
new file mode 100644
index 0000000..b5704bf
--- /dev/null
+++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java
@@ -0,0 +1,338 @@
+/*
+ * 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.
+ */
+
+package android.telephony.ims.stub;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.Uri;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
+import android.util.Log;
+import android.util.Pair;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Base class for different types of Capability exchange.
+ * @hide
+ */
+public class RcsCapabilityExchangeImplBase {
+
+    private static final String LOG_TAG = "RcsCapExchangeImplBase";
+
+    /**
+     * Service is unknown.
+     */
+    public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0;
+
+    /**
+     * The command failed with an unknown error.
+     */
+    public static final int COMMAND_CODE_GENERIC_FAILURE = 1;
+
+    /**
+     * Invalid parameter(s).
+     */
+    public static final int COMMAND_CODE_INVALID_PARAM = 2;
+
+    /**
+     * Fetch error.
+     */
+    public static final int COMMAND_CODE_FETCH_ERROR = 3;
+
+    /**
+     * Request timed out.
+     */
+    public static final int COMMAND_CODE_REQUEST_TIMEOUT = 4;
+
+    /**
+     * Failure due to insufficient memory available.
+     */
+    public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 5;
+
+    /**
+     * Network connection is lost.
+     * @hide
+     */
+    public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6;
+
+    /**
+     * Requested feature/resource is not supported.
+     * @hide
+     */
+    public static final int COMMAND_CODE_NOT_SUPPORTED = 7;
+
+    /**
+     * Contact or resource is not found.
+     */
+    public static final int COMMAND_CODE_NOT_FOUND = 8;
+
+    /**
+     * Service is not available.
+     */
+    public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 9;
+
+    /**
+     * Command resulted in no change in state, ignoring.
+     */
+    public static final int COMMAND_CODE_NO_CHANGE = 10;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "COMMAND_CODE_", value = {
+            COMMAND_CODE_SERVICE_UNKNOWN,
+            COMMAND_CODE_GENERIC_FAILURE,
+            COMMAND_CODE_INVALID_PARAM,
+            COMMAND_CODE_FETCH_ERROR,
+            COMMAND_CODE_REQUEST_TIMEOUT,
+            COMMAND_CODE_INSUFFICIENT_MEMORY,
+            COMMAND_CODE_LOST_NETWORK_CONNECTION,
+            COMMAND_CODE_NOT_SUPPORTED,
+            COMMAND_CODE_NOT_FOUND,
+            COMMAND_CODE_SERVICE_UNAVAILABLE,
+            COMMAND_CODE_NO_CHANGE
+    })
+    public @interface CommandCode {}
+
+    /**
+     * Interface used by the framework to receive the response of the publish request.
+     */
+    public interface PublishResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the {@link RcsFeature}
+         * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases
+         * when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+
+        /**
+         * Provide the framework with a subsequent network response update to
+         * {@link #publishCapabilities(String, PublishResponseCallback)}.
+         *
+         * @param code The SIP response code sent from the network for the operation
+         * token specified.
+         * @param reason The optional reason response from the network. If the network
+         *  provided no reason with the code, the string should be empty.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the {@link RcsFeature}
+         * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases
+         * when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(@IntRange(from = 100, to = 699) int code,
+                @NonNull String reason) throws ImsException;
+    }
+
+    /**
+     * Interface used by the framework to respond to OPTIONS requests.
+     */
+    public interface OptionsResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature}
+         * has not received the {@link ImsFeature#onFeatureReady()} callback. This may also happen
+         * in rare cases when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+        /**
+         * Send the response of a SIP OPTIONS capability exchange to the framework.
+         * @param code The SIP response code that was sent by the network in response
+         * to the request sent by {@link #sendOptionsCapabilityRequest}.
+         * @param reason The optional SIP response reason sent by the network.
+         * If none was sent, this should be an empty string.
+         * @param theirCaps the contact's UCE capabilities associated with the
+         * capability request.
+         * @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not
+         * currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+         * {@link RcsFeature} has not received the
+         * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
+         * cases when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(int code, @NonNull String reason,
+                @Nullable List<String> theirCaps) throws ImsException;
+    }
+
+    /**
+     * Interface used by the framework to receive the response of the subscribe request.
+     */
+    public interface SubscribeResponseCallback {
+        /**
+         * Notify the framework that the command associated with this callback has failed.
+         *
+         * @param code The reason why the associated command has failed.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not
+         * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
+         * rare cases when the Telephony stack has crashed.
+         */
+        void onCommandError(@CommandCode int code) throws ImsException;
+
+        /**
+         * Notify the framework of the response to the SUBSCRIBE request from
+         * {@link #subscribeForCapabilities(List<Uri>, SubscribeResponseCallback)}.
+         *
+         * @param code The SIP response code sent from the network for the operation
+         * token specified.
+         * @param reason The optional reason response from the network. If the network
+         *  provided no reason with the code, the string should be empty.
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently connected to the framework. This can happen if the
+         * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
+         * {@link RcsFeature} has not received the {@link ImsFeature#onFeatureReady()} callback.
+         * This may also happen in rare cases when the Telephony stack has crashed.
+         */
+        void onNetworkResponse(@IntRange(from = 100, to = 699) int code,
+                @NonNull String reason) throws ImsException;
+
+        /**
+         * Provides the framework with latest XML PIDF documents included in the
+         * network response for the requested  contacts' capabilities requested by the
+         * Framework  using {@link #requestCapabilities(List, int)}. This should be
+         * called every time a new NOTIFY event is received with new capability
+         * information.
+         *
+         * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
+         * not currently
+         * connected to the framework. This can happen if the {@link RcsFeature} is not
+         * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+         * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
+         * rare cases when the
+         * Telephony stack has crashed.
+         */
+        void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException;
+
+        /**
+         * A resource in the resource list for the presence subscribe event has been terminated.
+         * <p>
+         * This allows the framework to know that there will not be any capability information for
+         * a specific contact URI that they subscribed for.
+         */
+        void onResourceTerminated(
+                @NonNull List<Pair<Uri, String>> uriTerminatedReason) throws ImsException;
+
+        /**
+         * The subscription associated with a previous #requestCapabilities operation
+         * has been terminated. This will mostly be due to the subscription expiring,
+         * but may also happen due to an error.
+         * <p>
+         * This allows the framework to know that there will no longer be any
+         * capability updates for the requested operationToken.
+         */
+        void onTerminated(String reason, String retryAfter) throws ImsException;
+    }
+
+
+    private ICapabilityExchangeEventListener mListener;
+
+    /**
+     * Set the event listener to send the request to Framework.
+     */
+    public void setEventListener(ICapabilityExchangeEventListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Get the event listener.
+     */
+    public ICapabilityExchangeEventListener getEventListener() {
+        return mListener;
+    }
+
+    /**
+     * The user capabilities of one or multiple contacts have been requested by the framework.
+     * <p>
+     * The response from the network to the SUBSCRIBE request must be sent back to the framework
+     * using {@link #onSubscribeNetworkResponse(int, String, int)}. As NOTIFY requests come in from
+     * the network, the requested contact’s capabilities should be sent back to the framework using
+     * {@link #onSubscribeNotifyRequest} and {@link onSubscribeResourceTerminated}
+     * should be called with the presence information for the contacts specified.
+     * <p>
+     * Once the subscription is terminated, {@link #onSubscriptionTerminated} must be called for
+     * the framework to finish listening for NOTIFY responses.
+     * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
+     * capabilities for.
+     * @param cb The callback of the subscribe request.
+     */
+    public void subscribeForCapabilities(@NonNull List<Uri> uris,
+            @NonNull SubscribeResponseCallback cb) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "subscribeForCapabilities called with no implementation.");
+        try {
+            cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+
+    /**
+     * The capabilities of this device have been updated and should be published to the network.
+     * <p>
+     * If this operation succeeds, network response updates should be sent to the framework using
+     * {@link #onNetworkResponse(int, String)}.
+     * @param pidfXml The XML PIDF document containing the capabilities of this device to be sent
+     * to the carrier’s presence server.
+     * @param cb The callback of the publish request
+     */
+    public void publishCapabilities(@NonNull String pidfXml, @NonNull PublishResponseCallback cb) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "publishCapabilities called with no implementation.");
+        try {
+            cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+
+    /**
+     * Push one's own capabilities to a remote user via the SIP OPTIONS presence exchange mechanism
+     * in order to receive the capabilities of the remote user in response.
+     * <p>
+     * The implementer must call {@link #onNetworkResponse} to send the response of this
+     * query back to the framework.
+     * @param contactUri The URI of the remote user that we wish to get the capabilities of.
+     * @param myCapabilities The capabilities of this device to send to the remote user.
+     * @param callback The callback of this request which is sent from the remote user.
+     */
+    public void sendOptionsCapabilityRequest(@NonNull Uri contactUri,
+            @NonNull List<String> myCapabilities, @NonNull OptionsResponseCallback callback) {
+        // Stub - to be implemented by service
+        Log.w(LOG_TAG, "sendOptionsCapabilityRequest called with no implementation.");
+        try {
+            callback.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
+        } catch (ImsException e) {
+            // Do not do anything, this is a stub implementation.
+        }
+    }
+}
diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
index ab14e82..e3a8aee 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl
@@ -20,6 +20,8 @@
 import android.telephony.ims.aidl.IImsCallSessionListener;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsStreamMediaProfile;
+import android.telephony.ims.RtpHeaderExtension;
+
 import com.android.ims.internal.IImsVideoCallProvider;
 
 /**
@@ -297,4 +299,10 @@
      * @param rttMessage RTT message to be sent
      */
     void sendRttMessage(in String rttMessage);
+
+    /*
+     * Device sends RTP header extension(s).
+     * @param extensions the header extensions to be sent
+     */
+    void sendRtpHeaderExtensions(in List<RtpHeaderExtension> extensions);
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index b1700a1..9160746 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -30,77 +30,96 @@
 
     // from RIL_Errno
     int SUCCESS = 0;
-    int RADIO_NOT_AVAILABLE = 1;              /* If radio did not start or is resetting */
+    int RADIO_NOT_AVAILABLE = 1;                    /* If radio did not start or is resetting */
     int GENERIC_FAILURE = 2;
-    int PASSWORD_INCORRECT = 3;               /* for PIN/PIN2 methods only! */
-    int SIM_PIN2 = 4;                         /* Operation requires SIM PIN2 to be entered */
-    int SIM_PUK2 = 5;                         /* Operation requires SIM PIN2 to be entered */
+    int PASSWORD_INCORRECT = 3;                     /* for PIN/PIN2 methods only! */
+    int SIM_PIN2 = 4;                               /* Operation requires SIM PIN2 to be entered */
+    int SIM_PUK2 = 5;                               /* Operation requires SIM PIN2 to be entered */
     int REQUEST_NOT_SUPPORTED = 6;
     int REQUEST_CANCELLED = 7;
-    int OP_NOT_ALLOWED_DURING_VOICE_CALL = 8; /* data operation is not allowed during voice call in
-                                                 class C */
-    int OP_NOT_ALLOWED_BEFORE_REG_NW = 9;     /* request is not allowed before device registers to
-                                                 network */
-    int SMS_SEND_FAIL_RETRY = 10;             /* send sms fail and need retry */
-    int SIM_ABSENT = 11;                      /* ICC card is absent */
-    int SUBSCRIPTION_NOT_AVAILABLE = 12;      /* fail to find CDMA subscription from specified
-                                                 location */
-    int MODE_NOT_SUPPORTED = 13;              /* HW does not support preferred network type */
-    int FDN_CHECK_FAILURE = 14;               /* send operation barred error when FDN is enabled */
-    int ILLEGAL_SIM_OR_ME = 15;               /* network selection failure due
-                                                 to wrong SIM/ME and no
-                                                 retries needed */
-    int MISSING_RESOURCE = 16;                /* no logical channel available */
-    int NO_SUCH_ELEMENT = 17;                 /* application not found on SIM */
-    int DIAL_MODIFIED_TO_USSD = 18;           /* DIAL request modified to USSD */
-    int DIAL_MODIFIED_TO_SS = 19;             /* DIAL request modified to SS */
-    int DIAL_MODIFIED_TO_DIAL = 20;           /* DIAL request modified to DIAL with different data*/
-    int USSD_MODIFIED_TO_DIAL = 21;           /* USSD request modified to DIAL */
-    int USSD_MODIFIED_TO_SS = 22;             /* USSD request modified to SS */
-    int USSD_MODIFIED_TO_USSD = 23;           /* USSD request modified to different USSD request */
-    int SS_MODIFIED_TO_DIAL = 24;             /* SS request modified to DIAL */
-    int SS_MODIFIED_TO_USSD = 25;             /* SS request modified to USSD */
-    int SUBSCRIPTION_NOT_SUPPORTED = 26;      /* Subscription not supported */
-    int SS_MODIFIED_TO_SS = 27;               /* SS request modified to different SS request */
-    int SIM_ALREADY_POWERED_OFF = 29;         /* SAP: 0x03, Error card aleready powered off */
-    int SIM_ALREADY_POWERED_ON = 30;          /* SAP: 0x05, Error card already powered on */
-    int SIM_DATA_NOT_AVAILABLE = 31;          /* SAP: 0x06, Error data not available */
+    int OP_NOT_ALLOWED_DURING_VOICE_CALL = 8;       /* data operation is not allowed during voice
+                                                       call in class C */
+    int OP_NOT_ALLOWED_BEFORE_REG_NW = 9;           /* request is not allowed before device
+                                                       registers to network */
+    int SMS_SEND_FAIL_RETRY = 10;                   /* send sms fail and need retry */
+    int SIM_ABSENT = 11;                            /* ICC card is absent */
+    int SUBSCRIPTION_NOT_AVAILABLE = 12;            /* fail to find CDMA subscription from specified
+                                                       location */
+    int MODE_NOT_SUPPORTED = 13;                    /* HW does not support preferred network type */
+    int FDN_CHECK_FAILURE = 14;                     /* send operation barred error when FDN is
+                                                       enabled */
+    int ILLEGAL_SIM_OR_ME = 15;                     /* network selection failure due to wrong
+                                                       SIM/ME and no retries needed */
+    int MISSING_RESOURCE = 16;                      /* no logical channel available */
+    int NO_SUCH_ELEMENT = 17;                       /* application not found on SIM */
+    int DIAL_MODIFIED_TO_USSD = 18;                 /* DIAL request modified to USSD */
+    int DIAL_MODIFIED_TO_SS = 19;                   /* DIAL request modified to SS */
+    int DIAL_MODIFIED_TO_DIAL = 20;                 /* DIAL request modified to DIAL with
+                                                       different data*/
+    int USSD_MODIFIED_TO_DIAL = 21;                 /* USSD request modified to DIAL */
+    int USSD_MODIFIED_TO_SS = 22;                   /* USSD request modified to SS */
+    int USSD_MODIFIED_TO_USSD = 23;                 /* USSD request modified to different USSD
+                                                       request */
+    int SS_MODIFIED_TO_DIAL = 24;                   /* SS request modified to DIAL */
+    int SS_MODIFIED_TO_USSD = 25;                   /* SS request modified to USSD */
+    int SUBSCRIPTION_NOT_SUPPORTED = 26;            /* Subscription not supported */
+    int SS_MODIFIED_TO_SS = 27;                     /* SS request modified to different SS
+                                                       request */
+    int SIM_ALREADY_POWERED_OFF = 29;               /* SAP: 0x03, Error card aleready powered off */
+    int SIM_ALREADY_POWERED_ON = 30;                /* SAP: 0x05, Error card already powered on */
+    int SIM_DATA_NOT_AVAILABLE = 31;                /* SAP: 0x06, Error data not available */
     int SIM_SAP_CONNECT_FAILURE = 32;
     int SIM_SAP_MSG_SIZE_TOO_LARGE = 33;
     int SIM_SAP_MSG_SIZE_TOO_SMALL = 34;
     int SIM_SAP_CONNECT_OK_CALL_ONGOING = 35;
-    int LCE_NOT_SUPPORTED = 36;               /* Link Capacity Estimation (LCE) not supported */
-    int NO_MEMORY = 37;                       /* Not sufficient memory to process the request */
-    int INTERNAL_ERR = 38;                    /* Hit unexpected vendor internal error scenario */
-    int SYSTEM_ERR = 39;                      /* Hit platform or system error */
-    int MODEM_ERR = 40;                       /* Hit unexpected modem error */
-    int INVALID_STATE = 41;                   /* Unexpected request for the current state */
-    int NO_RESOURCES = 42;                    /* Not sufficient resource to process the request */
-    int SIM_ERR = 43;                         /* Received error from SIM card */
-    int INVALID_ARGUMENTS = 44;               /* Received invalid arguments in request */
-    int INVALID_SIM_STATE = 45;               /* Can not process the request in current SIM state */
-    int INVALID_MODEM_STATE = 46;             /* Can not process the request in current Modem state */
-    int INVALID_CALL_ID = 47;                 /* Received invalid call id in request */
-    int NO_SMS_TO_ACK = 48;                   /* ACK received when there is no SMS to ack */
-    int NETWORK_ERR = 49;                     /* Received error from network */
-    int REQUEST_RATE_LIMITED = 50;            /* Operation denied due to overly-frequent requests */
-    int SIM_BUSY = 51;                        /* SIM is busy */
-    int SIM_FULL = 52;                        /* The target EF is full */
-    int NETWORK_REJECT = 53;                  /* Request is rejected by network */
-    int OPERATION_NOT_ALLOWED = 54;           /* Not allowed the request now */
-    int EMPTY_RECORD = 55;                    /* The request record is empty */
-    int INVALID_SMS_FORMAT = 56;              /* Invalid sms format */
-    int ENCODING_ERR = 57;                    /* Message not encoded properly */
-    int INVALID_SMSC_ADDRESS = 58;            /* SMSC address specified is invalid */
-    int NO_SUCH_ENTRY = 59;                   /* No such entry present to perform the request */
-    int NETWORK_NOT_READY = 60;               /* Network is not ready to perform the request */
-    int NOT_PROVISIONED = 61;                 /* Device doesnot have this value provisioned */
-    int NO_SUBSCRIPTION = 62;                 /* Device doesnot have subscription */
-    int NO_NETWORK_FOUND = 63;                /* Network cannot be found */
-    int DEVICE_IN_USE = 64;                   /* Operation cannot be performed because the device
-                                                 is currently in use */
-    int ABORTED = 65;                         /* Operation aborted */
-    int INVALID_RESPONSE = 66;                /* Invalid response sent by vendor code */
+    int LCE_NOT_SUPPORTED = 36;                     /* Link Capacity Estimation (LCE) not
+                                                       supported */
+    int NO_MEMORY = 37;                             /* Not sufficient memory to process the
+                                                       request */
+    int INTERNAL_ERR = 38;                          /* Hit unexpected vendor internal error
+                                                       scenario */
+    int SYSTEM_ERR = 39;                            /* Hit platform or system error */
+    int MODEM_ERR = 40;                             /* Hit unexpected modem error */
+    int INVALID_STATE = 41;                         /* Unexpected request for the current state */
+    int NO_RESOURCES = 42;                          /* Not sufficient resource to process the
+                                                       request */
+    int SIM_ERR = 43;                               /* Received error from SIM card */
+    int INVALID_ARGUMENTS = 44;                     /* Received invalid arguments in request */
+    int INVALID_SIM_STATE = 45;                     /* Can not process the request in current SIM
+                                                       state */
+    int INVALID_MODEM_STATE = 46;                   /* Can not process the request in current Modem
+                                                       state */
+    int INVALID_CALL_ID = 47;                       /* Received invalid call id in request */
+    int NO_SMS_TO_ACK = 48;                         /* ACK received when there is no SMS to ack */
+    int NETWORK_ERR = 49;                           /* Received error from network */
+    int REQUEST_RATE_LIMITED = 50;                  /* Operation denied due to overly-frequent
+                                                       requests */
+    int SIM_BUSY = 51;                              /* SIM is busy */
+    int SIM_FULL = 52;                              /* The target EF is full */
+    int NETWORK_REJECT = 53;                        /* Request is rejected by network */
+    int OPERATION_NOT_ALLOWED = 54;                 /* Not allowed the request now */
+    int EMPTY_RECORD = 55;                          /* The request record is empty */
+    int INVALID_SMS_FORMAT = 56;                    /* Invalid sms format */
+    int ENCODING_ERR = 57;                          /* Message not encoded properly */
+    int INVALID_SMSC_ADDRESS = 58;                  /* SMSC address specified is invalid */
+    int NO_SUCH_ENTRY = 59;                         /* No such entry present to perform the
+                                                       request */
+    int NETWORK_NOT_READY = 60;                     /* Network is not ready to perform the
+                                                       request */
+    int NOT_PROVISIONED = 61;                       /* Device doesnot have this value
+                                                       provisioned */
+    int NO_SUBSCRIPTION = 62;                       /* Device doesnot have subscription */
+    int NO_NETWORK_FOUND = 63;                      /* Network cannot be found */
+    int DEVICE_IN_USE = 64;                         /* Operation cannot be performed because the
+                                                       device is currently in use */
+    int ABORTED = 65;                               /* Operation aborted */
+    int INVALID_RESPONSE = 66;                      /* Invalid response sent by vendor code */
+    int SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 67; /* 1X voice and SMS are not allowed
+                                                       simulteneously */
+    int ACCESS_BARRED = 68;                         /* SMS access is barred */
+    int BLOCKED_DUE_TO_CALL = 69;                   /* SMS is blocked due to call control */
+    int RF_HARDWARE_ISSUE = 70;                     /* RF HW issue is detected */
+    int NO_RF_CALIBRATION_INFO = 71;                /* No RF calibration in device */
 
     // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
     // reveal particular replacement for Generic failure
@@ -557,6 +576,7 @@
     int RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION = 1048;
     int RIL_UNSOL_NETWORK_SCAN_RESULT = 1049;
     int RIL_UNSOL_KEEPALIVE_STATUS = 1050;
+    int RIL_UNSOL_UNTHROTTLE_APN = 1052;
 
     /* The following unsols are not defined in RIL.h */
     int RIL_UNSOL_HAL_NON_RIL_BASE = 1100;
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
index 1adbc2d..f49d4fc 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
@@ -32,7 +32,7 @@
 
 
 
-    // Code below generated by codegen v1.0.18.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -98,8 +98,8 @@
     };
 
     @DataClass.Generated(
-            time = 1603836848866L,
-            codegenVersion = "1.0.18",
+            time = 1604522375155L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java",
             inputSignatures = "private  int mBaseData\nclass HierrarchicalDataClassBase extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genSetters=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
index a4fdcd1..e8cce23 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
@@ -46,7 +46,7 @@
 
 
 
-    // Code below generated by codegen v1.0.18.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -120,8 +120,8 @@
     };
 
     @DataClass.Generated(
-            time = 1603836849753L,
-            codegenVersion = "1.0.18",
+            time = 1604522376059L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java",
             inputSignatures = "private @android.annotation.NonNull java.lang.String mChildData\nclass HierrarchicalDataClassChild extends com.android.codegentest.HierrarchicalDataClassBase implements []\n@com.android.internal.util.DataClass(genParcelable=true, genConstructor=false, genSetters=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
index f0d728e..9de6552 100644
--- a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
@@ -54,7 +54,7 @@
 
 
 
-    // Code below generated by codegen v1.0.18.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -412,10 +412,10 @@
     }
 
     @DataClass.Generated(
-            time = 1603836847927L,
-            codegenVersion = "1.0.18",
+            time = 1604522374190L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java",
-            inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\n @java.lang.SuppressWarnings({\"WeakerAccess\"}) @android.annotation.Nullable java.lang.Boolean mNullableBoolean\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)")
+            inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\n @java.lang.SuppressWarnings @android.annotation.Nullable java.lang.Boolean mNullableBoolean\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
index a3f458b..5a3e273 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -344,7 +344,7 @@
 
 
 
-    // Code below generated by codegen v1.0.18.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -1874,10 +1874,10 @@
     }
 
     @DataClass.Generated(
-            time = 1603836845952L,
-            codegenVersion = "1.0.18",
+            time = 1604522372172L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
-            inputSignatures = "public static final  java.lang.String STATE_NAME_UNDEFINED\npublic static final  java.lang.String STATE_NAME_ON\npublic static final  java.lang.String STATE_NAME_OFF\npublic static final  int STATE_ON\npublic static final  int STATE_OFF\npublic static final  int STATE_UNDEFINED\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate  int mNum\nprivate  int mNum2\nprivate  int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient  android.net.LinkAddress[] mLinkAddresses6\ntransient  int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static  java.lang.String defaultName4()\nprivate  int[] lazyInitTmpStorage()\npublic  android.net.LinkAddress[] getLinkAddresses4()\nprivate  boolean patternEquals(java.util.regex.Pattern)\nprivate  int patternHashCode()\nprivate  void onConstructed()\npublic  void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
+            inputSignatures = "public static final  java.lang.String STATE_NAME_UNDEFINED\npublic static final  java.lang.String STATE_NAME_ON\npublic static final  java.lang.String STATE_NAME_OFF\npublic static final  int STATE_ON\npublic static final  int STATE_OFF\npublic static final  int STATE_UNDEFINED\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate  int mNum\nprivate  int mNum2\nprivate  int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient  android.net.LinkAddress[] mLinkAddresses6\ntransient  int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange int mDayOfWeek\nprivate @android.annotation.Size @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange float[] mCoords\nprivate static  java.lang.String defaultName4()\nprivate  int[] lazyInitTmpStorage()\npublic  android.net.LinkAddress[] getLinkAddresses4()\nprivate  boolean patternEquals(java.util.regex.Pattern)\nprivate  int patternHashCode()\nprivate  void onConstructed()\npublic  void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
index e356704..3ab3445 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
@@ -85,7 +85,7 @@
 
 
 
-    // Code below generated by codegen v1.0.18.
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -253,8 +253,8 @@
     }
 
     @DataClass.Generated(
-            time = 1603836846970L,
-            codegenVersion = "1.0.18",
+            time = 1604522373190L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java",
             inputSignatures = "  long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n  long creationTimestamp\nprivate static  java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate  void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\nabstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic  com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic  com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
index 07ec31d..8901cac 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
@@ -36,7 +36,7 @@
 
 
 
-        // Code below generated by codegen v1.0.18.
+        // Code below generated by codegen v1.0.20.
         //
         // DO NOT MODIFY!
         // CHECKSTYLE:OFF Generated code
@@ -135,8 +135,8 @@
         };
 
         @DataClass.Generated(
-                time = 1603836851627L,
-                codegenVersion = "1.0.18",
+                time = 1604522377998L,
+                codegenVersion = "1.0.20",
                 sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                 inputSignatures = " @android.annotation.NonNull java.lang.String mBar\nclass NestedDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
         @Deprecated
@@ -160,7 +160,7 @@
 
 
 
-            // Code below generated by codegen v1.0.18.
+            // Code below generated by codegen v1.0.20.
             //
             // DO NOT MODIFY!
             // CHECKSTYLE:OFF Generated code
@@ -259,8 +259,8 @@
             };
 
             @DataClass.Generated(
-                    time = 1603836851635L,
-                    codegenVersion = "1.0.18",
+                    time = 1604522378007L,
+                    codegenVersion = "1.0.20",
                     sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                     inputSignatures = " @android.annotation.NonNull long mBaz2\nclass NestedDataClass3 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
             @Deprecated
@@ -274,7 +274,7 @@
 
 
 
-        // Code below generated by codegen v1.0.18.
+        // Code below generated by codegen v1.0.20.
         //
         // DO NOT MODIFY!
         // CHECKSTYLE:OFF Generated code
@@ -373,8 +373,8 @@
         };
 
         @DataClass.Generated(
-                time = 1603836851640L,
-                codegenVersion = "1.0.18",
+                time = 1604522378015L,
+                codegenVersion = "1.0.20",
                 sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                 inputSignatures = " @android.annotation.NonNull java.lang.String mBaz\nclass NestedDataClass2 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
         @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
index 5cbc6b3..ac776f3 100644
--- a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
+++ b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
@@ -15,8 +15,10 @@
  */
 package com.android.codegentest;
 
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.PackageManager;
 
 import com.android.internal.util.DataClass;
 
@@ -57,9 +59,12 @@
     /** Unrelated methods should be noted, without triggering staleness false positives */
     public @NonNull String someMethod(int param) { return null; }
 
+    /** Inlined constants in annotation args should be fine */
+    private @IntRange(from = PackageManager.PERMISSION_GRANTED) void annotatedWithConstArg() {}
 
 
-    // Code below generated by codegen v1.0.18.
+
+    // Code below generated by codegen v1.0.20.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -84,10 +89,10 @@
     }
 
     @DataClass.Generated(
-            time = 1603836850677L,
-            codegenVersion = "1.0.18",
+            time = 1604522377011L,
+            codegenVersion = "1.0.20",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java",
-            inputSignatures = "private @android.annotation.Nullable java.util.List<java.util.Set<?>> mUsesWildcards\npublic @android.annotation.NonNull java.lang.String someMethod(int)\nclass StaleDataclassDetectorFalsePositivesTest extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false)")
+            inputSignatures = "private @android.annotation.Nullable java.util.List<java.util.Set<?>> mUsesWildcards\npublic @android.annotation.NonNull java.lang.String someMethod(int)\nprivate @android.annotation.IntRange void annotatedWithConstArg()\nclass StaleDataclassDetectorFalsePositivesTest extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index 6b974ff..db0eed8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -45,6 +45,15 @@
     }
 }
 
+fun WmAssertion.visibleWindowsShownMoreThanOneConsecutiveEntry(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("visibleWindowShownMoreThanOneConsecutiveEntry", bugId, enabled) {
+        this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+    }
+}
+
 @JvmOverloads
 fun LayersAssertion.noUncoveredRegions(
     beginRotation: Int,
@@ -159,6 +168,15 @@
     }
 }
 
+fun LayersAssertion.visibleLayersShownMoreThanOneConsecutiveEntry(
+    bugId: Int = 0,
+    enabled: Boolean = bugId == 0
+) {
+    all("visibleLayersShownMoreThanOneConsecutiveEntry", bugId, enabled) {
+        this.visibleLayersShownMoreThanOneConsecutiveEntry()
+    }
+}
+
 fun EventLogAssertion.focusChanges(
     vararg windows: String,
     bugId: Int = 0,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
new file mode 100644
index 0000000..01853df
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+package com.android.server.wm.flicker.close
+
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.Flicker
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.helpers.StandardAppHelper
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.helpers.waitUntilGone
+import com.android.server.wm.flicker.repetitions
+import com.android.server.wm.flicker.startRotation
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/*
+ * 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.
+ */
+
+/**
+ * Test app closes by pressing back button
+ * To run this test: `atest FlickerTests:CloseAppBackButtonTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class CloseAppBackButtonTest(
+    testName: String,
+    flickerSpec: Flicker
+) : FlickerTestRunner(testName, flickerSpec) {
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<Array<Any>> {
+            val instrumentation = InstrumentationRegistry.getInstrumentation()
+            val testApp = StandardAppHelper(instrumentation,
+                    "com.android.server.wm.flicker.testapp", "SimpleApp")
+            return FlickerTestRunnerFactory(instrumentation, repetitions = 10)
+                    .buildTest { configuration ->
+                        withTestName { buildTestTag("closeAppBackButton", testApp, configuration) }
+                        repeat { configuration.repetitions }
+                        setup {
+                            test {
+                                device.wakeUpAndGoToHomeScreen()
+                            }
+                            eachRun {
+                                this.setRotation(configuration.startRotation)
+                                testApp.open()
+                            }
+                        }
+                        transitions {
+                            device.pressBack()
+                            device.waitUntilGone(testApp.getPackage())
+                        }
+                        teardown {
+                            eachRun {
+                                this.setRotation(Surface.ROTATION_0)
+                            }
+                            test {
+                                testApp.exit()
+                            }
+                        }
+                    }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt
index d31c4ba..72efdb1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt
@@ -43,12 +43,12 @@
     }
 }
 
-fun LayersAssertion.wallpaperLayerBecomesInvisible(
+fun LayersAssertion.appLayerReplacesWallpaperLayer(
     testApp: IAppHelper,
     bugId: Int = 0,
     enabled: Boolean = bugId == 0
 ) {
-    all("wallpaperLayerBecomesInvisible", bugId, enabled) {
+    all("appLayerReplacesWallpaperLayer", bugId, enabled) {
         this.showsLayer("Wallpaper")
                 .then()
                 .replaceVisibleLayer("Wallpaper", testApp.getPackage())
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index ad23d9f..1f03c4d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -38,6 +38,8 @@
 import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
 import com.android.server.wm.flicker.statusBarLayerRotatesScales
 import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
 import org.junit.FixMethodOrder
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -87,6 +89,7 @@
                         windowManagerTrace {
                             navBarWindowIsAlwaysVisible()
                             statusBarWindowIsAlwaysVisible()
+                            visibleWindowsShownMoreThanOneConsecutiveEntry()
 
                             appWindowReplacesLauncherAsTopWindow(testApp)
                             wallpaperWindowBecomesInvisible()
@@ -102,8 +105,10 @@
                                 configuration.endRotation)
                             navBarLayerIsAlwaysVisible(enabled = false)
                             statusBarLayerIsAlwaysVisible(enabled = false)
+                            visibleLayersShownMoreThanOneConsecutiveEntry(
+                                    enabled = Surface.ROTATION_0 == configuration.endRotation)
 
-                            wallpaperLayerBecomesInvisible(testApp)
+                            appLayerReplacesWallpaperLayer(testApp)
                         }
 
                         eventLog {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
new file mode 100644
index 0000000..0c584f4
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+package com.android.server.wm.flicker.launch
+
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.Flicker
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.focusChanges
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.helpers.StandardAppHelper
+import com.android.server.wm.flicker.helpers.reopenAppFromOverview
+import com.android.server.wm.flicker.helpers.hasWindow
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.repetitions
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Launch an app from the recents app view (the overview)
+ * To run this test: `atest FlickerTests:OpenAppFromOverviewTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppFromOverviewTest(
+    testName: String,
+    flickerSpec: Flicker
+) : FlickerTestRunner(testName, flickerSpec) {
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<Array<Any>> {
+            val instrumentation = InstrumentationRegistry.getInstrumentation()
+            val testApp = StandardAppHelper(instrumentation,
+                    "com.android.server.wm.flicker.testapp", "SimpleApp")
+            return FlickerTestRunnerFactory(instrumentation, repetitions = 10)
+                    .buildTest { configuration ->
+                        withTag { buildTestTag("openAppFromOverview", testApp, configuration) }
+                        repeat { configuration.repetitions }
+                        setup {
+                            test {
+                                device.wakeUpAndGoToHomeScreen()
+                                testApp.open()
+                            }
+                            eachRun {
+                                device.pressHome()
+                                device.pressRecentApps()
+                                this.setRotation(configuration.startRotation)
+                            }
+                        }
+                        transitions {
+                            device.reopenAppFromOverview()
+                            device.hasWindow(testApp.getPackage())
+                        }
+                        teardown {
+                            test {
+                                testApp.exit()
+                                this.setRotation(Surface.ROTATION_0)
+                            }
+                        }
+                        assertions {
+                            windowManagerTrace {
+                                navBarWindowIsAlwaysVisible()
+                                statusBarWindowIsAlwaysVisible()
+                                visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+                                appWindowReplacesLauncherAsTopWindow(testApp)
+                                wallpaperWindowBecomesInvisible()
+                            }
+
+                            layersTrace {
+                                noUncoveredRegions(Surface.ROTATION_0, configuration.endRotation,
+                                        bugId = 141361128)
+                                navBarLayerRotatesAndScales(Surface.ROTATION_0,
+                                        configuration.endRotation)
+                                statusBarLayerRotatesScales(Surface.ROTATION_0,
+                                        configuration.endRotation)
+                                statusBarLayerIsAlwaysVisible(
+                                        enabled = Surface.ROTATION_0 == configuration.endRotation)
+                                navBarLayerIsAlwaysVisible(
+                                        enabled = Surface.ROTATION_0 == configuration.endRotation)
+                                visibleLayersShownMoreThanOneConsecutiveEntry(
+                                        enabled = Surface.ROTATION_0 == configuration.endRotation)
+
+                                appLayerReplacesWallpaperLayer(testApp)
+                            }
+
+                            eventLog {
+                                focusChanges("NexusLauncherActivity", testApp.`package`)
+                            }
+                        }
+                    }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index 5886a61..9b4223a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -38,6 +38,8 @@
 import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
 import com.android.server.wm.flicker.statusBarLayerRotatesScales
 import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
 import org.junit.FixMethodOrder
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -91,9 +93,10 @@
                         windowManagerTrace {
                             navBarWindowIsAlwaysVisible()
                             statusBarWindowIsAlwaysVisible()
+                            visibleWindowsShownMoreThanOneConsecutiveEntry()
 
                             appWindowReplacesLauncherAsTopWindow(testApp)
-                            wallpaperWindowBecomesInvisible(enabled = false)
+                            wallpaperWindowBecomesInvisible()
                         }
 
                         layersTrace {
@@ -106,8 +109,10 @@
                                 configuration.endRotation)
                             navBarLayerIsAlwaysVisible(enabled = false)
                             statusBarLayerIsAlwaysVisible(enabled = false)
+                            visibleLayersShownMoreThanOneConsecutiveEntry(
+                                    enabled = Surface.ROTATION_0 == configuration.endRotation)
 
-                            wallpaperLayerBecomesInvisible(testApp)
+                            appLayerReplacesWallpaperLayer(testApp)
                         }
 
                         eventLog {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 24ca311..0db064a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -5,7 +5,7 @@
  * 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
+ * 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,
@@ -17,8 +17,8 @@
 package com.android.server.wm.flicker.rotation
 
 import android.platform.test.annotations.Presubmit
-import androidx.test.filters.RequiresDevice
 import android.view.Surface
+import androidx.test.filters.RequiresDevice
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.server.wm.flicker.Flicker
 import com.android.server.wm.flicker.FlickerTestRunner
@@ -27,8 +27,8 @@
 import com.android.server.wm.flicker.focusDoesNotChange
 import com.android.server.wm.flicker.helpers.StandardAppHelper
 import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
 import com.android.server.wm.flicker.navBarLayerRotatesAndScales
@@ -36,6 +36,8 @@
 import com.android.server.wm.flicker.noUncoveredRegions
 import com.android.server.wm.flicker.repetitions
 import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
 import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
 import com.android.server.wm.flicker.statusBarLayerRotatesScales
 import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
@@ -46,7 +48,7 @@
 
 /**
  * Cycle through supported app rotations.
- * To run this test: `atest FlickerTest:ChangeAppRotationTest`
+ * To run this test: `atest FlickerTests:ChangeAppRotationTest`
  */
 @Presubmit
 @RequiresDevice
@@ -96,6 +98,7 @@
                         windowManagerTrace {
                             navBarWindowIsAlwaysVisible()
                             statusBarWindowIsAlwaysVisible()
+                            visibleWindowsShownMoreThanOneConsecutiveEntry()
                         }
 
                         layersTrace {
@@ -107,6 +110,7 @@
                                 configuration.endRotation)
                             statusBarLayerRotatesScales(configuration.startRotation,
                                 configuration.endRotation)
+                            visibleLayersShownMoreThanOneConsecutiveEntry(bugId = 140855415)
                         }
 
                         layersTrace {
@@ -128,7 +132,7 @@
                                         .then()
                                         .showsLayer(SCREENSHOT_LAYER)
                                         .then()
-                                showsLayer(testApp.getPackage())
+                                        .showsLayer(testApp.getPackage())
                             }
                         }
 
diff --git a/tests/GamePerformance/Android.bp b/tests/GamePerformance/Android.bp
index 648fd81..02908d3 100644
--- a/tests/GamePerformance/Android.bp
+++ b/tests/GamePerformance/Android.bp
@@ -22,7 +22,7 @@
         enabled: false,
     },
     srcs: ["src/**/*.java"],
-    static_libs: ["android-support-test"],
+    static_libs: ["androidx.test.rules"],
     libs: [
         "android.test.base",
         "android.test.runner",
diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp
index 0e9f723..a8aab2a 100644
--- a/tests/Input/Android.bp
+++ b/tests/Input/Android.bp
@@ -6,7 +6,6 @@
     static_libs: [
             "androidx.test.ext.junit",
             "androidx.test.rules",
-            "android-support-test",
             "ub-uiautomator",
         ],
     test_suites: ["device-tests"],
diff --git a/tests/NullHomeTest/Android.bp b/tests/NullHomeTest/Android.bp
index 99248bf..fc71d0d 100644
--- a/tests/NullHomeTest/Android.bp
+++ b/tests/NullHomeTest/Android.bp
@@ -17,6 +17,6 @@
     srcs: ["src/**/*.java"],
     certificate: "platform",
     platform_apis: true,
-    static_libs: ["android-support-test"],
+    static_libs: ["androidx.test.rules"],
     test_suites: ["device-tests"],
 }
diff --git a/tests/NullHomeTest/AndroidManifest.xml b/tests/NullHomeTest/AndroidManifest.xml
index dc6402e..6f77781 100644
--- a/tests/NullHomeTest/AndroidManifest.xml
+++ b/tests/NullHomeTest/AndroidManifest.xml
@@ -21,7 +21,7 @@
     <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />
 
     <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:name="androidx.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.test.nullhome"
         android:label="Check if no null Home exists/is enabled" />
 
diff --git a/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java b/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java
index 1d77cdc5..3ec3ef2 100644
--- a/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java
+++ b/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java
@@ -18,9 +18,10 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.support.test.InstrumentationRegistry;
 import android.util.Log;
 
+import androidx.test.InstrumentationRegistry;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index ae93a81..fa0574a5 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -376,7 +376,7 @@
         TestObserver observer = new TestObserver(OBSERVER_NAME_1) {
                 @Override
                 public int onHealthCheckFailed(VersionedPackage versionedPackage,
-                        int failureReason) {
+                        int failureReason, int mitigationCount) {
                     if (versionedPackage.getVersionCode() == VERSION_CODE) {
                         // Only rollback for specific versionCode
                         return PackageHealthObserverImpact.USER_IMPACT_MEDIUM;
@@ -1146,6 +1146,45 @@
         assertThat(observer.mMitigatedPackages).isEqualTo(List.of(APP_A));
     }
 
+    /**
+     * Ensure that the sliding window logic results in the correct mitigation count being sent to
+     * an observer.
+     */
+    @Test
+    public void testMitigationSlidingWindow() {
+        PackageWatchdog watchdog = createWatchdog();
+        TestObserver observer = new TestObserver(OBSERVER_NAME_1);
+        watchdog.startObservingHealth(observer, List.of(APP_A),
+                PackageWatchdog.DEFAULT_OBSERVING_DURATION_MS * 2);
+
+
+        raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
+                VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN);
+
+        moveTimeForwardAndDispatch(TimeUnit.MINUTES.toMillis(10));
+
+        raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
+                VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN);
+        raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
+                VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN);
+
+        moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS);
+
+        // The first failure will be outside the threshold.
+        raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
+                VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN);
+
+        moveTimeForwardAndDispatch(TimeUnit.MINUTES.toMillis(20));
+
+        // The next 2 failures will also be outside the threshold.
+        raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
+                VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN);
+        raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
+                VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN);
+
+        assertThat(observer.mMitigationCounts).isEqualTo(List.of(1, 2, 3, 3, 2, 3));
+    }
+
     private void adoptShellPermissions(String... permissions) {
         InstrumentationRegistry
                 .getInstrumentation()
@@ -1227,6 +1266,7 @@
         private boolean mMitigatedBootLoop = false;
         final List<String> mHealthCheckFailedPackages = new ArrayList<>();
         final List<String> mMitigatedPackages = new ArrayList<>();
+        final List<Integer> mMitigationCounts = new ArrayList<>();
 
         TestObserver(String name) {
             mName = name;
@@ -1238,13 +1278,16 @@
             mImpact = impact;
         }
 
-        public int onHealthCheckFailed(VersionedPackage versionedPackage, int failureReason) {
+        public int onHealthCheckFailed(VersionedPackage versionedPackage, int failureReason,
+                int mitigationCount) {
             mHealthCheckFailedPackages.add(versionedPackage.getPackageName());
             return mImpact;
         }
 
-        public boolean execute(VersionedPackage versionedPackage, int failureReason) {
+        public boolean execute(VersionedPackage versionedPackage, int failureReason,
+                int mitigationCount) {
             mMitigatedPackages.add(versionedPackage.getPackageName());
+            mMitigationCounts.add(mitigationCount);
             mLastFailureReason = failureReason;
             return true;
         }
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 11a83eb..6b7ea66 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -359,7 +359,7 @@
         assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities()));
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.R)
     public void testOemPrivate() {
         NetworkCapabilities nc = new NetworkCapabilities();
         // By default OEM_PRIVATE is neither in the unwanted or required lists and the network is
diff --git a/tests/net/common/java/android/net/OemNetworkPreferencesTest.java b/tests/net/common/java/android/net/OemNetworkPreferencesTest.java
new file mode 100644
index 0000000..b77ed6a
--- /dev/null
+++ b/tests/net/common/java/android/net/OemNetworkPreferencesTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+package android.net;
+
+import static com.android.testutils.MiscAsserts.assertThrows;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.util.SparseArray;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class OemNetworkPreferencesTest {
+
+    private static final int TEST_PREF = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_DEFAULT;
+    private static final String TEST_PACKAGE = "com.google.apps.contacts";
+
+    private final List<String> mPackages = new ArrayList<>();
+    private final OemNetworkPreferences.Builder mBuilder = new OemNetworkPreferences.Builder();
+
+    @Before
+    public void beforeEachTestMethod() {
+        mPackages.add(TEST_PACKAGE);
+    }
+
+    @Test
+    public void builderAddNetworkPreferenceRequiresNonNullPackages() {
+        assertThrows(NullPointerException.class,
+                () -> mBuilder.addNetworkPreference(TEST_PREF, null));
+    }
+
+    @Test
+    public void getNetworkPreferencesReturnsCorrectValue() {
+        final int expectedNumberOfMappings = 1;
+        mBuilder.addNetworkPreference(TEST_PREF, mPackages);
+
+        final SparseArray<List<String>> networkPreferences =
+                mBuilder.build().getNetworkPreferences();
+
+        assertEquals(expectedNumberOfMappings, networkPreferences.size());
+        assertEquals(mPackages.size(), networkPreferences.get(TEST_PREF).size());
+        assertEquals(mPackages.get(0), networkPreferences.get(TEST_PREF).get(0));
+    }
+
+    @Test
+    public void getNetworkPreferencesReturnsUnmodifiableValue() {
+        final String newPackage = "new.com.google.apps.contacts";
+        mBuilder.addNetworkPreference(TEST_PREF, mPackages);
+
+        final SparseArray<List<String>> networkPreferences =
+                mBuilder.build().getNetworkPreferences();
+
+        assertThrows(UnsupportedOperationException.class,
+                () -> networkPreferences.get(TEST_PREF).set(mPackages.size() - 1, newPackage));
+
+        assertThrows(UnsupportedOperationException.class,
+                () -> networkPreferences.get(TEST_PREF).add(newPackage));
+    }
+
+    @Test
+    public void toStringReturnsCorrectValue() {
+        mBuilder.addNetworkPreference(TEST_PREF, mPackages);
+
+        final String networkPreferencesString = mBuilder.build().getNetworkPreferences().toString();
+
+        assertTrue(networkPreferencesString.contains(Integer.toString(TEST_PREF)));
+        assertTrue(networkPreferencesString.contains(TEST_PACKAGE));
+    }
+
+    @Test
+    public void testOemNetworkPreferencesParcelable() {
+        mBuilder.addNetworkPreference(TEST_PREF, mPackages);
+
+        final OemNetworkPreferences prefs = mBuilder.build();
+
+        assertParcelSane(prefs, 1 /* fieldCount */);
+    }
+}
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
index 91c9a2a..6de31f6 100644
--- a/tests/net/java/android/net/MacAddressTest.java
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -22,11 +22,11 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.net.util.MacAddressUtils;
-
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.net.module.util.MacAddressUtils;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
index de1028c..c53462c 100644
--- a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
+++ b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
@@ -34,6 +34,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -53,6 +54,7 @@
 import android.net.StringNetworkSpecifier;
 import android.net.TelephonyNetworkSpecifier;
 import android.os.Handler;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.test.mock.MockContentResolver;
@@ -91,6 +93,7 @@
     private static final int POLICY_SNOOZED = -100;
 
     @Mock private Context mContext;
+    @Mock private Context mUserAllContext;
     @Mock private Resources mResources;
     @Mock private Handler mHandler;
     @Mock private MultipathPolicyTracker.Dependencies mDeps;
@@ -127,8 +130,11 @@
 
         when(mContext.getResources()).thenReturn(mResources);
         when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
-        when(mContext.registerReceiverAsUser(mConfigChangeReceiverCaptor.capture(),
-                any(), argThat(f -> f.hasAction(ACTION_CONFIGURATION_CHANGED)), any(), any()))
+        doReturn(UserHandle.ALL.getIdentifier()).when(mUserAllContext).getUserId();
+        when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt()))
+                .thenReturn(mUserAllContext);
+        when(mUserAllContext.registerReceiver(mConfigChangeReceiverCaptor.capture(),
+                argThat(f -> f.hasAction(ACTION_CONFIGURATION_CHANGED)), any(), any()))
                 .thenReturn(null);
 
         when(mDeps.getClock()).thenReturn(mClock);
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index e3ba3e1..1dcc07c 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -241,7 +241,7 @@
         doNothing().when(mNetService).registerObserver(any());
 
         // Deny all appops by default.
-        when(mAppOps.noteOpNoThrow(anyInt(), anyInt(), anyString()))
+        when(mAppOps.noteOpNoThrow(anyString(), anyInt(), anyString(), any(), any()))
                 .thenReturn(AppOpsManager.MODE_IGNORED);
 
         // Setup IpSecService
@@ -729,26 +729,27 @@
         assertEquals(expected, vpn.getProfileNameForPackage(TEST_VPN_PKG));
     }
 
-    private Vpn createVpnAndSetupUidChecks(int... grantedOps) throws Exception {
+    private Vpn createVpnAndSetupUidChecks(String... grantedOps) throws Exception {
         return createVpnAndSetupUidChecks(primaryUser, grantedOps);
     }
 
-    private Vpn createVpnAndSetupUidChecks(UserInfo user, int... grantedOps) throws Exception {
+    private Vpn createVpnAndSetupUidChecks(UserInfo user, String... grantedOps) throws Exception {
         final Vpn vpn = createVpn(user.id);
         setMockedUsers(user);
 
         when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt()))
                 .thenReturn(Process.myUid());
 
-        for (final int op : grantedOps) {
-            when(mAppOps.noteOpNoThrow(op, Process.myUid(), TEST_VPN_PKG))
+        for (final String opStr : grantedOps) {
+            when(mAppOps.noteOpNoThrow(opStr, Process.myUid(), TEST_VPN_PKG,
+                    null /* attributionTag */, null /* message */))
                     .thenReturn(AppOpsManager.MODE_ALLOWED);
         }
 
         return vpn;
     }
 
-    private void checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, int... checkedOps) {
+    private void checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, String... checkedOps) {
         assertEquals(expectedResult, vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile, mKeyStore));
 
         // The profile should always be stored, whether or not consent has been previously granted.
@@ -759,8 +760,9 @@
                         eq(Process.SYSTEM_UID),
                         eq(0));
 
-        for (final int checkedOp : checkedOps) {
-            verify(mAppOps).noteOpNoThrow(checkedOp, Process.myUid(), TEST_VPN_PKG);
+        for (final String checkedOpStr : checkedOps) {
+            verify(mAppOps).noteOpNoThrow(checkedOpStr, Process.myUid(), TEST_VPN_PKG,
+                    null /* attributionTag */, null /* message */);
         }
     }
 
@@ -768,11 +770,11 @@
     public void testProvisionVpnProfileNoIpsecTunnels() throws Exception {
         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS))
                 .thenReturn(false);
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             checkProvisionVpnProfile(
-                    vpn, true /* expectedResult */, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                    vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
             fail("Expected exception due to missing feature");
         } catch (UnsupportedOperationException expected) {
         }
@@ -780,10 +782,10 @@
 
     @Test
     public void testProvisionVpnProfilePreconsented() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         checkProvisionVpnProfile(
-                vpn, true /* expectedResult */, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
     }
 
     @Test
@@ -793,19 +795,19 @@
         // Expect that both the ACTIVATE_VPN and ACTIVATE_PLATFORM_VPN were tried, but the caller
         // had neither.
         checkProvisionVpnProfile(vpn, false /* expectedResult */,
-                AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, AppOpsManager.OP_ACTIVATE_VPN);
+                AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, AppOpsManager.OPSTR_ACTIVATE_VPN);
     }
 
     @Test
     public void testProvisionVpnProfileVpnServicePreconsented() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN);
 
-        checkProvisionVpnProfile(vpn, true /* expectedResult */, AppOpsManager.OP_ACTIVATE_VPN);
+        checkProvisionVpnProfile(vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_VPN);
     }
 
     @Test
     public void testProvisionVpnProfileTooLarge() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         final VpnProfile bigProfile = new VpnProfile("");
         bigProfile.name = new String(new byte[Vpn.MAX_VPN_PROFILE_SIZE_BYTES + 1]);
@@ -821,7 +823,7 @@
     public void testProvisionVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile, mKeyStore);
@@ -844,7 +846,7 @@
     public void testDeleteVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.deleteVpnProfile(TEST_VPN_PKG, mKeyStore);
@@ -867,7 +869,7 @@
 
     @Test
     public void testStartVpnProfile() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
                 .thenReturn(mVpnProfile.encode());
@@ -877,14 +879,16 @@
         verify(mKeyStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
         verify(mAppOps)
                 .noteOpNoThrow(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
-                        eq(TEST_VPN_PKG));
+                        eq(TEST_VPN_PKG),
+                        eq(null) /* attributionTag */,
+                        eq(null) /* message */);
     }
 
     @Test
     public void testStartVpnProfileVpnServicePreconsented() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN);
 
         when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
                 .thenReturn(mVpnProfile.encode());
@@ -892,7 +896,8 @@
         vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
 
         // Verify that the the ACTIVATE_VPN appop was checked, but no error was thrown.
-        verify(mAppOps).noteOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN, Process.myUid(), TEST_VPN_PKG);
+        verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(),
+                TEST_VPN_PKG, null /* attributionTag */, null /* message */);
     }
 
     @Test
@@ -908,10 +913,13 @@
         // Verify both appops were checked.
         verify(mAppOps)
                 .noteOpNoThrow(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
-                        eq(TEST_VPN_PKG));
-        verify(mAppOps).noteOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN, Process.myUid(), TEST_VPN_PKG);
+                        eq(TEST_VPN_PKG),
+                        eq(null) /* attributionTag */,
+                        eq(null) /* message */);
+        verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(),
+                TEST_VPN_PKG, null /* attributionTag */, null /* message */);
 
         // Keystore should never have been accessed.
         verify(mKeyStore, never()).get(any());
@@ -919,7 +927,7 @@
 
     @Test
     public void testStartVpnProfileMissingProfile() throws Exception {
-        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+        final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         when(mKeyStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))).thenReturn(null);
 
@@ -932,16 +940,18 @@
         verify(mKeyStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG));
         verify(mAppOps)
                 .noteOpNoThrow(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
-                        eq(TEST_VPN_PKG));
+                        eq(TEST_VPN_PKG),
+                        eq(null) /* attributionTag */,
+                        eq(null) /* message */);
     }
 
     @Test
     public void testStartVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.startVpnProfile(TEST_VPN_PKG, mKeyStore);
@@ -954,7 +964,7 @@
     public void testStopVpnProfileRestrictedUser() throws Exception {
         final Vpn vpn =
                 createVpnAndSetupUidChecks(
-                        restrictedProfileA, AppOpsManager.OP_ACTIVATE_PLATFORM_VPN);
+                        restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
 
         try {
             vpn.stopVpnProfile(TEST_VPN_PKG);
@@ -970,7 +980,7 @@
         assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_SERVICE));
         verify(mAppOps)
                 .setMode(
-                        eq(AppOpsManager.OP_ACTIVATE_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_VPN),
                         eq(Process.myUid()),
                         eq(TEST_VPN_PKG),
                         eq(AppOpsManager.MODE_ALLOWED));
@@ -983,7 +993,7 @@
         assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_PLATFORM));
         verify(mAppOps)
                 .setMode(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
                         eq(TEST_VPN_PKG),
                         eq(AppOpsManager.MODE_ALLOWED));
@@ -996,13 +1006,13 @@
         assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_NONE));
         verify(mAppOps)
                 .setMode(
-                        eq(AppOpsManager.OP_ACTIVATE_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_VPN),
                         eq(Process.myUid()),
                         eq(TEST_VPN_PKG),
                         eq(AppOpsManager.MODE_IGNORED));
         verify(mAppOps)
                 .setMode(
-                        eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
+                        eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
                         eq(Process.myUid()),
                         eq(TEST_VPN_PKG),
                         eq(AppOpsManager.MODE_IGNORED));
@@ -1059,7 +1069,7 @@
 
         verify(mKeyStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
         verify(mAppOps).setMode(
-                eq(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN), eq(uid), eq(TEST_VPN_PKG),
+                eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), eq(uid), eq(TEST_VPN_PKG),
                 eq(AppOpsManager.MODE_ALLOWED));
 
         verify(mSystemServices).settingsSecurePutStringForUser(
diff --git a/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java b/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
index f80af03..ec47550 100644
--- a/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
+++ b/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
@@ -214,7 +214,7 @@
     private File copyResourceToTemp(String resourcePath) throws IOException {
         final File tempFile = mHostTempFolder.newFile();
         final ClassLoader classLoader = getClass().getClassLoader();
-        try (InputStream assetIs = classLoader.getResource(resourcePath).openStream();
+        try (InputStream assetIs = classLoader.getResourceAsStream(resourcePath);
              FileOutputStream assetOs = new FileOutputStream(tempFile)) {
             if (assetIs == null) {
                 throw new IllegalStateException("Failed to find resource " + resourcePath);
diff --git a/tests/vcn/Android.bp b/tests/vcn/Android.bp
new file mode 100644
index 0000000..f967bf0
--- /dev/null
+++ b/tests/vcn/Android.bp
@@ -0,0 +1,27 @@
+//########################################################################
+// Build FrameworksVcnTests package
+//########################################################################
+
+android_test {
+    name: "FrameworksVcnTests",
+    srcs: [
+        "java/**/*.java",
+        "java/**/*.kt",
+    ],
+    platform_apis: true,
+    test_suites: ["device-tests"],
+    certificate: "platform",
+    static_libs: [
+        "androidx.test.rules",
+        "frameworks-base-testutils",
+        "framework-protos",
+        "mockito-target-minus-junit4",
+        "platform-test-annotations",
+        "services.core",
+    ],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
+}
diff --git a/tests/vcn/AndroidManifest.xml b/tests/vcn/AndroidManifest.xml
new file mode 100644
index 0000000..2ad9aac
--- /dev/null
+++ b/tests/vcn/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.frameworks.tests.vcn">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.frameworks.tests.vcn"
+        android:label="Frameworks VCN Tests" />
+</manifest>
diff --git a/tests/vcn/AndroidTest.xml b/tests/vcn/AndroidTest.xml
new file mode 100644
index 0000000..dc521fd
--- /dev/null
+++ b/tests/vcn/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<configuration description="Runs VCN Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="FrameworksVcnTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="FrameworksVcnTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.frameworks.tests.vcn" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/tests/vcn/TEST_MAPPING b/tests/vcn/TEST_MAPPING
new file mode 100644
index 0000000..54fa411
--- /dev/null
+++ b/tests/vcn/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksVcnTests"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tools/codegen/src/com/android/codegen/ClassInfo.kt b/tools/codegen/src/com/android/codegen/ClassInfo.kt
index bf95a2e..056898c 100644
--- a/tools/codegen/src/com/android/codegen/ClassInfo.kt
+++ b/tools/codegen/src/com/android/codegen/ClassInfo.kt
@@ -1,12 +1,14 @@
 package com.android.codegen
 
 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+import com.github.javaparser.ast.body.TypeDeclaration
 
 open class ClassInfo(val classAst: ClassOrInterfaceDeclaration, val fileInfo: FileInfo) {
 
     val fileAst = fileInfo.fileAst
 
     val nestedClasses = classAst.members.filterIsInstance<ClassOrInterfaceDeclaration>()
+    val nestedTypes = classAst.members.filterIsInstance<TypeDeclaration<*>>()
 
     val superInterfaces = classAst.implementedTypes.map { it.asString() }
     val superClass = classAst.extendedTypes.getOrNull(0)
diff --git a/tools/codegen/src/com/android/codegen/InputSignaturesComputation.kt b/tools/codegen/src/com/android/codegen/InputSignaturesComputation.kt
index 69ff18d..83108e5 100644
--- a/tools/codegen/src/com/android/codegen/InputSignaturesComputation.kt
+++ b/tools/codegen/src/com/android/codegen/InputSignaturesComputation.kt
@@ -63,6 +63,7 @@
         append("@")
         append(getFullClassName(ann.nameAsString))
         if (ann is MarkerAnnotationExpr) return@buildString
+        if (!ann.nameAsString.startsWith("DataClass")) return@buildString
 
         append("(")
 
@@ -128,7 +129,7 @@
 
     if (classAst.nameAsString == className) return thisPackagePrefix + classAst.nameAsString
 
-    nestedClasses.find {
+    nestedTypes.find {
         it.nameAsString == className
     }?.let { return thisClassPrefix + it.nameAsString }
 
diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt
index ca658a9..2e176c3 100644
--- a/tools/codegen/src/com/android/codegen/SharedConstants.kt
+++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt
@@ -1,7 +1,7 @@
 package com.android.codegen
 
 const val CODEGEN_NAME = "codegen"
-const val CODEGEN_VERSION = "1.0.18"
+const val CODEGEN_VERSION = "1.0.20"
 
 const val CANONICAL_BUILDER_CLASS = "Builder"
 const val BASE_BUILDER_CLASS = "BaseBuilder"
diff --git a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
index 51faa49..1aec9b8 100644
--- a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
+++ b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
@@ -98,8 +98,10 @@
 
     private fun elemToString(elem: Element): String {
         return buildString {
-            append(elem.modifiers.joinToString(" ") { it.name.toLowerCase() }).append(" ")
-            append(elem.annotationMirrors.joinToString(" ")).append(" ")
+            append(elem.modifiers.joinToString(" ") { it.name.toLowerCase() })
+            append(" ")
+            append(elem.annotationMirrors.joinToString(" ", transform = { annotationToString(it) }))
+            append(" ")
             if (elem is Symbol) {
                 if (elem.type is Type.MethodType) {
                     append((elem.type as Type.MethodType).returnType)
@@ -112,6 +114,14 @@
         }
     }
 
+    private fun annotationToString(ann: AnnotationMirror): String {
+        return if (ann.annotationType.toString().startsWith("com.android.internal.util.DataClass")) {
+            ann.toString()
+        } else {
+            ann.toString().substringBefore("(")
+        }
+    }
+
     private fun processSingleFile(elementAnnotatedWithGenerated: Element) {
 
         val classElement = elementAnnotatedWithGenerated.enclosingElement
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 43387fc..ab8702b 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -142,6 +142,9 @@
                 "libstatspull",
             ],
         },
+        darwin: {
+            enabled: false,
+        },
     },
 }
 
diff --git a/tools/validatekeymaps/Android.bp b/tools/validatekeymaps/Android.bp
index 2759e29..15b8b41 100644
--- a/tools/validatekeymaps/Android.bp
+++ b/tools/validatekeymaps/Android.bp
@@ -16,18 +16,25 @@
 
     static_libs: [
         "libbase",
-        "libbinder",
         "libinput",
         "libutils",
         "libcutils",
         "liblog",
         "libui-types",
     ],
+    target: {
+        linux_glibc: {
+            static_libs: [
+                // libbinder is only available for linux
+                "libbinder",
+            ],
+        },
+    },
 
     // This tool is prebuilt if we're doing an app-only build.
     product_variables: {
         unbundled_build: {
-          enabled: false,
+            enabled: false,
         },
     },
 }
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 0af6266..950473d 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -26,15 +26,15 @@
 
 using namespace android;
 
-static const char* kProgName = "validatekeymaps";
+static const char* PROG_NAME = "validatekeymaps";
 static bool gQuiet = false;
 
-enum FileType {
-    FILETYPE_UNKNOWN,
-    FILETYPE_KEYLAYOUT,
-    FILETYPE_KEYCHARACTERMAP,
-    FILETYPE_VIRTUALKEYDEFINITION,
-    FILETYPE_INPUTDEVICECONFIGURATION,
+enum class FileType {
+    UNKNOWN,
+    KEY_LAYOUT,
+    KEY_CHARACTER_MAP,
+    VIRTUAL_KEY_DEFINITION,
+    INPUT_DEVICE_CONFIGURATION,
 };
 
 static void log(const char* fmt, ...) {
@@ -57,33 +57,32 @@
 static void usage() {
     error("Keymap Validation Tool\n\n");
     error("Usage:\n");
-    error(
-        " %s [-q] [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]\n"
-        "   Validates the specified key layouts, key character maps, \n"
-        "   input device configurations, or virtual key definitions.\n\n"
-        "   -q Quiet; do not write anything to standard out.\n",
-        kProgName);
+    error(" %s [-q] [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]\n"
+          "   Validates the specified key layouts, key character maps, \n"
+          "   input device configurations, or virtual key definitions.\n\n"
+          "   -q Quiet; do not write anything to standard out.\n",
+          PROG_NAME);
 }
 
 static FileType getFileType(const char* filename) {
     const char *extension = strrchr(filename, '.');
     if (extension) {
         if (strcmp(extension, ".kl") == 0) {
-            return FILETYPE_KEYLAYOUT;
+            return FileType::KEY_LAYOUT;
         }
         if (strcmp(extension, ".kcm") == 0) {
-            return FILETYPE_KEYCHARACTERMAP;
+            return FileType::KEY_CHARACTER_MAP;
         }
         if (strcmp(extension, ".idc") == 0) {
-            return FILETYPE_INPUTDEVICECONFIGURATION;
+            return FileType::INPUT_DEVICE_CONFIGURATION;
         }
     }
 
     if (strstr(filename, "virtualkeys.")) {
-        return FILETYPE_VIRTUALKEYDEFINITION;
+        return FileType::VIRTUAL_KEY_DEFINITION;
     }
 
-    return FILETYPE_UNKNOWN;
+    return FileType::UNKNOWN;
 }
 
 static bool validateFile(const char* filename) {
@@ -91,48 +90,49 @@
 
     FileType fileType = getFileType(filename);
     switch (fileType) {
-    case FILETYPE_UNKNOWN:
-        error("Supported file types: *.kl, *.kcm, virtualkeys.*\n\n");
-        return false;
-
-    case FILETYPE_KEYLAYOUT: {
-        base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(filename);
-        if (!ret) {
-            error("Error %s parsing key layout file.\n\n", ret.error().message().c_str());
+        case FileType::UNKNOWN:
+            error("Supported file types: *.kl, *.kcm, virtualkeys.*\n\n");
             return false;
-        }
-        break;
-    }
 
-    case FILETYPE_KEYCHARACTERMAP: {
-        base::Result<std::shared_ptr<KeyCharacterMap>> ret = KeyCharacterMap::load(filename,
-                KeyCharacterMap::FORMAT_ANY);
-        if (!ret) {
-            error("Error %s parsing key character map file.\n\n", ret.error().message().c_str());
-            return false;
+        case FileType::KEY_LAYOUT: {
+            base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(filename);
+            if (!ret) {
+                error("Error %s parsing key layout file.\n\n", ret.error().message().c_str());
+                return false;
+            }
+            break;
         }
-        break;
-    }
 
-    case FILETYPE_INPUTDEVICECONFIGURATION: {
-        android::base::Result<std::unique_ptr<PropertyMap>> propertyMap =
-                PropertyMap::load(String8(filename));
-        if (!propertyMap.ok()) {
-            error("Error %d parsing input device configuration file.\n\n",
-                  propertyMap.error().code());
-            return false;
+        case FileType::KEY_CHARACTER_MAP: {
+            base::Result<std::shared_ptr<KeyCharacterMap>> ret =
+                    KeyCharacterMap::load(filename, KeyCharacterMap::Format::ANY);
+            if (!ret) {
+                error("Error %s parsing key character map file.\n\n",
+                      ret.error().message().c_str());
+                return false;
+            }
+            break;
         }
-        break;
-    }
 
-    case FILETYPE_VIRTUALKEYDEFINITION: {
-        std::unique_ptr<VirtualKeyMap> map = VirtualKeyMap::load(filename);
-        if (!map) {
-            error("Error while parsing virtual key definition file.\n\n");
-            return false;
+        case FileType::INPUT_DEVICE_CONFIGURATION: {
+            android::base::Result<std::unique_ptr<PropertyMap>> propertyMap =
+                    PropertyMap::load(String8(filename));
+            if (!propertyMap.ok()) {
+                error("Error %d parsing input device configuration file.\n\n",
+                      propertyMap.error().code());
+                return false;
+            }
+            break;
         }
-        break;
-    }
+
+        case FileType::VIRTUAL_KEY_DEFINITION: {
+            std::unique_ptr<VirtualKeyMap> map = VirtualKeyMap::load(filename);
+            if (!map) {
+                error("Error while parsing virtual key definition file.\n\n");
+                return false;
+            }
+            break;
+        }
     }
 
     return true;
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
index d5ef703..3b8c33c 100644
--- a/wifi/api/current.txt
+++ b/wifi/api/current.txt
@@ -105,6 +105,8 @@
     field @Deprecated public String FQDN;
     field @Deprecated public static final int SECURITY_TYPE_EAP = 3; // 0x3
     field @Deprecated public static final int SECURITY_TYPE_EAP_SUITE_B = 5; // 0x5
+    field @Deprecated public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE = 9; // 0x9
+    field @Deprecated public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT = 5; // 0x5
     field @Deprecated public static final int SECURITY_TYPE_OPEN = 0; // 0x0
     field @Deprecated public static final int SECURITY_TYPE_OWE = 6; // 0x6
     field @Deprecated public static final int SECURITY_TYPE_PSK = 2; // 0x2
@@ -342,6 +344,7 @@
     method public boolean isWapiSupported();
     method public boolean isWifiEnabled();
     method public boolean isWifiStandardSupported(int);
+    method public boolean isWpa3ApValidationSupported();
     method public boolean isWpa3SaeSupported();
     method public boolean isWpa3SuiteBSupported();
     method @Deprecated public boolean pingSupplicant();
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index ff06a18..d235c80 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -114,8 +114,6 @@
 ## used by both framework-wifi and service-wifi ##
 rule android.content.pm.BaseParceledListSlice* com.android.wifi.x.@0
 rule android.content.pm.ParceledListSlice* com.android.wifi.x.@0
-rule android.net.util.MacAddressUtils* com.android.wifi.x.@0
-rule android.net.util.nsd.DnsSdTxtRecord* com.android.wifi.x.@0
 rule android.os.HandlerExecutor* com.android.wifi.x.@0
 rule android.telephony.Annotation* com.android.wifi.x.@0
 rule com.android.internal.util.AsyncChannel* com.android.wifi.x.@0
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index c0f6e7a..e9d1a00 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -1026,9 +1026,17 @@
                         + channels.size() + ") configured");
             }
             for (int i = 0; i < channels.size(); i++) {
-                if (!isChannelBandPairValid(channels.valueAt(i), channels.keyAt(i))) {
-                    throw new IllegalArgumentException("Invalid channel(" + channels.valueAt(i)
-                            + ") & band (" + channels.keyAt(i) + ") configured");
+                int channel = channels.valueAt(i);
+                int band = channels.keyAt(i);
+                if (channel == 0) {
+                    if (!isBandValid(band)) {
+                        throw new IllegalArgumentException("Invalid band type: " + band);
+                    }
+                } else {
+                    if (!isChannelBandPairValid(channel, band)) {
+                        throw new IllegalArgumentException("Invalid channel(" + channel
+                                + ") & band (" + band + ") configured");
+                    }
                 }
             }
             mChannels = channels.clone();
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 8103ff7..1e2e122 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -29,7 +29,6 @@
 import android.net.ProxyInfo;
 import android.net.StaticIpConfiguration;
 import android.net.Uri;
-import android.net.util.MacAddressUtils;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -43,6 +42,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.MacAddressUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -439,14 +439,27 @@
     public static final int SECURITY_TYPE_EAP = 3;
     /** Security type for an SAE network. */
     public static final int SECURITY_TYPE_SAE = 4;
-    /** Security type for an EAP Suite B network. */
-    public static final int SECURITY_TYPE_EAP_SUITE_B = 5;
+    /**
+     * Security type for a WPA3-Enterprise in 192-bit security network.
+     * This is the same as {@link #SECURITY_TYPE_EAP_SUITE_B} and uses the same value.
+     */
+    public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT = 5;
+    /**
+     * Security type for a WPA3-Enterprise in 192-bit security network.
+     * @deprecated Use the {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT} constant
+     * (which is the same value).
+     */
+    @Deprecated
+    public static final int SECURITY_TYPE_EAP_SUITE_B =
+            SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT;
     /** Security type for an OWE network. */
     public static final int SECURITY_TYPE_OWE = 6;
     /** Security type for a WAPI PSK network. */
     public static final int SECURITY_TYPE_WAPI_PSK = 7;
     /** Security type for a WAPI Certificate network. */
     public static final int SECURITY_TYPE_WAPI_CERT = 8;
+    /** Security type for a WPA3-Enterprise network. */
+    public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE = 9;
 
     /**
      * Security types we support.
@@ -462,7 +475,9 @@
             SECURITY_TYPE_EAP_SUITE_B,
             SECURITY_TYPE_OWE,
             SECURITY_TYPE_WAPI_PSK,
-            SECURITY_TYPE_WAPI_CERT
+            SECURITY_TYPE_WAPI_CERT,
+            SECURITY_TYPE_EAP_WPA3_ENTERPRISE,
+            SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT,
     })
     public @interface SecurityType {}
 
@@ -478,8 +493,10 @@
      * {@link #SECURITY_TYPE_SAE},
      * {@link #SECURITY_TYPE_EAP_SUITE_B},
      * {@link #SECURITY_TYPE_OWE},
-     * {@link #SECURITY_TYPE_WAPI_PSK}, or
-     * {@link #SECURITY_TYPE_WAPI_CERT}
+     * {@link #SECURITY_TYPE_WAPI_PSK},
+     * {@link #SECURITY_TYPE_WAPI_CERT},
+     * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE},
+     * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}
      */
     public void setSecurityParams(@SecurityType int securityType) {
         // Clear all the bitsets.
@@ -518,7 +535,10 @@
                 allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
                 requirePmf = true;
                 break;
-            case SECURITY_TYPE_EAP_SUITE_B:
+            // The value of {@link SECURITY_TYPE_EAP_SUITE_B} is the same as
+            // {@link SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}, remove it to avoid
+            // duplicate case label errors.
+            case SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT:
                 allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
                 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
@@ -555,6 +575,16 @@
                 allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.SMS4);
                 allowedGroupCiphers.set(WifiConfiguration.GroupCipher.SMS4);
                 break;
+            case SECURITY_TYPE_EAP_WPA3_ENTERPRISE:
+                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+                allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+                allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+                allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
+                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+                allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+                requirePmf = true;
+                break;
             default:
                 throw new IllegalArgumentException("unknown security type " + securityType);
         }
@@ -1360,36 +1390,26 @@
          * @hide
          */
         public static final int NETWORK_SELECTION_DISABLED_STARTING_INDEX = 1;
-        /**
-         * The starting index for network selection temporarily disabled reasons.
-         * @hide
-         */
-        public static final int TEMPORARILY_DISABLED_STARTING_INDEX = 1;
-        /** This network is disabled because of multiple association rejections. */
+        /** This network is temporarily disabled because of multiple association rejections. */
         public static final int DISABLED_ASSOCIATION_REJECTION = 1;
-        /** This network is disabled because of multiple authentication failure. */
+        /** This network is temporarily disabled because of multiple authentication failure. */
         public static final int DISABLED_AUTHENTICATION_FAILURE = 2;
-        /** This network is disabled because of multiple DHCP failure. */
+        /** This network is temporarily disabled because of multiple DHCP failure. */
         public static final int DISABLED_DHCP_FAILURE = 3;
         /** This network is temporarily disabled because it has no Internet access. */
         public static final int DISABLED_NO_INTERNET_TEMPORARY = 4;
-        /**
-         * The starting index for network selection permanently disabled reasons.
-         * @hide
-         */
-        public static final int PERMANENTLY_DISABLED_STARTING_INDEX = 5;
-        /** This network is disabled due to absence of user credentials */
+        /** This network is permanently disabled due to absence of user credentials */
         public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5;
         /**
          * This network is permanently disabled because it has no Internet access and the user does
          * not want to stay connected.
          */
         public static final int DISABLED_NO_INTERNET_PERMANENT = 6;
-        /** This network is disabled due to WifiManager disabling it explicitly. */
+        /** This network is permanently disabled due to WifiManager disabling it explicitly. */
         public static final int DISABLED_BY_WIFI_MANAGER = 7;
-        /** This network is disabled due to wrong password. */
+        /** This network is permanently disabled due to wrong password. */
         public static final int DISABLED_BY_WRONG_PASSWORD = 8;
-        /** This network is disabled because service is not subscribed. */
+        /** This network is permanently disabled because service is not subscribed. */
         public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9;
         /**
          * All other disable reasons should be strictly less than this value.
@@ -1439,6 +1459,8 @@
             /**
              * Network Selection disable timeout for the error. After the timeout milliseconds,
              * enable the network again.
+             * If this is set to Integer.MAX_VALUE, the network will be permanently disabled until
+             * the next time the user manually connects to it.
              */
             public final int mDisableTimeoutMillis;
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8ee08f1..ef55a56 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2425,6 +2425,9 @@
     /** @hide */
     public static final long WIFI_FEATURE_FILS_SHA384     = 0x8000000000L; // FILS-SHA384
 
+    /** @hide */
+    public static final long WIFI_FEATURE_SAE_PK          = 0x10000000000L; // SAE-PK
+
     private long getSupportedFeatures() {
         try {
             return mService.getSupportedFeatures();
@@ -5330,6 +5333,13 @@
     }
 
     /**
+     * @return true if this device supports WPA3 AP validation.
+     */
+    public boolean isWpa3ApValidationSupported() {
+        return isFeatureSupported(WIFI_FEATURE_SAE_PK);
+    }
+
+    /**
      * Gets the factory Wi-Fi MAC addresses.
      * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array
      * if failed.
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
index 35853c0..be3b45d 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -367,20 +367,16 @@
                         && WifiEnterpriseConfig.isSuiteBCipherCert(
                         mWpa3EnterpriseConfig.getCaCertificate())) {
                     // WPA3-Enterprise in 192-bit security mode
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
+                    configuration.setSecurityParams(
+                            WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT);
                 } else if (mWpa3EnterpriseType == WPA3_ENTERPRISE_192_BIT) {
                     // WPA3-Enterprise in 192-bit security mode
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
+                    configuration.setSecurityParams(
+                            WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT);
                 } else {
                     // WPA3-Enterprise
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                    configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                    configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-                    configuration.allowedPairwiseCiphers.set(
-                            WifiConfiguration.PairwiseCipher.GCMP_256);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                    configuration.requirePmf = true;
+                    configuration.setSecurityParams(
+                            WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE);
                 }
                 configuration.enterpriseConfig = mWpa3EnterpriseConfig;
             } else if (mIsEnhancedOpen) { // OWE network
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index dc6ec90..61831ea 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -796,20 +796,16 @@
                         && WifiEnterpriseConfig.isSuiteBCipherCert(
                         mWpa3EnterpriseConfig.getCaCertificate())) {
                     // WPA3-Enterprise in 192-bit security mode
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
+                    configuration.setSecurityParams(
+                            WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT);
                 } else if (mWpa3EnterpriseType == WPA3_ENTERPRISE_192_BIT) {
                     // WPA3-Enterprise in 192-bit security mode
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
+                    configuration.setSecurityParams(
+                            WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT);
                 } else {
                     // WPA3-Enterprise
-                    configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
-                    configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-                    configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-                    configuration.allowedPairwiseCiphers.set(
-                            WifiConfiguration.PairwiseCipher.GCMP_256);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                    configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
-                    configuration.requirePmf = true;
+                    configuration.setSecurityParams(
+                            WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE);
                 }
                 configuration.enterpriseConfig = mWpa3EnterpriseConfig;
             } else if (mIsEnhancedOpen) { // OWE network
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
index dad431c1..e2f40cf 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
@@ -17,10 +17,11 @@
 package android.net.wifi.p2p.nsd;
 
 import android.compat.annotation.UnsupportedAppUsage;
-import android.net.util.nsd.DnsSdTxtRecord;
 import android.os.Build;
 import android.text.TextUtils;
 
+import com.android.net.module.util.DnsSdTxtRecord;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
index 4a94f1f..ad0fdd3 100644
--- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
@@ -398,6 +398,21 @@
         assertThat(dual_channels_config.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ);
         assertTrue(dual_channels.toString().equals(dual_channels_config.getChannels().toString()));
         assertThat(dual_channels_config.getChannel()).isEqualTo(2);
+
+        // Test different parameters.
+        dual_channels.clear();
+        dual_channels.put(SoftApConfiguration.BAND_5GHZ, 149);
+        dual_channels.put(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, 0);
+        expected_dual_bands[0] = SoftApConfiguration.BAND_5GHZ;
+        expected_dual_bands[1] = SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ;
+        dual_channels_config = new SoftApConfiguration.Builder()
+                .setSsid("ssid")
+                .setChannels(dual_channels)
+                .build();
+        assertTrue(Arrays.equals(expected_dual_bands, dual_channels_config.getBands()));
+        assertThat(dual_channels_config.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ);
+        assertTrue(dual_channels.toString().equals(dual_channels_config.getChannels().toString()));
+        assertThat(dual_channels_config.getChannel()).isEqualTo(149);
     }
 
     @Test
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
index f09c37d..756c735 100644
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -17,7 +17,8 @@
 package android.net.wifi;
 
 import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B;
+import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE;
+import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT;
 import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OPEN;
 import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OWE;
 import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_PSK;
@@ -33,13 +34,14 @@
 import static org.junit.Assert.assertTrue;
 
 import android.net.MacAddress;
-import android.net.util.MacAddressUtils;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
 import android.os.Parcel;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.net.module.util.MacAddressUtils;
+
 import org.junit.Before;
 import org.junit.Test;
 
@@ -568,7 +570,7 @@
     public void testSetSecurityParamsForSuiteB() throws Exception {
         WifiConfiguration config = new WifiConfiguration();
 
-        config.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
+        config.setSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT);
 
         assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192));
         assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
@@ -581,6 +583,26 @@
     }
 
     /**
+     * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the
+     * {@link WifiConfiguration} object correctly for WPA3 Enterprise security type.
+     * @throws Exception
+     */
+    @Test
+    public void testSetSecurityParamsForWpa3Enterprise() throws Exception {
+        WifiConfiguration config = new WifiConfiguration();
+
+        config.setSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE);
+
+        assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
+        assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
+        assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP));
+        assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256));
+        assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP));
+        assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256));
+        assertTrue(config.requirePmf);
+    }
+
+    /**
      * Test that the NetworkSelectionStatus Builder returns the same values that was set, and that
      * calling build multiple times returns different instances.
      */
@@ -641,7 +663,10 @@
         configuration.setSecurityParams(SECURITY_TYPE_EAP);
         assertFalse(configuration.needsPreSharedKey());
 
-        configuration.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
+        configuration.setSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE);
+        assertFalse(configuration.needsPreSharedKey());
+
+        configuration.setSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT);
         assertFalse(configuration.needsPreSharedKey());
     }
 
@@ -667,7 +692,10 @@
         configuration.setSecurityParams(SECURITY_TYPE_EAP);
         assertEquals(KeyMgmt.WPA_EAP, configuration.getAuthType());
 
-        configuration.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
+        configuration.setSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE);
+        assertEquals(KeyMgmt.WPA_EAP, configuration.getAuthType());
+
+        configuration.setSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT);
         assertEquals(KeyMgmt.SUITE_B_192, configuration.getAuthType());
 
         configuration.setSecurityParams(SECURITY_TYPE_WAPI_CERT);